;***** MultifuncDigitalClock.asm ******************************************
;
;	多機能携帯デジタル時計
;
;	Copyright (C) 2023   by M.Yamamoto. All rights reserved.
;
;	Homepage URL: http://xyama.sakura.ne.jp/hp/MultifuncDigitalClock.html
;
;     ( coding:  Ver. 0.00   2023/07/22  by M.Yamamoto )
;	coding:  Ver. 1.00   2023/10/17  初期バージョン
;	update:  Ver. 1.01   2023/11/19  メニュー 9 機能を追加
;	update:  Ver. 1.02   2023/11/21  メニュー 3 機能を書き直し
;	update:  Ver. 1.03   2023/11/23  メニュー 5 に"None"表示を追加
;	update:  Ver. 1.04   2023/12/01  TMR1基準時間の調整支援を追加,他
;	bugfix:  Ver. x.xx
;
;******************************************************* PicAsm 0265 ******

;	Device: PIC16F1827	Clock: 4MHz (クリスタル)

#ifdef comment

 このファイル（MultifuncDigitalClock.asm）はテキストファイルであり、現在、Windows メモ帳 11.2306.15.0 によって書
 いているが、ファイル中で使用している罫線（コメントで多用）の表示処理がうまくできず、同メモ帳では見た目がぐちゃ
 ぐちゃになる。ただし、現時点（2023/09/23）においては Microsoft Edge 117.0.2045.40 では、問題なく表示ができるの
 でドラッグ＆ドロップして同ブラウザで見るように！！

 ------------------------------------------------------------
（Ver. 1.04 で TMR1 基準時間の調整を行うための支援機能を追加）
 ------------------------------------------------------------

 "定数の定義と変数のレジスタ割付け" の先頭部分にある次の行

	;#define 	xx_debug			;TMR1 基準時間の調整支援（関連６か所あり）

 の先頭の ；（セミコロン）を取り除いてアセンブルをし直すことによって、"TMR1 基準時間の調整支援" プログラムに切り
 替わる。使用法は「メニューの選択」LCD 画面で、メニュー項目 2: [ DtlStopW ] を選択して実行する。

 Start / Stop スイッチ を Start 側に倒すと、PIC の RB7 ピン（ICSP 端子の DAT ピン）に、10 分間だけ "L" 信号を出
 力するとともに LED(赤) を点灯させて知らせる。

 この 10 分間の "L" 信号の長さを、電気信号で作動するストップウオッチ等で測定する。測定値が 10 分間と大きく異なる
 場合は、補正値 xx の値を変更しながら正しく 10 分に近づけてゆく。

	xx		equ	-33			;補正値
	basic_const	equ	65536 - (10000 + xx)	;(4 / 4MHz) * 10000 = 0.01 S = 10 mS

 "TMR1 基準時間の調整支援" プログラムでメニュー項目 2: [ DtlStopW ] を実行中は、RB7 ピンは出力ポートに切り替わっ
 ているので、RIGHT スイッチの操作は絶対にしないように。

 なお、調整の終了時には、上に示した #define 文に再び ; を付してコメント行に戻し、アセンブルをし直すこと。

 詳細は、上に記した URL（ホームページ）のプログラムの項の、"ストップウオッチ機能（詳細測定、長時間測定）の精度" 
 を参照のこと。

 ------------------
 <機能概要と使用法>
 ------------------

・本機は、携帯使用を想定した多機能のデジタル時計で、現在時刻（年、月、日、曜日、AM/PM、時、分、秒）を表示する時
　計機能、２種類（詳細測定、長時間測定）のストップウオッチ機能、２種類（インターバル、ウィークリー）のタイマー機
　能の他、メンテナンス用途としての現在時刻の設定機能などを有する。 

・携帯使用をするために、電源には 18650 リチウムイオン電池を採用している。そして、本機ではリアルタイムクロック
　（RTC）モジュールを搭載（バックアップ用のバッテリーも搭載）してあるため、リチウムイオン電池の消耗などで電源が
　切れたときはもちろん、本機の不使用時の長時間の電源断にも、安定した時刻の継続が期待できる。

・また、本機には 18650 リチウムイオン電池のための充電機能も内蔵しているので、USB 端子から + 5 V 電源を供給すれば
　電池の充電も可能である。ただし、本機では充電中には本機の電源スイッチを切っておく必要があり、充電しながらの連続
　使用はできない。

・なお、後述の 1:「現在時刻の表示」機能 、4:「ストップウオッチ(長時間)」機能 、「5:記録内容の表示」機能の３機能
　については、長時間に亘る使用が予想されることもあって、一定時間スイッチの入力指示がない場合には、自動的に LCD 
　の電源を切り、本機の PIC をスリープ状態にさせて電池の消耗を抑えるようにしている。

・さて、本機の電源スイッチをオンにすると、"ピポッ" と開始アラーム音とともに LED (緑) を点滅表示した後、LCD 画面
　にも次の開始メッセージが交互に２秒間ずつ連続２回表示される。

			[ Multifun ]			[ Ver x.xx ]
			[ DigClock ]			[  by M.Y  ]

・その後１秒間の空白をおいた後、リアルタイムクロック（ RTC ）モジュールの状態がチェックされ、異常がなかった場合
　には、後述の 1:「現在時刻の表示」機能に実行が移されて時計機能を開始し、LCD 画面に現在時刻（年、月、日、曜日、
　AM/PM、時、分、秒）を表示する。

・一方、本機に初めて電源を入れたときや、バックアップ用バッテリーを交換したときなどに、次のエラーメッセージが LCD 
　画面に表示されるとともに、"ブッブー" アラーム音の出力と LED (赤) が点灯される。

			[ RTC Err! ]	..... DS3231 RTC エラーメッセージ
			[  Init?_  ]	..... ユーザのスイッチ応答待ち

・ユーザはエラーメッセージの確認をしてバッテリーの交換などの処置を行った後、すべてのタクトスイッチの内のどれかを
　押して応答をする。

・すると、リアルタイムクロック（ RTC ）モジュールが初期設定され、エラーフラグがクリアされるとともに、年月日、時
　分秒が RTC モジュールをプログラミングしたときの初期値、"2022/01/01"、"00:00:00" に設定がされて時計機能を開始し、
　LED (赤) は消灯される。

・しかし、表示時刻は現在のリアルな時刻とは異なっているので、一旦、後述の「メニューの選択」機能に戻ってから 8:「
　現在時刻の設定」機能を選択して、リアルな現在時刻に設定をし直す必要がある。

・次の図は、本機におけるスイッチ操作と各機能間の遷移の関係だけを図に表したもので、(XXX) で示す各スイッチを操作す
　ることで各機能間を移動する。(XXX) ＋ (XXX) と表現されているものは、＋ 印の左側スイッチを押しながら 右側スイッ
　チをちょんと押すことを表している。（なお、各機能内でのスイッチ操作については、以降で説明をするそれぞれの機能の
　項を参照のこと）

	［ スイッチ操作と各メニュー項目（機能）間との遷移図 ］

		                                               ENABLE   START/
		Start                         ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   　┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│□│   │○│     │○│   │○│   │○│   │○│   │○│
		└□┘   └─┘     └─┘   └─┘   └─┘   └─┘   └─┘
		 Stop    CLEAR       EXIT     DOWN      UP      LEFT     RIGHT

			スイッチ省略名	 (EXT): EXIT
					 (DWN): DOWN
					  (UP): UP
					 (LEF): LEFT
					 (RIG): RIGHT
					 (ZER): ZERO
					 (MOD): TIME MODE
					  (EN): ENABLE
					 (STA): START/GOAL
					 (CLR): CLEAR

					 * 印 : 3秒以上の長押し

	 （電源 ON）─────────────┐
	                                      │
	                                      ↓
	┏━━━━━┓                  ┏━━━━━┓                    ┏━━━━━┓
	┃          ┃ (EXT)    menu=1  ┃          ┃ (EN) + (EXT)       ┃          ┃
	┃ メニュー ┃────────→┃ 現在時刻 ┃───────┐    ┃ スリープ ┃
	┃          ┃        │        ┃          ┃              │    ┃          ┃
	┃  の選択  ┃    ┌─│───→┃  の表示  ┃ (EXT)        │    ┃  モード  ┃
	┃          ┃    │  │        ┃          ┃───┐      │    ┃          ┃
	┗━━━━━┛    │  │        ┗━━━━━┛      │      │    ┗━━━━━┛
	      ↑          │  │            ↑  │   (自動) │      │ 3分    ↑  │
	      │          │  │            │  └─────│───│────┘  │ (ZER) or (MOD) or
	      │          │  │            │              │      │        ↑  │ (EXT) or (EN)
	      │          │  │            └───────│───│────│─┘
	      │          │  │                            │      │        │  │
	      └─────│─│──────────────┘      │        │  │
	      ↑          │  │                                    │        │  │
	      │          │  │        ┏━━━━━┓              │        │  │
	      │          │  │        ┃          ┃              │        │  │
	      │          │  │menu=2  ┃ ストップ ┃ (EXT)        │        │  │
	      │          │  └───→┃ ウオッチ ┃───┐      │        │  │
	      │          │  │        ┃  (詳細)  ┃      │      │        │  │
	      │          │  │        ┃          ┃      │      │        │  │
	      │          │  │        ┗━━━━━┛      │      │        │  │
	      │          │  │                            │      │        │  │
	      └─────│─│──────────────┘      │        │  │
	      ↑          │  │                                    │        │  │
	      │          │  │        ┏━━━━━┓              │        │  │
	      │          │  │        ┃          ┃              │        │  │
	      │          │  │menu=3  ┃ インター ┃ (EXT)        │        │  │
	      │          │  └───→┃バル(間隔)┃───┐      │        │  │
	      │          │  │        ┃ タイマー ┃      │      │        │  │
	      │          │  │        ┃          ┃      │      │        │  │
	      │          │  │        ┗━━━━━┛      │      │        │  │
	      │          │  │                            │      │        │  │
	      └─────│─│──────────────┘      │        │  │
	      ↑          │  │                                    │        │  │
	      │          │  │        ┏━━━━━┓              │        │  │
	      │          │  │        ┃          ┃ (EN) + (EXT) │        │  │
	      │          │  │menu=4  ┃ ストップ ┃─────┐  │        │  │
	      │          │  └───→┃ ウオッチ ┃          │  │        │  │
	      │          │  │        ┃ (長時間) ┃ (EXT)    │  │        │  │
	      │          │  │        ┃          ┃───┐  │  │        │  │
	      │          │  │        ┗━━━━━┛      │  │  │        │  │
	      │          │  │            ↑  │   (自動) │  │  │ 1分    │  │ (EXT) or
	      │          │  │            │  └─────│─│─│────┘  │ (EN)  or
	      │          │  │            │              │  │  │        ↑  │ (STA)
	      │          │  │            └───────│─│─│────│─┘
	      │          │  │                            │  │  │        │  │
	      └─────│─│──────────────┘  │  │        │  │
	      ↑          │  │                                │  │        │  │
	      │          │  │        ┏━━━━━┓          │  │        │  │
	      │          │  │        ┃          ┃←────┘  │        │  │
	      │          │  │menu=5  ┃ 記録内容 ┃              │        │  │
	      │          │  └───→┃          ┃              │        │  │
	      │          │  │        ┃  の表示  ┃ (EXT)        │        │  │
	      │          │  │        ┃          ┃───┐      │        │  │
	      │          │  │        ┗━━━━━┛      │      │        │  │
	      │          │  │            ↑  │   (自動) │      │ 1分    │  │ (EXT) or
	      │          │  │            │  └─────│───│────┘  │ (RIG) or
	      │          │  │            │              │      │            │ (LEF)
	      │          │  │            └───────│───│──────┘
	      │          │  │                            │      │
	      └─────│─│──────────────┘      │
	      ↑          │  │                                    │
	      │          │  │        ┏━━━━━┓              │
	      │          │  │        ┃          ┃ (EN) + (EXT) │
	      │          │  │menu=6  ┃週間タイマ┃─────┐  │
	      │          │  └───→┃ ーの時刻 ┃          │  │
	      │          │  │        ┃   設定   ┃ (EXT*) ..│..│..... 設定終了
	      │          │  │        ┃          ┃───┐  │  │
	      │          │  │        ┗━━━━━┛ .....│..│..│..... 設定中断終了
	      │          │  │                            │  │  │
	      └─────│─│──────────────┘  │  │ (LEF) + (RIG) or
	      ↑          │  │                                │  │ (RIG) + (LEF)
	      │          │  │        ┏━━━━━┓          │  │
	      │          │  │        ┃          ┃←────┘  │
	      │          │  │menu=7  ┃週間タイマ┃              │
	      │          │  └───→┃ ーの設定 ┃              │
	      │          │  │        ┃表示と消去┃ (EXT)        │
	      │          │  │        ┃          ┃───┐      │
	      │          │  │        ┗━━━━━┛      │      │
	      │          │  │                            │      │
	      └─────│─│──────────────┘      │
	      ↑          │  │                                    │
	      │          │  │        ┏━━━━━┓              │
	      │          │  │        ┃          ┃←──────┘
	      │          │  │menu=8  ┃ 現在時刻 ┃
	      │          │  └───→┃          ┃ (LEF) + (RIG) or
	      │          │  │        ┃  の設定  ┃ (RIG) + (LEF)  ..... 設定中断終了
	      │          │  │        ┃          ┃───────┐
	      │          │  │        ┗━━━━━┛ (EXT) .......│..... 設定終了
	      │          │  │                                    │
	      │          └─│──────────────────┘
	      │              │
	      │              │        ┏━━━━━┓
	      │              │        ┃          ┃ (LEF) + (RIG) or
	      │              │menu=9  ┃ スリープ ┃ (RIG) + (LEF)  ..... 設定中断終了
	      │              └───→┃ 移行時間 ┃───────┐
	      │                        ┃  の変更  ┃ (EXT) .......│..... 設定終了
	      │                        ┃          ┃              │
	      │                        ┗━━━━━┛              │
	      │                                                    │
	      └──────────────────────────┘

-------------------------
◎ 「メニューの選択」機能
-------------------------

・本機には以降で順に説明をするように９つのメニュー項目（機能）があり、本機能である「メニューの選択」LCD 画面によ
　って、希望する各メニュー項目（機能）を選択する。

			[ Select_x ]	..... メニュー番号 x がブリンク表示   １行目

			[ ClockDsp ]	..... 1:「現在時刻の表示」	   ┐
			     ・						   │
			     ・						   │ ２行目
			     ・						   │
			[ SleepTim ]	..... 9:「スリープ移行時間の変更」 ┘

・具体的な各メニュー項目の種類は次の通りで、使用している LCD 画面の表示文字数の制約から、次のような機能の略名で表
　している。機能の略名では分かりづらいと思うが右側に付した和名から機能を察していただきたい。
　（機能の詳細については各機能の項を参照のこと）

		1: ClockDsp   .....　「現在時刻の表示」機能
		2: DtlStopW   .....　「ストップウオッチ(詳細)」機能
		3: ItvTimer   .....　「インターバル（間隔）タイマー」機能
		4: LngStopW   .....　「ストップウオッチ(長時間)」機能
		5: MemoDisp   .....　「記録内容の表示」機能
		6: WkTimSet   .....　「週間タイマーの時刻設定」機能
		7: WkTimDsp   .....　「週間タイマーの設定表示と消去」機能
		8: ClockAdj   .....　「現在時刻の設定」機能
		9: SleepTim   .....　「スリープ移行時間の変更」機能

・なお、「メニューの選択」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示した名前で
　呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │●│   │●│   │●│   │○│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		  DOWN スイッチ ..... 前のメニュー項目を表示
		    UP スイッチ ..... 次のメニュー項目を表示

		 ALARM スイッチ ..... アラーム音出力の有効／無効

		  EXIT スイッチ ..... 選択したメニュー項目（機能）に移行

・各メニュー項目（機能）を実行した後で、終了をさせるために EXIT スイッチを押すと、本「メニューの選択」機能に再び
　戻って来る。ただし２つ例外があって、１つは、6:「週間タイマーの時刻設定」では EXIT スイッチを３秒以上の長押しを
　しないと、「メニューの選択」機能には戻らない。またもう１つは、8:「現在時刻の設定」では EXIT スイッチを押しても、
　「メニューの選択」機能には戻らず、1:「現在時刻の表示」機能に移行をする。

・そして、前機能から戻ってきた本「メニューの選択」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅さ
　せて、本機能に動作が移ったことを知らせる。

・本「メニューの選択」機能に再び戻って来ると、LCD 画面の２行目には戻る以前に実行をしていた機能の略名が表示され、
　また、１行目の右端 x の部分にはメニュー項目の番号がブリンク表示されて、次に実行すべきメニューの選択を促す。

・「メニューの選択」LCD 画面でメニュー項目を変更するには、UP スイッチ、または DOWN スイッチを押すことによって行
　う。UP スイッチは、現在１行目に表示されているメニュー項目番号 x 値を、押すごとに ＋１ ずつ増加（インクリメント）
　し、また DOWN スイッチは、逆に押すごとに －１ ずつ減少（デクリメント）するとともに、２行目には機能の略名がメニ
　ュー項目番号 x 値に応じて変更表示される。

・そして、UP スイッチの操作では、メニュー項目番号の最大値 9 を超えると最小値 1 に戻る。また DOWN スイッチの操作
　では、メニュー項目番号の最小値 1 を超えると最大値 9 に戻る。このように、UP スイッチ、DOWN スイッチを押すことに
　よって、メニュー項目を自由に変更することができる。

・メニュー項目（番号）が決まったら EXIT スイッチを押すことによって、「メニューの選択」機能から選択をした各メニュ
　ー項目（１～９）別機能に移行（ジャンプ）をする。

・ALARM スイッチは、時報予報音、時報正報音、タイマー一致音、その他の効果音など、各種アラーム音の出力を一括して管
　理するスイッチで、押すごとに有効／無効を繰り返すトグルスイッチとなっている。 この ALARM スイッチは、本「メニュ
　ーの選択」機能においてだけ操作が可能なスイッチで、各メニュー項目（１～９）別機能では操作ができないので注意が必
　要である。

---------------------------------------------
◎ メニュー項目: 1 ... 「現在時刻の表示」機能
---------------------------------------------

・本機の中枢であり、現在時刻（年、月、日、曜日、AM/PM、時、分、秒）を表示する時計機能である。本機ではリアルタイ
　ムクロック（RTC）モジュールを搭載（バックアップ用のバッテリーも搭載）してあるため、電池の消耗などで電源が切れ
　たときや本機の不使用時の長時間の電源断にも、安定した時刻の継続が期待できる。

・「メニューの選択」LCD 画面で、メニュー項目 1: [ 1.Clock ] を選択後に EXIT スイッチを押した場合、または、8:「
　現在時刻の設定」機能で EXIT スイッチを押した場合（通常終了）と、同機能で LEFT スイッチ ＋ RIGHT スイッチ、ま 
　たは RIGHT スイッチ ＋ LEFT スイッチの操作をした場合（中断終了）にも、同機能を終了して本機能に移行（ジャンプ）
　をしてくる。その他にも、本機では電源を入れた直後には、「メニューの選択」機能ではなく本「現在時刻の表示」機能
　が最初に実行される。

			[ Select_1 ]
			[ ClockDsp ]	..... 1:「現在時刻の表示」

　そして、移行をしてきた本「現在時刻の表示」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅させて、
　本機能に動作が移ったことを知らせる。

・本機能の現在時刻の LCD 画面表示は、使用した小さな LCD に対して表示させるための情報量が多いため、次に示すように、
　１行目を偶数秒のときと奇数秒のときとで交互に情報を切り替えて表示をさせている。すなわち、偶数秒のときには年月日
　を表示させ、奇数秒のときには曜日と、12 時間表示のときには AM/PM 別の表示をさせ、また、24 時間表示のときには同
　表示位置は空白表示としている。

					偶数秒のとき		　 奇数秒のとき
			[ xx/xx/xx ]	１行目 ... 年月日の表示　　[ (SUN) AM ]	１行目 ... 曜日 AM/PM の表示
			[ xx:xx:xx ]	２行目 ... 時分秒の表示　　[ xx:xx:xx ]	２行目 ... 時分秒の表示

・なお、「現在時刻の表示」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示した名前で
　呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │●│   │●│   │●│   │○│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		 TMODE スイッチ ..... 12時間表示／24時間表示の切り替え

		  ZERO スイッチ ..... 毎正時 00 分 00 秒に設定

		ENABLE スイッチ + 
		  EXIT スイッチ ..... 「現在時刻の設定」に移行

		  EXIT スイッチ ..... 「メニューの選択」に戻る

・本機の "時"、"分"、"秒" 表示の内、"時" 表示は TMODE（TIME MODE）スイッチを押すことによって、12 時間表示と 24 時
　間表示をいつでも切り替えることができる。TMODE スイッチはトグルスイッチになっていて、押すごとに 12 時間表示と 24
　時間表示が交互に切り替わる。

・次に、24 時間表示と 12 時間表示の対応を示すが、12 時間表示のときにのみ "xx 時" の先頭の１桁目（左側）は、ゼロサ
　プレスを行なって表示をする。

	(24H)  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
	(12H)  12  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11
	       am am am am am am am am am am am am pm pm pm pm pm pm pm pm pm pm pm pm

・本機で使用しているリアルタイムクロック（RTC）モジュールでは、これらの 12 時間表示、24 時間表示の情報も管理がで
　きるが、本機では、（RTC）には常に 24 時間表示で動作をさせ、12 時間表示のときには本機のプログラム内で変換をして、 
　LCD 画面に表示をさせている。

・また、毎正時プラス・マイナス５分以内のときに、ZERO スイッチを押すと、現在時刻の "分" と "秒" を "00 分 00 秒" 
　に設定し直して、リアルタイムクロック（RTC）モジュールに書き込み、LCD 画面表示もその "00 分 00 秒" から再開始を
　する。ただし、毎正時プラス・マイナス５分以外のときには、ZERO スイッチを押しても無視をされる。

・本機は携帯用の多機能デジタル時計としての使用を想定していて、電源には 18650 リチウムイオン電池を使用している。そ
　のために際限なく時計表示をさせておくことはできない。したがって、この「現在時刻の表示」機能では３分間（デフォル
　ト値）どのスイッチも入力がなかった場合には、自動的に LCD の電源を切り、本機の PIC をスリープ状態にさせて電池の
　消耗を抑えるようにしている。

・しかし、このスリープ状態を解除させたい場合には、上述の本機能で使用できる赤字名のスイッチ（TMODE、ZERO、ENABLE、
　EXIT スイッチ）の内の、どれかを押すことによっていつでも直ちに目覚めさせることができる。

・スリープ状態になるときには、３分（デフォルト値）を経過する３秒前から、秒ごとに "ブッ" アラーム音と LED (緑) を
　瞬間点滅させ、３分を経過直後に "ブッブー" アラーム音とともに LED (緑) を点滅させてから、スリープ状態になる。

・ユーザのスイッチ操作によってスリープ状態から目覚めるときには、目覚めた直後に "ピピッ" アラーム音とともに LED 
　(緑) を点滅させる。また、スリープ中にも本機の存在感を誇示？するために、１分間に１度、"ピッ" ブザー音ととも
　に LED (赤) を瞬間点滅させている。

・本機では毎時の時報音を出力させるための時間監視と、後述の 6:「週間タイマーの時刻設定」機能で設定をしたタイマー一
　致の時間監視をさせるために、目覚めているときはもちろん、スリープ状態においても 毎秒ごとに瞬間だけウエイクアップ
　をさせてそれらの時間監視をさせ、時間一致があればそれらに応じた各アラーム音の出力をする。

・９つのメニュー項目（機能）の内、1: 本機能と、4:「ストップウオッチ(長時間)」機能、5:「記録内容の表示」機能の３機
　能についてのみ、リアルタイムクロック（RTC）モジュールによる 時計機能を動作させている。したがって、それらの３機
　能では本機のプログラムでいつも上述の時間監視が行われていて、前項の「メニューの選択」機能で述べた ALARM スイッチ 
　によって、アラーム音の出力が有効になっている場合には各アラーム音を出力する。

・本機能を終了させるのには２つの方法があり、単独で EXIT スイッチを押した場合には「メニューの選択」に戻る。また、
　ENABLE スイッチを押しながら EXIT スイッチを押した場合には、8:「現在時刻の設定」機能に移行（ジャンプ）するので、
　引き続き現在時刻（年、月、日、時、分、秒）の設定作業を行うことができる。

-------------------------------------------------------
◎ メニュー項目: 2 ... 「ストップウオッチ（詳細）」機能
-------------------------------------------------------

・本機能のストップウオッチは 1/100 秒単位での測定ができるのが特徴で、"99 時間 59 分 59 秒 99" までの表示が可能で、
　それ以上の３桁目の時表示はできないが 100 時間以上の測定も連続無制限に可能である。本機能では最大値の表示を過ぎる
　と一旦、"00 時間 00 分 00 秒 00" の表示に戻って引き続きカウントアップを繰り返し行う。

・しかし、本機能ではこのような長時間に亘る使用は想定をしていないので、PIC をスリープ状態にさせることもしない。し
　たがって、電池の消耗という観点ではすこぶる不利となる。 もしも、このような長時間に亘る測定をしたい場合には、
　1/100 秒単位での測定はできないが（というよりも長時間に亘る測定では 1/100 秒単位の測定などは不要と思われる）、後
　述の 4:「ストップウオッチ（長時間）」機能で測定することをお勧めする。

・「メニューの選択」LCD 画面で、メニュー項目 2: [ 2.StW_Dt ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。

			[ Select_2 ]
			[ DtlStopW ]	..... 2:「ストップウオッチ(詳細)」

　そして、移行をしてきた本「ストップウオッチ（詳細）」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅
　させて、本機能に動作が移ったことを知らせる。

・なお、「ストップウオッチ（詳細）」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示
　した名前で呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                                               ENABLE   START/
		Start                         ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   　┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│■│   │●│     │●│   │○│   │○│   │○│   │○│
		└■┘   └─┘     └─┘   └─┘   └─┘   └─┘   └─┘
		 Stop    CLEAR       EXIT     DOWN      UP      LEFT     RIGHT

		トグルスイッチ = Start（LINE IN = "L"*）..... 動作スタート

		トグルスイッチ = Stop （LINE IN = "H"*）..... 動作ストップ

			*スタート信号 (RA4 入力) はインバータにより反転する

		 CLEAR スイッチ ..... 全桁 "00" にクリア表示

		  EXIT スイッチ ..... 「メニューの選択」に戻る

・本機能のストップウオッチの LCD 画面表示は次の通りで、ストップウオッチの動作がスタートする前のもので、初期状態を
　表している。

			[ 00:00:00 ]	 ... HH:MM:SS
			[ (StW) 00 ]	 ... (StW) XX ... XX: 1/100 秒

・Start / Stop スイッチはトグルスイッチを使用していて、Start 側に倒すとストップウオッチの動作がスタートし、1/100 
　秒単位で LCD 画面表示のカウントアップが始まる。やがて、ストップウオッチを停止したいときには Stop 側に倒すとスト
　ップウオッチの動作がストップ して、LCD 画面表示のカウントアップも停止をするとともに、"ポッポッポッポッ" アラー
　ム音の出力と LED (緑) が点灯して、ストップウオッチが停止したことをユーザに知らせる。

・このストップウオッチが停止した知らせを受けた後、ユーザはそのときの LCD 画面の表示値を確認する。そして、再度スト
　ップウオッチの動作停止を繰り返し実行したい場合には、CLEAR スイッチを押すと上述のストップウオッチの動作がスター
　トする前の、初期状態の LCD 画面表示に戻るとともに LED (緑) が消灯する。

・一方、この CLEAR スイッチを押して初期状態の LCD 画面表示に戻す前後のどちらの場合にも、EXIT スイッチを押すと LED 
　(緑) が点灯している場合には消灯し、本機能を終了して「メニューの選択」機能に戻る。

・また、本機には LINE IN 入力端子が設けてあり、その入力端子に外部からの電気信号を入力することによって、Start / Stop
　トグルスイッチを操作したときと同様なストップウオッチ動作を行うことができる。電気信号が "L" の場合にはトグルスイ
　ッチを Start 側に倒した場合と同様であり、"H" の場合にはトグルスイッチを Stop 側に倒した場合と同様な動作をする。

・なお、本機のロジック回路は 3.3 V 電源で動作をしているため、この LINE IN 入力端子に入力するための外部電気信号の
　電圧も、ロジックレベルを合わせる必要がある。

-----------------------------------------------------------
◎ メニュー項目: 3 ... 「インターバル（間隔）タイマー」機能
-----------------------------------------------------------

・本機能のタイマーは、分かりやすく例えれば "キッチンタイマー" のような使い方を想定していて、タイマー動作を開始さ
　せる前に予め設定をしておいた時間から、ひたすらカウントダウンを繰り返し、残り時間がゼロになるとタイマー動作を停
　止する。

・この予め設定をしておくタイマー時間の範囲は、本機能では最大 "99 時間 59 分 59 秒" までが可能で、１秒単位でカウン
　トダウンを繰り返えすが、長時間の設定は電池の消耗という観点ですこぶる不利となる。この設定値は次回のタイマー動作
　のときにも使用ができるように、自動的に EEPROM にバックアップがとられる。

・「メニューの選択」LCD 画面で、メニュー項目 3: [ ItvTimer ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。

			[ Select_3 ]
			[ ItvTimer ]	..... 3:「インターバル(間隔)タイマー」

　そして、移行をしてきた本「インターバル（間隔）タイマー」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を
　点滅させて、本機能に動作が移ったことを知らせる。

・なお、「インターバル（間隔）タイマー」機能では次図に示す黒塗りすべてのスイッチを使用し、それらのスイッチ名を赤
　字で示した名前で呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                                               ENABLE   START/
		Start                         ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   　┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│■│   │●│     │●│   │●│   │●│   │●│   │●│
		└■┘   └─┘     └─┘   └─┘   └─┘   └─┘   └─┘
		 Stop    CLEAR       EXIT     DOWN      UP      LEFT     RIGHT

		トグルスイッチ = Start（LINE IN = "L"*）..... 動作スタート

		トグルスイッチ = Stop （LINE IN = "H"*）..... 動作ストップ

			*スタート信号 (RA4 入力) はインバータにより反転する

		CLEAR スイッチ ..... 前回の設定値を表示

		 LEFT スイッチ ..... ブリンク位置のポインタを - 1
		RIGHT スイッチ ..... ブリンク位置のポインタを + 1

		 DOWN スイッチ ..... ブリンク位置の値を - 1
		   UP スイッチ ..... ブリンク位置の値を + 1

		 EXIT スイッチ ..... 「メニューの選択」に戻る

・本機能タイマーの LCD 画面表示は次の通りで、２行目のタイマー時間の設定値（HH:MM:SS）には、「メニューの選択」機能
　から移行をしてきた直後には、バックアップがとられている EEPROM から自動的に読み出されて表示がされる。ただし、本
　機能がまったく初めて使用されたときには、バックアップの時間設定値データがないので "00:00:00" が表示される。

			[ ItvTimer ]	 ... インターバルタイマー
			[ xx:xx:xx ]	 ... タイマー時間の設定値

・タイマー時間の設定値に "00:00:00" が表示されていたり、現在表示されている設定値を変更したい場合には、DOWN、UP、
　LEFT、RIGHT の各スイッチを使用して、自分が希望するタイマー時間の設定値に変更する。

・まず初めに、LEFT または RIGHT スイッチ を押すことによって、ブリンク位置が左または右に移動をするので、変更をした
　い "HH"、"MM"、"SS" の位置にポイントする。

・次に、ポイントしたブリンク位置の設定値を、UP スイッチを押すごとに１ずつ増加、または DOWN スイッチを押すごとに１
　ずつ減少することができる。このときの増減幅を大きくしたい場合には、UP スイッチ、または DOWN スイッチを押したまま
　にしていると、１秒当たり 4 ～ 5 の増減幅で更新をするようになる。

・このようにタイマー時間の設定をした後で、Start / Stop スイッチを Start 側に倒すとタイマー動作がスタート し、１秒
　単位で LCD 画面表示のカウントダウンが始まる。やがて、残りのタイマー時間がゼロになるとタイマー動作を停止して、
　LCD 画面表示のカウントダウンも停止をするとともに、"ポッポッポッポッ" アラーム音の出力と LED (緑) が点灯して、タ
　イマーが停止したことをユーザに知らせる。この知らせを受けた後には、ユーザは Start / Stop スイッチを Stop 側に戻し
　ておく。

・LCD 画面表示がカウントダウン中に何らかの理由で、Start / Stop スイッチを Stop 側に倒すとタイマー動作は強制的に停
　止して、同様に "ポッポッポッポッ" アラーム音の出力と LED (緑) が点灯する。

・また、タイマー時間の設定値に "00:00:00" が表示されているときに、Start / Stop スイッチを Start 側に倒すと、"ブッ" 
　アラーム音の出力とともに LED (赤) が瞬間点滅するエラー表示を、Start / Stop スイッチを Stop 側に戻すまで連続で繰
　り返される。

・タイマーが停止したことを確認後 CLEAR スイッチを押すと、前回のタイマー設定値が再び LCD 画面に表示されるとともに 
　LED (緑) が消灯するが、設定値の変更をしたければ上述と同様にして変更作業を行う。以降は Start / Stop スイッチの操
　作によってタイマー動作を繰り返し実行することができる。

・一方、この CLEAR スイッチを押して前回のタイマー設定値が LCD 画面に表示される前後のどちらの場合にも、EXIT スイッ
　チを押すと LED (緑) が点灯している場合には消灯し、本機能を終了して「メニューの選択」機能に戻るが、その直前に、
　最終的に用いられたタイマー時間の設定値が EEPROM のバックアップデータと比較され、両者が異なる場合にだけ、前者の
　設定値が新たなバックアップデータとして EEPROM に再書き込みが行われる。

・なお、前項の 2:「ストップウオッチ(詳細)」機能と同様に、LINE IN 入力端子から入力した外部電気信号でもタイマー動作
　をスタートさせることは可能であるが、そのような使い方は本機能では想定をしていないのであまりお勧めはしない。

---------------------------------------------------------
◎ メニュー項目: 4 ... 「ストップウオッチ（長時間）」機能
---------------------------------------------------------

・本機能は主に室外での携行使用を想定しており（例えばウォーキングの友として、その間中をずっと本機の持ち歩きをする
　など）、下図の ENABLE スイッチと START/GOAL スイッチについては２個ずつ用意して、１組は他のスイッチと同様にプリ
　ント基板上に搭載し、 もう１組は本機能のための専用スイッチとも言うべきもので、本機のケースの蓋を閉めた状態でもス
　イッチの頭がケース外に飛び出すような構造にケース加工を施して、ケースの上蓋に取り付けてある。

・実際の運用に当たっては、ウォーキングなどの移動中には本機をポケットや、カバンなどの中に入れられたりして使用され
　ることが多い ― と想定されるため、上述のようなスイッチの取り付け構造や、また、スイッチの誤操作を極力防ぐために、
　後述のように２個のスイッチを組み合わせたスイッチ操作を採用している。

・また、本機能は比較的長時間の携行使用することを想定して、なるべく電池の消耗が少なくて済むように一定時間スイッチ
　操作がなかったときには、PIC をスリープ状態にさせるなどの考慮をしており、また、測定ができる時間の最小単位は１秒
　で最大 "99 時間 59 分 59 秒" までの６桁の表示で、それ以上の３桁目の時表示はできないが 100 時間以上の測定も連続
　無制限に可能である。本機能では最大値の表示を過ぎると一旦、"00 時間 00 分 00 秒" の表示に戻って引き続きカウント
　アップを繰り返し行う。

・このように、秒以下の詳細な測定は本機能ではできないが、もしも、詳細な測定を希望する場合には、前々項の 2:「ストッ
　プウオッチ(詳細)」機能を使用すれば 1/100 秒単位での測定ができるので、 そちらの機能を使用することをお勧めする。

・「メニューの選択」LCD 画面で、メニュー項目 4: [ LngStopW ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。

			[ Select_4 ]
			[ LngStopW ]	..... 4:「ストップウオッチ(長時間)」

　そして、移行をしてきた本「ストップウオッチ（長時間）」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点
　滅させて、本機能に動作が移ったことを知らせる。

・本機能に移行した直後の LCD 画面表示は次の通りで、１行目には本機能の略名が表示され、２行目には現在時刻 "HH:MM:SS" 
　が刻々と刻まれながら表示される。

			[ LngStopW ]	..... 本機能の略名を表示
			[ xx:xx:xx ]	..... 現在時刻 "HH:MM:SS" を刻々と刻みながら表示

・なお、「ストップウオッチ（長時間）」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で
　示した名前で呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │○│   │○│   │●│   │●│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

	    (1)        ENABLE スイッチ +
		        START スイッチ ..... （通常のちょん押し） START / SPLIT(LAP)

	    (2) ENABLE スイッチ 長押し +
		 START スイッチ 長押し ..... （３秒以上の長押し） GOAL

	    (3)        ENABLE スイッチ +
		         EXIT スイッチ ..... 「記録内容の表示」に移行

	    (4)          EXIT スイッチ ..... 「メニューの選択」に戻る

・下図は、「メニューの選択」機能から本機能に移行をし、再び「メニューの選択」機能へ戻ったり、または「記録内容の表
　示」機能に移行するまでを図に表したもので、図中の (1) ～ (4) の番号は上のスイッチ操作の要点の左端に付した番号を
　指す。

	     （スプリットタイムのカウントが [ 00:00:00 ] から開始される）
	        ↓

	│      |                                                   |      |
	│      |←-----------------------------------------SPLITn→|      |   ;スプリット（SPLIT）タイム
	│      |←------------------------SPLITn-1→|              |      |   ;スタートしてからゴールまでの途中経過時間
	│      |                                    |              |      |
	│      |←-------------------SPLIT2→|      |              |      |
	│      |←----SPLIT1→|              |      |              |      |   ;ラップ（LAP）タイム
	│      |              |              |      |              |      |   ;スタートからゴールまでの区間経過時間
	│      |←---LAP1---→|←---LAP2---→|------|←---LAPn---→|      |
	│      |              |              |      |              |      |
	│─--─|───────|───────|─--─|───────|─--─|

	↑-----(1)            (1)            (1)----(1)            (2)----(3)（「記録内容の表示」に移行）
	│     START                                              GOAL    (4)（「メニューの選択」に戻る）
	│
      （「メニューの選択」から「ストップウオッチ」に移行）                                        

・上図において、スタートしてからゴールをするまでの間に、多くのスプリットタイムを記録することを、本機能の一番の目
　的としている。これらのスプリットタイムは、スタート（START）時のスイッチ操作 (1) を除いて、その後の、２回目以降
　に操作 (1) を行うごとに、PIC の内蔵メモリ（SRAM）に書き込んで記録が取られて行く。
　（スイッチ操作 (1) ENABLE スイッチ ＋ START スイッチ とは、ENABLE スイッチを押しながら START スイッチを通常の
　　ちょん押しをすることを表す）

・なお、このスタート（START）時の スイッチ操作 (1) を契機として、スプリットタイムのカウントが [ 00:00:00 ] から
　開始され、LCD 画面の１行目に表示がされるようになる。そして、"ドーミーソードー" アラーム音とともに LED (緑) (赤) 
　が交互に点滅して、スプリットタイムのカウントがスタート (START) をしたことを知らせる。

			[ xx:xx:xx ]	..... スプリットタイムを１秒ずつ更新しながら表示
			[ xx:xx:xx ]	..... 現在時刻 "HH:MM:SS" を刻々と刻みながら表示

・上述のように、PIC の内蔵メモリ（SRAM）に、そのときのスプリットタイムを書き込んで記録が取られるとき、それを知ら
　せるために "ポッポッ" アラーム音とともに LED (緑) を点滅させる。

・そしてその直後に、LCD 画面の表示が一時的に約５秒間だけ次のように変わって、そのときの記録番号とラップタイムが表
　示される。ラップタイムは、今回測定したスプリットタイムと、前回測定してメモリ（SRAM）に記録されているスプリット
　タイムとの差を、時間計算によって求めたものである。

			[ ** xx ** ]	..... xx に記録番号を表示
			[ xx:xx:xx ]	..... ラップタイムを表示

・このときの、内蔵メモリ（SRAM）に書き込むことが可能なスプリットタイムの最大数は、現在 40 個に制限がしてあり、書
　き込んだ後にその最大数に達したかのチェックを行い、最大数に達した場合には、３秒間次のような警告メッセージを LCD 
　画面に表示して、かつ、"ブッブッブッブッ" アラーム音とともに LED (赤) が点滅を繰り返えす。

			[ xx:xx:xx ]	..... スプリットタイム
			[ Mem Full ]	..... メモリ満タン警告メッセージ

・その後 "ドーソーミードー" アラーム音とともに LED (緑) (赤) が交互に点滅した後、最終の記録番号（40）とラップタイ
　ムが約５秒間表示され、本機能は強制的にゴールにさせられ、スプリットタイムのカウントが停止する。そして、その後は
　右下の LCD 画面になり現在時刻を更新しながら表示し続ける。

		[ ** 40 ** ]	..... 最終の記録番号	[ StpW End ]	..... ストップウオッチの動作が終了した
		[ xx:xx:xx ]	..... ラップタイム	[ xx:xx:xx ]	..... 現在時刻を更新しながら表示し続ける

・本機能ではスタートしてからゴールするまでを長時間使用することを想定しているが、その間ずっと LCD 画面を表示させて
　おく必要はない。電池の消耗を抑えるという観点で本機能では１分間（デフォルト値）どのスイッチも入力がなかった場合
　には、自動的に LCD の電源を切り、本機の PIC をスリープ状態にさせている。

・しかし、このスリープ状態を解除させたい場合には、上述の本機能で使用できる赤字名のスイッチ（ENABLE、START/GOAL 、
　EXIT スイッチ）の内の、どれかを押すことによっていつでも目覚めさせ、直ちに LCD 画面を表示させることができる。

・スリープ状態になるときには、１分（デフォルト値）を経過する３秒前から、秒ごとに "ブッ" アラーム音と LED (緑) を
　瞬間点滅させ、１分を経過直後に "ブッブー" アラーム音とともに LED (緑) を点滅させてから、スリープ状態になる。

・ユーザのスイッチ操作によってスリープ状態から目覚めるときには、目覚めた直後に "ピピッ" アラーム音とともに LED 
　(緑) を点滅させる。また、スリープ中にも本機の存在感を誇示？するために、１分間に１度、"ピッ" ブザー音とともに 
　LED (赤) を瞬間点滅させている。

・また本機能においても、毎時の時報音を出力させるための時間監視と、後述の 6:「週間タイマーの時刻設定」機能で設定を
　した、タイマー一致の時間監視をさせているので、目覚めているとき、スリープ中にかかわらず、時間一致があればそれら
　に応じた各アラーム音の出力をする。

・やがて、ゴールをするためにスイッチ操作 (2) が行われると、最後のスプリットタイムが PIC の内蔵メモリ（SRAM）に書
　き込まれて記録され、"ドーソーミードー" アラーム音とともに LED (緑) (赤) が交互に点滅をするので、それを合図に (2) 
　の操作を止めるようにする。

・またその直後に、LCD 画面の表示が約５秒間だけ記録番号とラップタイムが表示されることは、スイッチ操作 (1) の場合と
　同様である。そして、その後は次の LCD 画面の表示に変わってストップウオッチの動作が終了したことを知らせ、次のスイ
　ッチ操作の指示があるまでは現在時刻を更新しながら表示し続ける。

			[ StpW End ]	..... ストップウオッチの動作が終了した
			[ xx:xx:xx ]	..... 現在時刻を更新しながら表示し続ける

・ゴール（GOAL）をした後のスイッチ操作は (3) または (4) のどちらかで、スイッチ操作 (3) を行った場合には次項の 5:
　「記録内容の表示」機能に移行して、引き続き、今まで PIC の内蔵メモリ（SRAM）に記録されてきた スプリットタイムを
　基に、改めて記録番号、スプリットタイム、ラップタイムを表示させることができる。

・一方、スイッチ操作 (4) を行った場合には「メニューの選択」機能に戻る。しかし、本機の電源を切ったり、新たに本機能
　を実行して新しいスプリットタイムで PIC の内蔵メモリ（SRAM）に上書きをしない限り、今まで記録されてきたスプリット
　タイムはいつまでも残っているので、改めて「メニューの選択」機能で 5:「記録内容の表示」機能を選択すれば、同様に記
　録番号、スプリットタイム、ラップタイムを表示させることができる。

（ヒント）「メニューの選択」機能にはスリープモードがないため、改めてスプリットタイム等を表示させる予定はあるがそ
　　　　　れまでに時間を要する場合は、5:「記録内容の表示」機能にしておいた方がスリープモードがあるので、電池の消
　　　　　耗を抑えるという観点では良い。もちろん、本機の電源を切ればすべてのスプリットタイムの記録は消滅をする。

---------------------------------------------
◎ メニュー項目: 5 ... 「記録内容の表示」機能
---------------------------------------------

・例えばウォーキングなどの外出先で、前項の 4:「ストップウオッチ（長時間）」機能 によって、PIC の内蔵メモリ（SRAM）
　に記録をしたスプリットタイムのデータは、4:「ストップウオッチ（長時間）」機能を終了させた後になっても、帰宅後に、
　本機能で PIC の内蔵メモリ（SRAM）を読み出し、記録番号、スプリットタイム、ラップタイム を 改めて LCD 画面に表示
　をさせることができる。（上の（ヒント）を参照のこと）

・ただし、本機の電源を切ったり、新たに 4:「ストップウオッチ（長時間）」機能を実行して、新しいスプリットタイムで 
　PIC の内蔵メモリ（SRAM）に上書きをした場合は、旧スプリットタイムの記録はすべて消滅をする。（もしも、4:「ストッ
　プウオッチ（長時間）」機能に移行しても、スイッチ操作 (1) を行う以前に、(3) または (4) を行って同機能を終了させ
　た場合には、旧スプリットタイムの記録は消滅をしないですべて残る。）

・「メニューの選択」LCD 画面で、メニュー項目 5: [ MemoDisp ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。または、前項の 4:「ストップウオッチ（長時間）」機能で、スイッチ操作 (3)（ENABLE スイッチ ＋ EXIT 
　スイッチ）を行った場合にも、同機能を終了して本機能に移行（ジャンプ）してくる。

			[ Select_5 ]
			[ MemoDisp ]	..... 5:「記録内容の表示」

　そして、移行をしてきた本「記録内容の表示」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅させて、本
　機能に動作が移ったことを知らせる。

・本機能に移行した直後の LCD 画面表示は次の通りで、１行目には本機能の略名が表示され、２行目には現在時刻 "HH:MM:SS" 
　が刻々と刻まれながら表示される。

			[ MemoDisp ]	..... 本機能の略名を表示
			[ xx:xx:xx ]	..... 現在時刻 "HH:MM:SS" を刻々と刻みながら表示

・ただし、まだ 4:「ストップウオッチ（長時間）」機能が実行されておらず、先に本機能を実行したような場合、すなわち、
　スプリットタイムのデータが内蔵メモリ（SRAM）に１件も記録されていない場合には、LCD 画面の２行目には "None" の文
　字列がブリンク表示される。このときの "None" 文字列は、初めの 0.5 秒間は表示、かつ、"ブッ" アラーム音出力と LED 
　(赤) を瞬間点滅させ、次の 0.5 秒間は文字列を消滅させる ― の点滅表示を１秒周期で繰り返してユーザに注意喚起する。

			[ MemoDisp ]	..... 本機能の略名を表示
			[   None   ]	..... "None" がブリンク表示

・このように、上の "None" 文字列のブリンク表示になったときには、EXIT スイッチを押して「メニューの選択」機能に戻る
　ことしか選択肢はない。

・なお、「記録内容の表示」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示した名前で
　呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │○│   │○│   │●│   │●│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		  LEFT スイッチ ..... １つ前のデータを表示
		 RIGHT スイッチ ..... １つ後のデータを表示

		  EXIT スイッチ ..... 「メニューの選択」に戻る

・本機能では、前項の 4:「ストップウオッチ（長時間）」機能によって、PIC の内蔵メモリ（SRAM）に記録をさせた複数のチ
　ェック地点でのスプリットタイムを、LEFT スイッチ、または RIGHT スイッチを操作するごとに読み出して、そのときの 記
　録番号（チェック地点番号）とともに、改めて時間計算を行って求めたラップタイムの３つの情報を LCD 画面に表示をする。

・このとき読み出しのキーとなる記録番号は、初めてスイッチ操作があった場合には、それが RIGHT スイッチのときは１番が、
　LEFT スイッチのときは記録した最大値が選択されて、それらが初期値となる。

・そして、まず初めに記録番号が次の形式で LCD 画面に表示される。この記録番号は２つのスイッチの内どちらかを操作する
　ごとに更新をするが、RIGHT スイッチの場合には、１ずつ増加（インクリメント、最大値に達したときは次には再び１番に
　戻る）され、一方、LEFT スイッチの場合には、１ずつ減少（デクリメント、１番に達したときは次には再び最大値に戻る）
　されて、LCD 画面に表示がされる。

			[ ** xx ** ]	..... 記録番号 xx を表示
			[          ]	..... ２行目には何も表示されない

・このときの表示される記録番号は、どちらかのスイッチを押している間中ずっと表示され続けるが、手を離した瞬間に次の
　形式でスプリットタイム（１行目）、およびラップタイム（２行目）の表示に切り替わる。

			[ xx:xx:xx ]	..... スプリットタイムを表示
			[ xx:xx:xx ]	..... ラップタイムを表示

・このようにして２つのスイッチの内どちらかを操作するごとに、記録番号の表示と、スプリットタイム、ラップタイムの表
　示に切り替わりながら LCD 画面に表示されるが、本機能においても前項の 4:「ストップウオッチ（長時間）」機能と同様
　に、１分間（デフォルト値）どのスイッチの入力もなかった場合には、自動的に LCD の電源を切り、本機の PIC をスリー
　プ状態にさせて電池の消耗を抑えている。

・このスリープ状態を解除させたい場合には、上述の本機能で使用できる赤字名のスイッチ（LEFT、RIGHT 、EXIT スイッチ）
　の内の、どれかを押すことによっていつでも目覚めさせ、直ちに LCD 画面を表示させることも前項の機能と同様である。

・しかし、スリープ状態から目覚めたときには、一旦、次の形式で刻々と更新をしながら現在時刻が表示されるようになるが、
　次に、LEFT、または RIGHT スイッチのどちらかを操作することによって、再び上述した形式で、記録番号（チェック地点番
　号）とスプリットタイム、ラップタイムの表示に切り替わる。

			[ MemoDisp ]	..... 本機能の略名を表示
			[ xx:xx:xx ]	..... 現在時刻 "HH:MM:SS" を刻々と刻みながら表示

・また本機能においても、毎時の時報音を出力させるための時間監視と、タイマー一致の時間監視をさせているので、目覚め
　ているとき、スリープ中にかかわらず、時間一致があればそれらに応じた各アラーム音の出力をする。

・本機能を終了させたいときには EXIT スイッチ を押すことによって「メニューの選択」機能に戻るが、上述したように、本
　機の電源を切ったり、新しいスプリットタイムで PIC の内蔵メモリ（SRAM）に上書きをしない限り、記録されたスプリット
　タイムはいつまでも残っているので、再び（何度でも）本機能を繰り返すことができる。

-----------------------------------------------------
◎ メニュー項目: 6 ... 「週間タイマーの時刻設定」機能
-----------------------------------------------------

・本機では９つのメニュー項目（機能）の内、1:「現在時刻の表示」機能、4:「ストップウオッチ(長時間)」機能、5:「記録
　内容の表示」機能の３機能についてのみ、リアルタイムクロック（RTC）モジュールによる時計機能を動作させている。

・そこで、あらかじめ本機能によってタイマー時間を設定しておくと、そのタイマー時間と現在時刻が一致したときに、アラ
　ーム音を出力することができる。本機は携帯仕様のためにリレー等を動作させてもあまり意味がないので、アラーム音の出
　力だけをする。

・本機能は機能名通り週間タイマーとなっており、曜日、時、分の情報を PIC の内蔵メモリ（SRAM）に書き込むとともに、
　EEPROM にもバックアップがとられるため、本機の電源を切っても設定情報が消えることはない。 そのため次項の 7:「週間
　タイマーの設定表示と消去」機能で消去をしない限り、毎週同時刻になるとアラーム音を出力する。

・「メニューの選択」LCD 画面で、メニュー項目 6: [ WkTimSet ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。

			[ Select_6 ]
			[ WkTimSet ]	..... 6:「週間タイマーの時刻設定」

　そして、移行をしてきた本「週間タイマーの時刻設定」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅さ
　せて、本機能に動作が移ったことを知らせる。

・なお、「週間タイマーの時刻設定」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示し
　た名前で呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │●│   │●│   │●│   │●│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		  LEFT スイッチ ..... ブリンク位置のポインタを - 1
		 RIGHT スイッチ ..... ブリンク位置のポインタを + 1

		  DOWN スイッチ ..... ブリンク位置の値を - 1
		    UP スイッチ ..... ブリンク位置の値を + 1

		  EXIT スイッチ ..... タイマー用メモリに書き込み、次の設定に移る

		  LEFT スイッチ + 
		 RIGHT スイッチ ..... 「週間タイマーの時刻設定」を中断し、「メニューの選択」に戻る

		 RIGHT スイッチ + 
		  LEFT スイッチ ..... 「週間タイマーの時刻設定」を中断し、「メニューの選択」に戻る

	  LEFT(ENABLE) スイッチ + 
		  EXIT スイッチ ..... 「週間タイマーの設定表示と消去」に移行

	   EXIT スイッチ 長押し ..... 「メニューの選択」に戻る

・本機能のタイマー時刻設定の LCD 画面表示は次の通りで、設定をする前の初期のときの２行目にはすべて "0" が表示され、
　先頭の "0" 位置がブリンク表示される。"00:00" の位置に "時"、"分" を設定し、右端の "0" の位置には "曜日" を表す
　数字を設定する。

			[ Set EDAY ]	..... 右側に曜日 (略名) を表示
			[ 00:00  0 ]	..... "HH:MM"、"曜日を表す数字" を設定

・先頭の "0" 位置がブリンク表示されているのは、初めに "時" を設定することを表しており、UP スイッチ、または DOWN 
　スイッチを押すことによって、"時" の設定値を 24 時間表示で入力する。UP スイッチ を押すごとに１ずつ増加し、DOWN 
　スイッチを押すごとに１ずつ減少することができる。このときの増減幅を大きくしたい場合には、UP スイッチ、または 
　DOWN スイッチを押したままにしていると、１秒当たり 4 ～ 5 の増減幅で更新をするようになる。

・"時" の設定が済んだら次に、"分" を設定するために RIGHT スイッチを押すと、ブリンク位置が "分" の左側 "0" 位置に
　移動をする。"時" のときと同様に、UP スイッチ、または DOWN スイッチを押すことによって、"分" を設定する。

・最後に "曜日" を設定するためにもう一度 RIGHT スイッチを押すと、次にはブリンク位置が右端の "0" の位置に移動をす
　るので、同様に UP スイッチ、または DOWN スイッチで "曜日" を表す数字を設定する。すると、数字に対応した曜日の略
　名が LCD 画面１行目の右側に表示される。 その数字と "曜日"、"略名" の対応表を次に示す。

		┌───┬──┬──┬──┬──┬──┬──┬──┬──┐
		│設定値│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │
		├───┼──┼──┼──┼──┼──┼──┼──┼──┤
		│ 曜日 │毎日│ 日 │ 月 │ 火 │ 水 │ 木 │ 金 │ 土 │
		├───┼──┼──┼──┼──┼──┼──┼──┼──┤
		│(略名)│EDAY│ SUN│ MON│ TUE│ WED│ THU│ FRI│ SAT│
		└───┴──┴──┴──┴──┴──┴──┴──┴──┘

・このように、RIGHT スイッチ は、押すごとにブリンク位置が１ずつ増加（右に移動）をするが、逆に LEFT スイッチ は、
　押すごとにブリンク位置が１ずつ減少（左に移動）をするので、希望するブリンク位置を自由に変更することができ、設
　定をする３つの "時"、"分"、"曜日" 情報は、どの順序で行っても構わない。

・こうして "時"、"分"、"曜日" の３つのタイマー情報の設定ができたら、次に EXIT スイッチ を押すことによって、タイ
　マー情報用に割り当てた PIC の内蔵メモリ（SRAM）に書き込まれる。この書き込みを行うときには、事前に、既に書き込
　まれているタイマー情報のすべてと、書き込もうとしているタイマー情報とが比較されて、一致する情報があるときには、
　"ブッ" アラーム音の出力と LED (赤) を点滅させて、注意を喚起するとともに書き込みを中止する。

・また、内蔵メモリ（SRAM）に書き込むことが可能なタイマー情報の最大数は、現在 20 個に制限がしてあり、既に最大数に
　達している場合には、次のようなエラーメッセージを約３秒間 LCD 画面に表示をして、かつ、"ブッブッブッブッ" アラー
　ム音とともに LED (赤) が点滅を繰り返えす。その後、本機能を強制終了して「メニューの選択」機能に戻る。

			[ Set Err! ]	..... エラーメッセージ
			[ Mem Full ]	..... メモリ満タン警告メッセージ

・PIC の内蔵メモリ（SRAM）に正常に書き込みができた場合には、"ポッポッ" アラーム音出力と LED (緑) を点滅させて、
　正常書き込みができたことを報告する。そして、LCD 画面の２行目を、上述のようにすべて "0" 表示にし、かつ、先頭の 
　"0" 位置をブリンク表示して、初期の LCD 画面に戻す。（初期の LCD 画面には戻さないように変更）

・上述のように、本機能での EXIT スイッチの動作は、他の機能の場合と異なっているので注意が必要である（他の７つのメ
　ニュー項目（機能）のすべてでは、「メニューの選択」機能に戻るときに用いる）。本機能での EXIT スイッチは、タイマ
　ー情報を PIC の内蔵メモリ（SRAM）に書き込む指示をし、書き込んだ後、引き続き次の新たなタイマー情報の設定操作を
　行うことができるようにする。

・このようにして PIC の内蔵メモリ（SRAM）に書き込まれたタイマー情報は、上述した 1:「現在時刻の表示」機能、4:「ス
　トップウオッチ(長時間)」機能、5:「記録内容の表示」機能の３機能の内のどれかが実行されているときに、現在時刻が毎
　分 "00" 秒になるごとにタイマー一致があるかの時間監視をさせ、もし一致があった場合には、一致をした "00" 秒を始め
　として合計 10 回、毎秒ごとに "ピポッピポッ" アラーム音の出力と LED (緑) を点滅させて、ユーザに知らせる。

・本機能でタイマー情報の設定操作中に、何らかの理由で本機能を中断したくなった場合には、LEFT スイッチ ＋ RIGHT ス
　イッチ、または RIGHT スイッチ ＋ LEFT スイッチ の操作をすることで、設定している情報は書き込まれることはなく、
　本機能を途中で中断終了して「メニューの選択」機能に戻る。

・本機能では、EXIT スイッチを３秒以上の長押しをすることによって、本機能を正常に終了させ「メニューの選択」機能に
　戻ることができる。このとき、現在 PIC の内蔵メモリ（SRAM）に書き込まれているタイマー情報は、同じ PIC の内蔵メモ
　リ（EEPROM）にもバックアップをとってから本機能を終了する。

-----------------------------------------------------------
◎ メニュー項目: 7 ... 「週間タイマーの設定表示と消去」機能
-----------------------------------------------------------

・前項の 6:「週間タイマーの時刻設定」機能 によってタイマー情報の設定を行った直後や、設定を行ってから何日も経って、
　再度現在の設定状態の確認をしたいときなど、本機能によって PIC の内蔵メモリ（SRAM）に書き込まれている、タイマー
　情報の現在の設定状態を１件ずつ LCD 画面上に読み出して確認をすることができる。

・また、本機能では再確認をした結果、不要になったタイマー情報を個別に内蔵メモリ（SRAM）から消去をしたり、すべての
　タイマー情報を一度に全消去をしたりすることができる。このように内蔵メモリ（SRAM）内の情報の消去をした場合には、 
　バックアップ用の内蔵メモリ（EEPROM）も自動で更新をする。

・「メニューの選択」LCD 画面で、メニュー項目 7: [ WkTimDsp ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。または、前項の 6:「週間タイマーの時刻設定」機能で、スイッチ操作（LEFT(ENABLE) スイッチ ＋ EXIT 
　スイッチ）を行った場合にも、 同機能を終了して本機能に移行（ジャンプ）してくる。

			[ Select_7 ]
			[ WkTimDsp ]	..... 7:「週間タイマーの設定表示と消去」

　そして、移行をしてきた本「週間タイマーの設定表示と消去」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) 
　を点滅させて、本機能に動作が移ったことを知らせる。

・なお、「週間タイマーの設定表示と消去」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字
　で示した名前で呼ぶ。 また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │●│   │●│   │●│   │●│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		  LEFT スイッチ ..... １つ前の登録情報を表示
		 RIGHT スイッチ ..... １つ後の登録情報を表示

		  DOWN スイッチ ..... 表示している登録情報を消去

		    UP スイッチ +
		  DOWN スイッチ ..... すべての登録情報を消去

		  EXIT スイッチ ..... 「メニューの選択」に戻る

・本機能での LCD 画面の表示は次の通りで、まず２行目の nn には仮につけられた登録情報の番号が、xx:xx にはタイマー
　時間の時分 "HH:MM" が、そして１行目の www には曜日 (略名) を表示する。本機能に移行をしてきた直後には、nn の登
　録情報の番号には "01" が選択される。そして、PIC の内蔵メモリ（SRAM）に書き込まれている、１件目のタイマー情報が
　読み出され、その情報の時分 "HH:MM" と曜日 (略名) が表示される。

			[ Dsp  www ]	..... www: 曜日 (略名) を表示
			[ xx:xx nn ]	..... xx:xx 時分、nn: 登録情報の番号

・２件目以降のタイマー情報を表示させるときには、RIGHT スイッチ、または LEFT スイッチを押すことによって行ない、
　RIGHT スイッチ は押すごとに、登録情報の仮番号が１ずつ増加してその登録情報を表示する。逆に、LEFT スイッチ は押
　すごとに、登録情報の仮番号が１ずつ減少してその登録情報を表示する。

・そして、今 LCD 画面に表示されているタイマー情報が不要になった場合には、DOWN スイッチを押すことによって、その表
　示されているタイマー情報だけを、内蔵メモリ（SRAM）から個別に消去することができる。また、すべての登録情報が不要
　になった場合には、UP スイッチ ＋ DOWN スイッチのスイッチ操作をすることによって、タイマー情報に割り当てられてい
　る内蔵メモリ（SRAM）のすべてを消去 する。これらの消去をしたときには、"ピッピッ" アラーム音の出力と LED (緑) を
　点滅させる。

・また、表示をさせる登録情報が１件もない場合には、nn は "00"、xx:xx は "00:00" 表示となり、www 位置には "None" 
　の文字列が表示されるが、このときの "None" 文字列は、初めの 0.5 秒間は表示、かつ、"ブッ" アラーム音出力と LED 
　(赤) を瞬間点滅させ、次の 0.5 秒間は文字列を消滅させる ― の点滅表示を１秒周期で繰り返してユーザに知らせる。

			[ Dsp None ]	..... "None" がブリンク表示
			[ 00:00 00 ]	..... 00:00 時分、00: 登録情報の番号

・タイマー情報の LCD 画面表示の確認が済んだら、EXIT スイッチ を押すと「メニューの選択」機能に戻ることができる。 
　また、上の "None" 文字列のブリンク表示になったときには、EXIT スイッチ を押すことしか選択肢はない。

---------------------------------------------
◎ メニュー項目: 8 ... 「現在時刻の設定」機能
---------------------------------------------

・本機の電源を初めて入れたときや、バックアップ用バッテリーを交換したときなどに、エラーメッセージが LCD 画面に表示
　され、それに応答をすると、リアルタイムクロック（ RTC ）モジュールが初期設定される。しかし、年月日、時分秒が 
　"2022/01/01"、"00:00:00" と、RTC モジュールをプログラミングしたときの初期値に設定がされるので、これをリアルな現
　在時刻に設定をし直す必要がある。本機能はそのようなときのために設けられている。

・「メニューの選択」LCD 画面で、メニュー項目 8: [ ClockAdj ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。または、1:「現在時刻の表示」機能で、ENABLE スイッチ ＋ EXIT スイッチの操作を行った場合にも、同
　機能を終了して本機能に移行（ジャンプ）してくる。

			[ Select_8 ]
			[ ClockAdj ]	..... 8:「現在時刻の設定」

　そして、移行をしてきた本「現在時刻の設定」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅させて、本
　機能に動作が移ったことを知らせる。

・なお、「現在時刻の設定」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示した名前で
　呼ぶ。また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │●│   │●│   │●│   │●│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		  LEFT スイッチ ..... ブリンク位置のポインタを - 1
		 RIGHT スイッチ ..... ブリンク位置のポインタを + 1

		  DOWN スイッチ ..... ブリンク位置の値を - 1
		    UP スイッチ ..... ブリンク位置の値を + 1

		  EXIT スイッチ ..... 「現在時刻の設定」を終了し、「現在時刻の表示」に移行

		  LEFT スイッチ + 
		 RIGHT スイッチ ..... 「現在時刻の設定」を中断し、「現在時刻の表示」に移行

		 RIGHT スイッチ + 
		  LEFT スイッチ ..... 「現在時刻の設定」を中断し、「現在時刻の表示」に移行

・本機能に移行（ジャンプ）してくると、まず、LCD 画面には次のように表示がされ、１行目では年月日を設定する画面であ
　ることを表している。そして２行目には RTC モジュールに設定がされている現在の年月日が表示され、年 "yy" の左文字
　がブリンク表示されて、これから 年 "yy" が設定変更の対象であることを意味する。

			[ Date Set ]	..... 年月日設定メッセージ
			[ yy/nn/dd ]	..... 年月日の表示と設定

・このブリンク表示される位置を変更したい場合には、RIGHT スイッチ、または LEFT スイッチ を押すことによって、ブリ
　ンク位置が右または左に移動をするので、変更をしたい 年 "yy"、月 "nn"、日 "dd" の位置にポイントする。
　（この 月 "nn" という表現は、本来 月 "mm" とすべきだが、分 "mm" を優先させたので 月 "nn" とした）

・このとき、日 "dd" がブリンク表示されているときに RIGHT スイッチを押すと、次の時分秒を設定する LCD 画面 に変わ
　って 時 "hh" がブリンク表示される。また 年 "yy" がブリンク表示されているときに LEFT スイッチを押すと、 同様の 
　LCD 画面に変わって 秒 "ss" がブリンク表示される。

			[ Time Set ]	..... 時分秒設定メッセージ
			[ hh:mm:ss ]	..... 時分秒の表示と設定

・また、秒 "ss" がブリンク表示されているときに RIGHT スイッチを押すと、前の年月日を設定する LCD 画面 に変わって 
　年 "yy" がブリンク表示される。また 時 "hh" がブリンク表示されているときに LEFT スイッチを押すと、同様の LCD 画
　面に変わって 日 "dd" がブリンク表示される。

・このように、年 "yy"、月 "nn"、日 "dd"、時 "hh"、分 "mm"、秒 "ss" の、どこの位置にも自由にポイントすることがで
　きるので、次には、UP スイッチ、または DOWN スイッチを押すことによって、ブリンク位置の項目の設定値を変更するこ
　とができる。

・すなわち、UP スイッチを押すごとに設定値が１ずつ増加し、DOWN スイッチを押すごとに１ずつ減少する。このときの増減
　幅を大きくしたい場合には、UP スイッチ、または DOWN スイッチを押したままにしていると、１秒当たり 4 ～ 5 の増減
　幅で更新をするようになる。

・以上のようにしてリアルな現在時刻の設定値が入力できたら、最後に EXIT スイッチ を押すと、リアルタイムクロック
　（ RTC ）モジュールにその設定値が書き込まれる。そして、本機能は終了して 1:「現在時刻の表示」機能 に移行（ジャ
　ンプ）をする。「メニューの選択」機能に戻るのではなく、1:「現在時刻の表示」機能に移行するのは、正しく設定変更が
　できたかを直ちに確認ができるようにするためである。

・本機能で現在時刻の設定操作中に、何らかの理由で本機能を中断したくなった場合には、LEFT スイッチ ＋ RIGHT スイッ
　チ、または RIGHT スイッチ ＋ LEFT スイッチ の操作をすることで、設定値は RTC モジュールに書き込まれることはなく、
　本機能を途中で中断終了して 1:「現在時刻の表示」機能に移行する。

-----------------------------------------------------
◎ メニュー項目: 9 ... 「スリープ移行時間の変更」機能
-----------------------------------------------------

・本機では９つのメニュー項目（機能）の内、1:「現在時刻の表示」機能、4:「ストップウオッチ(長時間)」機能、5:「記録
　内容の表示」機能の３機能についてのみ、スリープ機能が動作するようにさせている。特に、1:「現在時刻の表示」機能、
　4:「ストップウオッチ(長時間)」機能については、長時間に亘る使用が予想されるため、一定時間スイッチの入力がない場
　合には自動的に LCD の電源を切り、本機の PIC をスリープ状態にさせて電池の消耗を抑えるようにしている。

・その一定時間を、メニュー項目 1: では 3 分、メニュー項目 4: では 1 分、メニュー項目 5: では 1 分 と、当初は固定
　をしていたが、使用状況によっては変更ができる方がより便利 ― と考え直して、ここに 1 分 ～ 15 分 の範囲 で自由に
　変更ができる、9:「スリープ移行時間の変更」機能を追加した。

・「メニューの選択」LCD 画面で、メニュー項目 9: [ SleepTim ] を選択後に EXIT スイッチを押すと、本機能に移行（ジャ
　ンプ）してくる。

			[ Select_9 ]
			[ SleepTim ]	..... 9:「スリープ移行時間の変更」

　そして、移行をしてきた本「スリープ移行時間の変更」機能では、"ピポッピポッ" アラーム音の出力と LED (緑) を点滅さ
　せて、本機能に動作が移ったことを知らせる。

・なお、「スリープ移行時間の変更」機能では次図に示す黒塗りのスイッチだけを使用し、それらのスイッチ名を赤字で示し
　た名前で呼ぶ。 また、本機能においてのスイッチ操作の要点を先にまとめておくと、次のようになる。

		                           ENABLE   START/
		          ZERO    TMODE    /ALARM    GOAL
		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
		│●│   │●│   │●│   │●│   │●│
		└─┘   └─┘   └─┘   └─┘   └─┘
		 EXIT     DOWN      UP      LEFT     RIGHT

		  LEFT スイッチ ..... ブリンク位置のポインタを - 1
		 RIGHT スイッチ ..... ブリンク位置のポインタを + 1

		  DOWN スイッチ ..... ブリンク位置の値を - 1
		    UP スイッチ ..... ブリンク位置の値を + 1

		  DOWN スイッチ + 
		    UP スイッチ ..... すべてのデフォルト値を一括設定

		    UP スイッチ + 
		  DOWN スイッチ ..... すべてのデフォルト値を一括設定

		  LEFT スイッチ + 
		 RIGHT スイッチ ..... 「スリープ移行時間の変更」を中断し、「メニューの選択」に戻る

		 RIGHT スイッチ + 
		  LEFT スイッチ ..... 「スリープ移行時間の変更」を中断し、「メニューの選択」に戻る

		  EXIT スイッチ ..... 「スリープ移行時間の変更」を終了し、「メニューの選択」に戻る

・本機能に動作が移ると LCD 画面には、次の形式で、現在設定されているそれぞれの値（分）が２行目に表示され、かつ、
　２行目の先頭がブリンク表示、すなわち メニュー項目 1 の設定値を変更するようにユーザに促す。 下の写真例ではデフ
　ォルト（既定）値が表示されている。

			[ M1,M4,M5 ]	..... M1: メニュー項目 1, M4: メニュー項目 4, M5: メニュー項目 5
			[ xx xx xx ]	..... 現在設定されている、それぞれの値（分）が表示される

・このブリンク表示の位置は、LEFT スイッチ、または RIGHT スイッチ を押すことによって、自由に左または右に移動をす
　るので、変更をしたいメニュー項目の位置にポイントする。

・変更をしたいメニュー項目が決まったら、次に UP スッチを押すごとに１ずつ増加、または DOWN スイッチを押すごとに１
　ずつ減少することができる。これらの設定値は 1 分 ～ 15 分 の範囲で自由に変更設定をすることができる。

・またこの設定中に、UP スッチ ＋ DOWN スイッチ 、または DOWN スッチ ＋ UP スイッチ の操作をすると、現在どのよう
　な設定値が表示されていても、３つすべての設定値を、一瞬にデフォルト値（すなわち、メニュー項目 1: では 3 分、メ
　ニュー項目 4: では 1 分、メニュー項目 5: では 1 分）の表示に一括して戻す機能を持つ。

・３つすべての設定が済んだら最後に EXIT スイッチ を押すと、それらの設定値が新たなバックアップデータとして EEPROM 
　に書き込みが行われ、本機能を終了して「メニューの選択」機能に戻る。

・なお、何らかの理由で設定中に本機能を中断したくなった場合には、LEFT スイッチ ＋ RIGHT スイッチ、または RIGHT ス
　イッチ ＋ LEFT スイッチ の操作をすることで、それまでの変更されて表示されている設定値は破棄され、 本機能を終了
　して「メニューの選択」機能に戻る。

#endif

;==========================================================================

;	PIC16F1827 のピンと用途

;	 (1) RA2: LED(緑) 出力			(18) RA1: LCD 電源制御
;	 (2) RA3: LED(赤) 出力			(17) RA0: ブザー音 出力	
;	 (3) RA4: スタート信号入力		(16) OSC1: オシレータ水晶入力
;	 (4) RA5: Vpp / CLEAR スイッチ入力	(15) OSC2: オシレータ水晶出力
;	 (5) VSS: 電源 GND			(14) VDD: 電源 +3.3V DC
;	 (6) RB0: INT 外部割り込み入力		(13) RB7: RIGHT / START/GOAL スイッチ入力
;	 (7) RB1: I2C SDA 入出力		(12) RB6: LEFT / ENABLE/ALARM スイッチ入力
;	 (8) RB2: DOWN / ZERO スイッチ入力	(11) RB5: EXIT スイッチ入力
;	 (9) RB3: UP / TMODE スイッチ入力	(10) RB4: I2C SCL 出力

;==========================================================================

		list		p=pic16f1827		;デバイス情報
		include		p16f1827.inc		;インクルードファイル
		errorlevel	-302			;Eliminate bank warning

;==========================================================================
;		コンフィギュレーションワードの設定
;==========================================================================

	__config _CONFIG1, _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF
	__config _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_HI & _LVP_OFF

; ------------------------------------
; CONFIGURATION WORD 1 (ADDRESS:8007H)		Data Sheet DS41391B - page 50
; ------------------------------------
;
;     CONFIG1 = 00 1001 1000 0001
;	        || |||| |||| ||||
;	bit2-0  || |||| |||| |+++---- FOSC<2:0>: オシレータ選択ビット
;	        || |||| |||| |          111 = ECH:    外部クロック、高消費電力モード(4-20 MHz):  OSC1/CLKINピンに供給
;	        || |||| |||| |          110 = ECM:    外部クロック、中消費電力モード(0.5-4 MHz): OSC1/CLKINピンに供給
;	        || |||| |||| |          101 = ECL:    外部クロック、低消費電力モード(0-0.5 MHz): OSC1/CLKINピンに供給
;	        || |||| |||| |          100 = INTOSC: 内部HFINTOSC CLKINピンはI/Oとして機能
;	        || |||| |||| |          011 = EXTRC:  CLKINピンに外部RC回路を接続
;	        || |||| |||| |          010 = HS:     OSC1とOSC2ピンの間に高速水晶/セラミック振動子を接続
;	        || |||| |||| |      >   001 = XT:     OSC1とOSC2ピンの間に水晶/セラミック振動子を接続
;	        || |||| |||| |          000 = LP:     OSC1とOSC2ピンの間に低消費電力水晶振動子を接続
;	        || |||| |||| |
;	bit4-3  || |||| |||+ +------- WDTE<1:0>: ウォッチドッグ タイマ イネーブルビット
;	        || |||| |||             11 = ON:     WDTを有効
;	        || |||| |||             10 = NSLEEP: WDTを動作時は有効、スリープ中は無効
;	        || |||| |||             01 = SWDTEN: WDTをWDTCONレジスタのSWDTENビットで制御
;	        || |||| |||         >   00 = OFF:    WDTを無効
;	        || |||| |||           _____
;	bit5    || |||| ||+---------- PWRTE: パワーアップ タイマ イネーブルビット
;	        || |||| ||              1 = OFF: PWRTを無効
;	        || |||| ||          >   0 = ON:  PWRTを有効
;	        || |||| ||
;	bit6    || |||| |+----------- MCLRE: MCLR/VPPピン機能選択ビット
;	        || |||| |              LVPビット=0 の場合
;	        || |||| |               1 = ON:  MCLR/VPPピンの機能はMCLR、弱プルアップを有効
;	        || |||| |           >   0 = OFF: MCLR/VPPピンはデジタル入力、MCLRは無効、弱プルアップはWPUA3ビットで制御
;	        || |||| |             __
;	bit7    || |||| +------------ CP: コード保護ビット
;	        || ||||             >   1 = OFF: プログラムメモリのコード保護を無効
;	        || ||||                 0 = ON:  プログラムメモリのコード保護を有効
;	        || ||||               ___
;	bit8    || |||+-------------- CPD: データコード保護ビット
;	        || |||              >   1 = OFF: データメモリのコード保護を無効
;	        || |||                  0 = ON:  データメモリのコード保護を有効
;	        || |||
;	bit10-9 || |++--------------- BOREN<1:0>: ブラウンアウト リセット イネーブルビット
;	        || |                    11 = ON:     BORを有効
;	        || |                    10 = NSLEEP: BORを動作時は有効、スリープ中は無効
;	        || |                    01 = SBODEN: BORをBORCONレジスタのSBORENビットで制御
;	        || |                >   00 = OFF:    BORを無効
;	        || |                  ________
;	bit11   || +----------------- CLKOUTEN: クロック出力イネーブルビット
;	        ||                     FOSCビットがLP、XT、HSモードの場合
;	        ||                  >   このビットを無視しCLKOUT機能を無効、CLKOUTピンはI/Oとして機能
;	        ||                     FOSCビットがその他のモードの場合
;	        ||                      1 = OFF: CLKOUT機能を無効、CLKOUTピンはI/Oとして機能
;	        ||                      0 = ON:  CLKOUTピンのCLKOUT機能を有効
;	        ||
;	bit12   |+------------------- IESO: 内部/外部切り換えビット
;	        |                       1 = ON:  内部/外部切り換えモードを有効
;	        |                   >   0 = OFF: 内部/外部切り換えモードを無効
;	        |
;	bit13   +-------------------- FCMEN: フェイルセーフ クロックモニタ イネーブルビット
;	                                1 = ON:  フェイルセーフ クロックモニタと内部/外部切り換えの両方を有効
;	                            >   0 = OFF: フェイルセーフ クロックモニタを無効
;
; ------------------------------------
; CONFIGURATION WORD 2 (ADDRESS:8008H)		Data Sheet DS41391B - page 52
; ------------------------------------
;
;     CONFIG2 = 01 1000 1111 1111
;	        || |||| |||| ||||
;	bit1-0  || |||| |||| ||++---- WRT<1:0>: フラッシュメモリ自己書き込み保護ビット
;	        || |||| |||| ||     >   11 = OFF:  書き込み保護を無効
;	        || |||| |||| ||         10 = BOOT: 0000h～01FFhを書き込み保護、0200h～0FFFhをEECON制御で変更可能
;	        || |||| |||| ||         01 = HALF: 0000h～07FFhを書き込み保護、0800h～0FFFhをEECON制御で変更可能
;	        || |||| |||| ||         00 = ALL:  0000h～0FFFhを書き込み保護、EECON制御によるアドレス変更を不可
;	        || |||| |||| ||
;	bit3-2  || |||| |||| ++------ 未実装
;	        || |||| ||||
;	bit4    || |||| |||+--------- 予約
;	        || |||| |||
;	bit7-5  || |||| +++---------- 未実装
;	        || ||||
;	bit8    || |||+-------------- PLLEN: PLLイネーブルビット
;	        || |||                  1 = ON:  4xPLLを有効
;	        || |||              >   0 = OFF: 4xPLLを無効
;	        || |||
;	bit9    || ||+--------------- STVREN: スタック オーバーフロー/アンダーフロー リセット イネーブルビット
;	        || ||                   1 = ON:  スタックのオーバーフロー/アンダーフローによってリセットを発生させる
;	        || ||               >   0 = OFF: スタックのオーバーフロー/アンダーフローによってリセットを発生させない
;	        || ||
;	bit10   || |+---------------- BORV: ブラウンアウト リセット電圧選択ビット
;	        || |                    1 = LO: ブラウンアウト リセット電圧(VBOR)のトリップポイントを低に設定
;	        || |                >   0 = HI: ブラウンアウト リセット電圧(VBOR)のトリップポイントを高に設定                   
;	        || |
;	bit11   || +----------------- 未実装
;	        ||                    _____
;	bit12   |+------------------- DEBUG: インサーキット デバッガモード ビット
;	        |                   >   1 = OFF: インサーキット デバッガを無効、ICSPCLKとICSPDATは汎用I/Oピンとして機能
;	        |                       0 = ON:  インサーキット デバッガを有効、ICSPCLKとICSPDATはデバッガ専用
;	        |
;	bit13   +-------------------- LVP: 低電圧プログラミング イネーブルビット
;	                                1 = ON:  低電圧プログラミングを有効
;	                            >   0 = OFF: プログラミング時にMCLRに高電圧の印加が必要

;==========================================================================
;		定数の定義と変数のレジスタ割付け
;==========================================================================

		radix	dec

;#define 	xx_debug			;TMR1 基準時間の調整支援（関連６か所あり）

#define 	ver_no	"1.04"

linear_memory	equ	h'2000' + 80			  ;リニアデータメモリの先頭アドレス
timer_memory	equ	linear_memory			  ;タイマー用メモリの先頭アドレス
timer_capacity	equ	20				  ;タイマー用メモリの記憶容量の最大値
split_memory	equ	timer_memory + 3 * timer_capacity ;スプリット用メモリの先頭アドレス
split_capacity	equ	50				  ;スプリットタイムの記憶容量の最大値
next_memory	equ	split_memory + 3 * split_capacity ;次に使用できるメモリの先頭アドレス

_BZ		equ	0			;アラーム音 出力	;┐
_PWcntl		equ	1			;LCD 電源制御		;│
_ledG		equ	2			;LED(緑)		;│PORTA
_ledR		equ	3			;LED(赤)		;│
_Start		equ	4	;Start 信号 (Start/Stop スイッチ)	;│
_swCLR		equ	5			;CLEAR  スイッチ	;┘

SDA		equ	1			;I2C-LCD SDA		;┐
SCL		equ	4			;I2C-LCD SCL		;│
_swDWN		equ	2			;DOWN   スイッチ	;│
_swZER		equ	2			;ZERO   スイッチ	;│
_swUP		equ	3			;UP     スイッチ	;│
_swMOD		equ	3			;TMODE  スイッチ	;│PORTB
_swEXT		equ	5			;EXIT   スイッチ	;│
_swLEF		equ	6			;LEFT   スイッチ	;│
_swEN		equ	6			;ENABLE スイッチ	;│
_swALM		equ	6			;ALARM  スイッチ	;│
_swRIG		equ	7			;RIGHT  スイッチ	;│
_swSTA		equ	7			;START/GOAL スイッチ	;┘

xx		equ	-33			;補正値
basic_const	equ	65536 - (10000 + xx)	;(4 / 4MHz) * 10000 = 0.01 S = 10 mS

f_do2		equ	65536 -  478		;ド(1046.52 Hz)  at 4MHz
f_rah		equ	65536 -  568		;ラ (880.00 Hz)
f_soh		equ	65536 -  638		;ソ (784.00 Hz)
f_mih		equ	65536 -  758		;ミ (659.26 Hz)
f_doh		equ	65536 -  956		;ド (523.26 Hz)
f_ra		equ	65536 - 1136		;ラ (440.00 Hz)
f_so		equ	65536 - 1276		;ソ (392.00 Hz)
f_mi		equ	65536 - 1517		;ミ (329.63 Hz)
f_do		equ	65536 - 1911		;ド (261.63 Hz)
f_do_		equ	65536 - 3822		;ド (130.82 Hz)

po_tim		equ	100			;音長(ms)
pi_tim		equ	100			;音長
bu_tim		equ	100			;音長
buu_tim		equ	250			;音長
dms_tim		equ	200			;音長

		cblock	h'20'
temp_hh						;仮の時_BCD カウンタ
temp_mm						;仮の分_BCD カウンタ
temp_ss						;仮の秒_BCD カウンタ
uru_flg						;0:平年 / 1:閏年
cur_yh						;年(上位2桁)(変)_BCD カウンタ
cur_yl						;年(下位2桁)(変)_BCD カウンタ
cur_nn						;月(変)_BCD カウンタ
cur_week					;週位置カウンタ（曜日 1～7）
xxx_yh						;ワーク

bcd_hh_s					;時_BCD カウンタ	;┐
bcd_mm_s					;分_BCD カウンタ	;│順序を変更しないこと!（スプリット: 経過時間用）
bcd_ss_s					;秒_BCD カウンタ	;┘
bcd_hh_l					;時_BCD カウンタ	;┐
bcd_mm_l					;分_BCD カウンタ	;│順序を変更しないこと!（ラップ: 区間経過時間用）
bcd_ss_l					;秒_BCD カウンタ	;┘
bcd_hh_w					;時_BCD カウンタ	;┐
bcd_mm_w					;分_BCD カウンタ	;│順序を変更しないこと!（ワーク用）
bcd_ss_w					;秒_BCD カウンタ	;│
bcd_xx_w					;1/100秒_BCD カウンタ	;┘

menu_no						;メニュー番号
blk_point					;ブリンク表示位置ポインタ
dsp_point					;表示位置ポインタ
time_flg					;時間表示モードフラグ
						; bit1: 0:24H/1:12H
						; bit0: 0:am/1:pm
stat_flg					;進行状態フラグ
						; bit7: メモリ書き込み指示フラグ
						; bit6: スイッチ入力有りフラグ
						; bit5: ラップタイム表示済みフラグ
						; bit4: ラップタイム表示指示フラグ
						; bit3: ストップウオッチ動作終了フラグ
						; bit2: ストップウオッチ動作中フラグ
						; bit1: 経過時間更新フラグ
						; bit0: 現在時刻更新フラグ
stat2_flg					;進行状態-2フラグ
						; bit7: 処理終了（エグジット）フラグ
						; bit6: 例外終了（次処理に移行）フラグ
						; bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
						; bit4: タイムアウトフラグ
						; bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
						; bit2: 状態変化割り込み記憶フラグ
						; bit1: スリープ中状態フラグ
						; bit0: スリープ移行時間チェックフラグ
alm_flg						;アラーム音出力フラグ
						; bit7: アラーム音出力有効／無効フラグ
						; bit6: アラーム音出力済みフラグ
						; bit3: 時報正報音フラグ
						; bit2: 時報予報音フラグ
						; bit1: タイマー一致音フラグ
						; bit0: タイマー一致音継続中フラグ
bup_flg						;EEPROM バックアップ要求フラグ
hold_cnt					;スイッチ長押し時間監視カウンタ
bsc_cnt						;1 秒作成カウンタ
slp_cnt_h					;スリープ移行時間カウンタ high
slp_cnt_l					;スリープ移行時間カウンタ low
split_cnt					;スプリット番号カウンタ
split_cntx					;スプリット番号カウンタ退避用
laptim_cnt					;ラップタイム表示時間カウンタ
dsp_cnt						;タイマー用メモリの表示カウンタ
valid_cnt					;タイマー用メモリの有効数カウンタ
fmmwwwss					;タイマー制御バイト
del_fsr_h					;消去対象のタイマー用メモリのアドレス記憶
del_fsr_l					;

;chr_wk3					;ワーク: 変換後上位数字	;┐
chr_wk2						;ワーク: 		;│順序を変更しないこと!
chr_wk1						;ワーク: 変換後下位数字	;┘
lp_cnt1						;ワーク: ループカウンタ
lp_cnt2						;ワーク: ループカウンタ
work1						;ワーク
work2						;ワーク

const_high					;音階用分周定数 high の保存
const_low					;音階用分周定数 low の保存

wt1cnt						;ウェイト用ループカウンタ
wt2cnt						;ウェイト用ループカウンタ
wt3cnt						;ウェイト用ループカウンタ

; (I2C_S2_LCD.sub で使用)
addr_high					;読み出すデータの high アドレス
addr_low					;読み出すデータの low アドレス
lcdtmp						;LCD への出力データの一時保存
lcdtmp2						;
i2ctmp						;
bit_cnt						;ループカウンタ

; (I2C_RTC.sub で使用)
seconds						;00h: Seconds: 00-59
minutes						;01h: Minutes: 00-59
hours						;02h: Hours:   1-12 + AM/PM, 00-23
day						;03h: Day:     1-7
date						;04h: Date:    01-31
month						;05h: Month/Century: 01-12 + Century
year						;06h: Year:    00-99
alarm1s						;07h: Alarm 1 Seconds: 00-59
alarm1m						;08h: Alarm 1 Minutes: 00-59
alarm1h						;09h: Alarm 1 Hours:   1-12 + AM/PM, 00-23
alarm1dy					;0Ah: Alarm 1 Day:     1-7
alarm1d						;0Bh: Alarm 1 Date:    1-31
alarm2h						;0Ch: Alarm 2 Hours:   1-12 + AM/PM, 00-23
alarm2d						;0Dh: Alarm 2 Day:     1-7, Alarm 2 Date:    1-31
control						;0Eh: Control
cont_stat					;0Fh: Control/Status
aging						;10h: Aging Offset
temp_m						;11h: MSB of Temp
temp_l						;12h: LSB of Temp

rtc_lpcnt					;ループカウンタ
rtc_addr_high					;読み出すデータの high アドレス
rtc_addr_low					;読み出すデータの low アドレス
		endc

		cblock	h'80' - 11
bcd_yh						;年(上位2桁)_BCD カウンタ
bcd_yl						;年(下位2桁)_BCD カウンタ
;bcd_yy						;年_BCD カウンタ	;┐
bcd_nn						;月_BCD カウンタ	;│
bcd_dd						;日_BCD カウンタ	;│順序を変更しないこと!（現在時刻用）
bcd_hh						;時_BCD カウンタ	;│
bcd_mm						;分_BCD カウンタ	;│
bcd_ss						;秒_BCD カウンタ	;┘
bcd_ww						;曜日_BCD カウンタ

						;スリープ移行時間（分）カウンタ	
menu_1						;menu_1 分カウンタ	;┐
menu_4						;menu_4 分カウンタ	;│順序を変更しないこと!
menu_5						;menu_5 分カウンタ	;┘
		endc

;==========================================================================
;		マクロ命令定義
;==========================================================================

;		I2C LCD メッセージデータ表示マクロ

Disp_I2cLcd	macro	@com,@msg,@x
		movlw	@com
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
	#if 	@x == 0
	#else
		movlw	high @msg		;メッセージデータの先頭アドレスの high アドレス
		movwf	addr_high		;
		movlw	low @msg		;メッセージデータの先頭アドレスの low アドレス
		movwf	addr_low		;
	#endif
		call	I2cLcd_Disp		;メッセージデータ１行表示
		endm

;		I2C LCD メッセージデータ表示マクロ (ページ 1 用)

xDisp_I2cLcd	macro	@com,@msg,@x
		movlw	@com
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力
	#if 	@x == 0
	#else
		movlw	high @msg		;メッセージデータの先頭アドレスの high アドレス
		movwf	addr_high		;
		movlw	low @msg		;メッセージデータの先頭アドレスの low アドレス
		movwf	addr_low		;
	#endif
		call	xI2cLcd_Disp		;メッセージデータ１行表示
		endm

;		Sound_M マクロ（タイマー１割り込み使用）

Sound_M		macro	@scale,@time
		movlw	high @scale		;出力音階
		movwf	const_high
		movlw	low @scale
		movwf	const_low
		movlw	@time			;出力時間(ms)
		goto	buzzer_control		;ブザー音出力コントロール
		endm

;
;==========================================================================
;--------------------------------------------------------------------------
 		org	h'0000'			;(Page 0)
;--------------------------------------------------------------------------
;==========================================================================

;==========================================================================
;		プログラム開始
;==========================================================================

;		org	h'0000'			;リセットベクタ
		goto	initialize

;==========================================================================
;		割り込み処理
;==========================================================================

		org	h'0004'			;割り込みベクタ

interrupt
		movlp	high $			;ページ 0
		movlb	0			;バンク 0

		; 割り込み処理の振り分け

		btfsc	INTCON,INTF	;;	;INT 外部割り込みフラグ = 1 か？
		goto	int_int		;;	;Yes

		btfsc	INTCON,TMR0IF		;TMR0 オーバーフロー割り込みフラグ = 1 か？
		goto	int_tmr0		;Yes

		btfsc	PIR1,TMR1IF		;TMR1 オーバーフロー割り込みフラグ = 1 か？
		goto	int_tmr1		;Yes

		btfsc	INTCON,IOCIF		;状態変化割り込みフラグ = 1 か？
		goto	int_ioc			;Yes

		goto	int_end			;(Illegal interrupt)

;---------------- INT 外部割り込み処理 ------------------------------------

int_int		bcf	INTCON,INTF		;INT 外部割り込みフラグ = 0

		movlw	6		;;
		subwf	menu_no,W	;;
		btfsc	STATUS,Z	;;	;メニュー番号 = 6 か？
		goto	inti03		;;	;Yes
		movlw	7		;;
		subwf	menu_no,W	;;
		btfsc	STATUS,Z	;;	;メニュー番号 = 7 か？
		goto	inti03		;;	;Yes

		; 現在時刻の管理
		call	clock_rtc_read		;RTC DS3231 から年月日、時分秒を読み出し

		movlp	high time_alarm_control
		call	time_alarm_control	;時報音、タイマー一致音フラグコントロール
		movlp	high $

		; スリープ移行時間カウンタの更新
		btfsc	stat2_flg,1		;スリープ中状態フラグ = 1 か？
		goto	inti01			;Yes

		decf	slp_cnt_l,F		;slp_cnt_l - 1
		incf	slp_cnt_l,W		;
		btfsc	STATUS,Z		;slp_cnt_l - 1 < 0 か？
		decf	slp_cnt_h,F		;Yes. slp_cnt_h - 1
		bsf	stat2_flg,0		;スリープ移行時間チェックフラグ = 1

inti01		movlw	4			;4:「ストップウオッチ(長時間)」
		subwf	menu_no,W		;
		btfss	STATUS,Z		;メニュー番号 = 4 か？
		goto	inti03			;No

		; 経過時間（スプリットタイム）の管理
		btfsc	stat_flg,3		;ストップウオッチ動作終了フラグ = 1 か？
		goto	inti02			;Yes

		btfss	stat_flg,2		;ストップウオッチ動作中フラグ = 1 か？
		goto	inti03			;No

		movlp	high ssmmhh_inc
		call	ssmmhh_inc		;秒、分、時_BCD カウンタのインクリメント
		movlp	high $
		bsf	stat_flg,1		;経過時間更新フラグ = 1

		; ラップタイム表示時間の監視（5 秒間）
inti02		btfsc	stat_flg,4		;ラップタイム表示指示フラグ = 1 か？
		decfsz	laptim_cnt,F		;Yes. ラップタイム表示時間カウンタ - 1 = 0 か？
		goto	inti03			;No

		bcf	stat_flg,4		;ラップタイム表示指示フラグ = 0

inti03		goto	int_end

;---------------- TMR0 オーバーフロー割り込み処理 -------------------------

int_tmr0	bcf	INTCON,TMR0IF		;TMR0 オーバーフロー割り込みフラグ = 0
		movlw	256 - 250		;(4 / 4MHz) * 250 * 256(Prescaler) = 64000μS = 64 mS
		movwf	TMR0

		incf	hold_cnt,F		;長押し監視カウンタ + 1
		movlw	47 + 1			;64ms x 47 = 3,008 mS = 3 秒間の監視
		subwf	hold_cnt,W
		btfsc	STATUS,C		;長押し監視カウンタ >= 47 + 1 か？
		bcf	INTCON,TMR0IE		;Yes. TMR0 オーバーフロー割り込み許可 = 0
		goto	int_end

;---------------- TMR1 オーバーフロー割り込み処理 -------------------------

int_tmr1	bcf	PIR1,TMR1IF		;TMR1 オーバーフロー割り込みフラグ = 0

		btfsc	alm_flg,7		;アラーム音出力フラグ = 1 か？
		goto	int1t02			;Yes

		; 「ストップウオッチ(詳細)」／「インターバル（間隔）タイマー」のとき
		movlw	high basic_const	;(4 / 4MHz) * 10000 = 0.01 S = 10 mS
		movwf	TMR1H			;TMR1H に設定
		movlw	low basic_const		;
		movwf	TMR1L			;TMR1L に設定

		movlw	2
		subwf	menu_no,W
		btfss	STATUS,Z		;メニュー番号 = 2:「ストップウオッチ(詳細)」か？
		goto	int1t01			;No

		; メニュー番号 = 2:「ストップウオッチ(詳細)」のとき
		bsf	stat2_flg,3		;1/100 秒更新フラグ = 1
		call	xxssmmhh_inc		;Yes. 1/100秒、秒、分、時_BCD カウンタのインクリメント

#ifdef xx_debug				;(1/6)
		movlw	h'10'
		subwf	bcd_mm_w,W
		btfsc	STATUS,Z		;10 分経過 か？
		goto	int1t0x			;Yes
#endif

		goto	int1t03

		; メニュー番号 = 3:「インターバル（間隔）タイマー」のとき
int1t01		decfsz	bsc_cnt,F		;1 秒作成カウンタ bsc_cnt - 1 = 0 か？
		goto	int1t03			;No

		movlw	100
		movwf	bsc_cnt			;10 mS * 100 = 1000 mS = 1 Sec

		bsf	stat2_flg,3		;1 秒更新フラグ = 1 （1/100 秒と兼用）
		call	ssmmhh_dec		;秒、分、時_BCD カウンタのデクリメント
		movf	bcd_ss_w,W
		iorwf	bcd_mm_w,W
		iorwf	bcd_hh_w,W
		btfss	STATUS,Z		;３つすべての BCD カウンタ = h'00' か？
		goto	int1t03			;No

int1t0x		movlb	1			;バンク 1
		bcf	PIE1,TMR1IE		;TMR1 オーバーフロー割り込み許可 = 0
		movlb	0			;バンク 0
		bsf	stat2_flg,4		;タイムアウトフラグ = 1
		goto	int1t03

		; ビープ音出力のとき
int1t02		movf	const_high,W		;音階用分周定数 high を
		movwf	TMR1H			;TMR1H に設定
		movf	const_low,W		;音階用分周定数 low を
		movwf	TMR1L			;TMR1L に設定

		movlw	1 << _BZ		;ブザー音出力, 対象ビットをセット
		xorwf	PORTA,F			;出力をビット反転

int1t03		goto	int_end

;---------------- 状態変化割り込み処理 ------------------------------------

int_ioc		movlb	7			;バンク 7
		clrf	IOCBF			;状態変化割り込みフラグをクリアすると
						;INTCON レジスタの IOCIF ビットもクリアされる
		movlb	0			;バンク 0
		bcf	INTCON,IOCIE		;状態変化割り込み許可 = 0

		bsf	stat2_flg,2		;状態変化割り込み記憶フラグ = 1
;		goto	int_end

		; 割り込み処理の終了

int_end		retfie				;割り込みからの復帰	

;--------------------------------------------------------------------------
;		1/100秒、秒、分、時_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

;	00:00:00.00 → .......... → 99:59:59.99 → 00:00:00.00 → 

		;	dsp_point = 0: "HH"
		;		    1: "HL"
		;		    2: "MH"
		;		    3: "ML"
		;		    4: "SH"
		;		    5: "SL"
		;		    6: "XH"
		;		    7: "XL"

xxssmmhh_inc
		movlw	high bcd_xx_w		;1/100秒_BCD カウンタのアドレス（ワーク用）
		movwf	FSR0H			;
		movlw	low bcd_xx_w		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	7			;表示位置ポインタの初期設定
		movwf	dsp_point		;表示位置ポインタ = 7 = "XL"
		call	inc_bcd			;1/100秒_BCD カウンタ bcd_xx_w を BCD インクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 6 = "XH"
		movlw	h'a0'
		subwf	INDF0,W
		btfss	STATUS,C		;1/100秒_BCD カウンタ bcd_xx_w >= h'a0' か？
		return				;No

		clrf	INDF0			;1/100秒_BCD カウンタ bcd_xx_w = h'00'
		addfsr	FSR0,-1			;間接アドレス FSR0H:FSR0L - 1

		decf	dsp_point,F		;表示位置ポインタ = 5 = "SL"
		call	inc_bcd			;秒_BCD カウンタ bcd_ss_w を BCD インクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 4 = "SH"
		movlw	h'60'
		subwf	INDF0,W
		btfss	STATUS,C		;秒_BCD カウンタ bcd_ss_w >= h'60' か？
		return				;No

		clrf	INDF0			;秒_BCD カウンタ bcd_ss_w = h'00'
		addfsr	FSR0,-1			;間接アドレス FSR0H:FSR0L - 1

		decf	dsp_point,F		;表示位置ポインタ = 3 = "ML"
		call	inc_bcd			;分_BCD カウンタ bcd_mm_w を BCD インクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 2 = "MH"
		movlw	h'60'
		subwf	INDF0,W
		btfss	STATUS,C		;分_BCD カウンタ bcd_mm_w >= h'60' か？
		return				;No

		clrf	INDF0			;分_BCD カウンタ bcd_mm_w = h'00'
		addfsr	FSR0,-1			;間接アドレス FSR0H:FSR0L - 1

		decf	dsp_point,F		;表示位置ポインタ = 1 = "HL"
		call	inc_bcd			;時_BCD カウンタ bcd_hh_w を BCD インクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 0 = "HH"
		movlw	h'a0'
		subwf	INDF0,W
		btfss	STATUS,C		;時_BCD カウンタ bcd_hh_w >= h'a0' か？
		return				;No

		clrf	INDF0			;時_BCD カウンタ bcd_hh_w = h'00'
		return

;--------------------------------------------------------------------------
;		秒、分、時_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

		;	dsp_point = 0: "HH"
		;		    1: "HL"
		;		    2: "MH"
		;		    3: "ML"
		;		    4: "SH"
		;		    5: "SL"

ssmmhh_dec
		movlw	high bcd_ss_w		;秒_BCD カウンタのアドレス（ワーク用）
		movwf	FSR0H			;
		movlw	low bcd_ss_w		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	5			;表示位置ポインタの初期設定
		movwf	dsp_point		;表示位置ポインタ = 5 = "SL"
		call	dec_bcd			;秒_BCD カウンタ bcd_ss_w を BCD デクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 4 = "SH"
		movf	INDF0,W
		andlw	h'f0'			;上位4ビット
		sublw	h'f0'
		btfss	STATUS,Z		;上位4ビット = h'f0' か？
		return				;No

		movlw	h'59'
		movwf	INDF0			;秒_BCD カウンタ bcd_ss_w = h'59'
		addfsr	FSR0,-1			;間接アドレス FSR0H:FSR0L - 1

		decf	dsp_point,F		;表示位置ポインタ = 3 = "ML"
		call	dec_bcd			;分_BCD カウンタ bcd_mm_w を BCD デクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 2 = "MH"
		movf	INDF0,W
		andlw	h'f0'			;上位4ビット
		sublw	h'f0'
		btfss	STATUS,Z		;上位4ビット = h'f0' か？
		return				;No

		movlw	h'59'
		movwf	INDF0			;分_BCD カウンタ bcd_mm_w = h'59'
		addfsr	FSR0,-1			;間接アドレス FSR0H:FSR0L - 1

		decf	dsp_point,F		;表示位置ポインタ = 1 = "HL"
		call	dec_bcd			;時_BCD カウンタ bcd_hh_w を BCD デクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		decf	dsp_point,F		;表示位置ポインタ = 0 = "HH"
	;	movf	INDF0,W
	;	andlw	h'f0'			;上位4ビット
	;	sublw	h'f0'
	;	btfss	STATUS,Z		;上位4ビット = h'f0' か？
		return				;No

	;	最上位桁 "HH" が桁上がりをする前に、
	;	bcd_xx_w = bcd_ss_w = bcd_mm_w = bcd_hh_w = h'00' 
	;	となった時点で、TMR1 オーバーフロー割り込み処理内で、
	;	割り込みの禁止と、タイムアウトフラグ = 1 としている

;==========================================================================
;		サブルーチンファイルのインクルード
;==========================================================================

#define 	TRISX	TRISB			;PORTB で I2C を行う場合
#define 	PORTX	PORTB			;
#define 	_PIC16F1			;PIC16F1ファミリで使用
#define 	_4MHz				;4 MHz クロックで使用

#define 	i2c_byte_send	byte_send	;I2C_RTCII.sub を使用する場合
#define 	i2c_byte_reciv	byte_reciv	;
#define 	i2c_ack		ack		;
#define 	i2c_nack	nack		;

;				ドライブ、パス名は、各自の開発環境に合わせるように !!

		include		C:\Data\Project\PIC\_sub\I2C_S2_LCD.sub	;Ver.1.06 以上が必要
		include		C:\Data\Project\PIC\_sub\I2C_RTCII.sub	;Ver.1.02 以上が必要

;==========================================================================
;		I2C LCD（ AQM0802A の場合 ）表示用 メッセージ等
;==========================================================================

		; スタートメッセージ

start_msg	dt	"Multifun",0
		dt	"DigClock",0
;			 01234567

		dt	"Ver ",ver_no,0
		dt	" by M.Y ",0
;			 01234567

		; RTC エラーメッセージ

rtc_err_msg	dt	"RTC Err!",0
		dt	" Init?_ ",0
;			 01234567

		; 年月日設定メッセージ

date_set_msg	dt	"Date Set",0
;			 01234567

		; 時分秒設定メッセージ

time_set_msg	dt	"Time Set",0
;			 01234567

		; ストップウオッチ(詳細)メッセージ

;			"xx:xx:xx"
detail_stw_msg	dt	"(StW) 00",0
;			 01234567

		; ストップウオッチ(長時間)終了メッセージ

long_end_msg	dt	"StpW End",0
;			"xx:xx:xx"
;			 01234567

		; メモリ満タンメッセージ

mem_full_msg	dt	"Mem Full",0
;			"xx:xx:xx"
;			 01234567

		; 番号テンプレート出力

number_msg	dt	"**    **",0
;			 01234567

		; スリープ移行時間メッセージ

sleep_time_msg	dt	"M1,M4,M5",0
;			"xx xx xx"
;			 01234567

;==========================================================================
;		初期化処理
;==========================================================================

initialize

		clrf	STATUS			;STATUS クリア
	 	clrf	INTCON			;INTCON クリア

		movlb	1			;バンク 1
		clrf	OSCCON			;OSCCON クリア

		; PORTA, PORTB ポートの各機能設定

		movlb	0			;バンク 0
		clrf	PORTA			;
		clrf	PORTB			;

		movlb	2			;バンク 2
		clrf	LATA			;
		clrf	LATB			;

		movlb	3			;バンク 3
		clrf	ANSELA			;すべて デジタル I/O ポート
		clrf	ANSELB			;

		movlb	1			;バンク 1
		movlw	b'00110000'		;RA5-RA4:入力
		movwf	TRISA			;ポートA の I/O 設定
		movlw	b'11101101'		;RB7-RB5,RB3-RB2,RB0:入力, RB4,RB1:出力
		movwf	TRISB			;ポートB の I/O 設定

		movlb	4			;バンク 4
		movlw	b'00100000'		;RA5
		movwf	WPUA			;プルアップ有効
		movlw	b'11101100'		;RB7-RB5,RB3-RB2
		movwf	WPUB			;プルアップ有効

		movlb	7			;バンク 7
		movlw	b'11000000'		;RB7-RB6
		movwf	IOCBN			;ポートB の立ち下がりエッジ状態変化割り込み

		; OPTION レジスタ の設定

		movlb	1			;バンク 1
		movlw	b'00000111'		;WPUEN:   bit7=0: プルアップ有効
						;PSA:     bit3=0: Timer0 でプリスケーラ使用
						;PS<2:0>: bit2-0=111: プリスケーラ値を1:256
		movwf	OPTION_REG

		; 割り込みの設定

		bcf	PIE1,TMR1IE		;TMR1 オーバーフロー割り込み許可 = 0
		bcf	PIE2,EEIE		;EEPROM 書き込み完了割り込み許可 = 0

		movlb	0			;バンク 0
		movlw	b'00000001'		;TMR1CS<1:0>: bit7-6=00: Timer1クロック源=命令クロック(FOSC/4)を選択
						;T1CKPS<1:0>: bit5-4=00: プリスケーラ値を1:1
						;TMR1ON:      bit0=1:    Timer1を有効
		movwf	T1CON			;Timer1制御レジスタ
	;	clrf	T1GCON			;Timer1ゲート制御レジスタ

		movlw	b'11000000'		;GIE:    bit7=1: グローバル割り込みを許可 = 1
						;PEIE:   bit6=1: ペリフェラル割り込みを許可 = 1
						;TMR0IE: bit5=0: TMR0 オーバーフロー割り込み許可 = 0
						;INTE:   bit4=0: INT 外部割り込み許可 = 0
						;IOCIE:  bit3=0: 状態変化割り込み許可 = 0
		movwf	INTCON			;各割り込み要因の設定

;--------------------------------------------------------------------------

		; スタートメッセージの表示

		bcf	PORTA,_ledG		;LED(緑) 消灯
		bcf	PORTA,_ledR		;LED(赤) 消灯
		bcf	PORTA,_PWcntl		;LCD 電源 ON
		bsf	PORTB,SDA		;SDA="H"
		bsf	PORTB,SCL		;SCL="H"

		movlw	h'80'
		movwf	alm_flg			;アラーム音出力フラグ = 1
		call	buzzer_pipo		;"ピポッ" アラーム音出力と LED(緑)点滅 (Total 260 mS)
		call	I2cLcd_Init		;I2C LCD (AQM0802A) の初期設定

		movlw	2
		movwf	lp_cnt1			;メッセージの表示回数
init01
		;	[ Multifun ]		;プログラム略名
		;	[ DigClock ]
		;	  01234567

		Disp_I2cLcd	h'80',start_msg,1	;表示位置指定 (１行目先頭)
		Disp_I2cLcd	h'c0',         ,0	;表示位置指定 (２行目先頭)
		call	wait_1sec
		call	wait_1sec

		;	[ Ver x.xx ]		;バージョン番号
		;	[  by M.Y  ]
		;	  01234567

		Disp_I2cLcd	h'80',         ,0	;表示位置指定 (１行目先頭)
		Disp_I2cLcd	h'c0',         ,0	;表示位置指定 (２行目先頭)
		call	wait_1sec
		call	wait_1sec

		decfsz	lp_cnt1,F		;メッセージの表示回数 = 終了 か？
		goto	init01			;No

		movlw	h'01'			;表示クリア
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
		call	wait_1sec
	;	call	wait_1sec

;--------------------------------------------------------------------------

		; I2C RTC（DS3231）モジュールのチェック

rtcinit01
		Rtc_Read_M	cont_stat,1	;0Fh: Control/Status 読み出し

		btfss	cont_stat,7		;OSF = 1 か？
		goto	rtcinit03		;No

		;	[ RTC Err! ]		;DS3231 RTC エラーメッセージ
		;	[  Init?_  ]		;DS3231 初期化メッセージ
		;	  01234567

		Disp_I2cLcd	h'80',rtc_err_msg,1	;表示位置指定 (１行目先頭)
		Disp_I2cLcd	h'c0',           ,0	;表示位置指定 (２行目先頭)

		movlw	h'0d'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=1: ブリンク
		movlw	h'c7'			;
		call	I2cLcd_Cmd		;表示位置指定 
		call	buzzer_bubuu		;"ブッブー" アラーム音出力
		bsf	PORTA,_ledR		;LED(赤) 点灯

rtcinit02	comf	PORTB,W			;全ビットを反転
		andlw	h'ec'
		btfsc	STATUS,Z		;どれかのスイッチ = ON か？
		goto	rtcinit02		;No

		movlw	h'0c'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク

		; I2C RTC（DS3231）モジュールの初期設定

		call	I2cRtc_Init		;I2C RTC（DS3231）モジュールの初期設定
		bcf	PORTA,_ledR		;LED(赤) 消灯
		goto	rtcinit01

;--------------------------------------------------------------------------

		; 各変数の初期設定

#define 	bcd_yy	bcd_yl			;年(下位2桁) BCD カウンタ ***

rtcinit03	movlw	h'20'
		movwf	bcd_yh			;年(上位2桁) BCD カウンタ ***

		clrf	time_flg		;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		clrf	stat_flg		;進行状態フラグの初期設定
		clrf	stat2_flg		;進行状態-2フラグの初期設定
		clrf	split_cnt		;スプリット番号カウンタの初期設定

		movlp	high read_eeprom_memory
		call	read_eeprom_memory	;タイマー用メモリをバックアップ EEPROM から読み出し
		movlp	high $

		movlp	high read_sleep_time
		call	read_sleep_time		;スリープ移行時間（分）をバックアップ EEPROM から読み出し
		movlp	high $

	;;	goto	main			;「メニューの選択」

		movlw	1
		movwf	menu_no			;メニュー番号の初期設定
		goto	clock_display		;「現在時刻の表示」に移行

;--------------------------------------------------------------------------
;		RTC DS3231 から年月日、時分秒を読み出し
;--------------------------------------------------------------------------

clock_rtc_read
		Rtc_Read_M	seconds,7	;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter
		bsf	stat_flg,0		;現在時刻更新フラグ = 1
		return

;--------------------------------------------------------------------------
;		バッファと_BCD カウンタ間のデータ移動
;--------------------------------------------------------------------------

		; バッファからカウンタへコピー

buffer_to_counter

		movlw	high seconds		;RTC バッファの先頭アドレス
		movwf	FSR1H			;
		movlw	low seconds		;
		movwf	FSR1L			;

		moviw	FSR1++			;Seconds
		movwf	bcd_ss			;秒_BCD カウンタ

		moviw	FSR1++			;Minutes
		movwf	bcd_mm			;分_BCD カウンタ

		moviw	FSR1++			;Hours
		movwf	bcd_hh			;時_BCD カウンタ

		moviw	FSR1++			;Day
		movwf	bcd_ww			;曜日_BCD カウンタ

		moviw	FSR1++			;Date
		movwf	bcd_dd			;日_BCD カウンタ

		moviw	FSR1++			;Month
		andlw	h'1f'			;
		movwf	bcd_nn			;月_BCD カウンタ

		moviw	FSR1++			;Year
		movwf	bcd_yy			;年_BCD カウンタ
		return

;--------------------------------------------------------------------------

		; カウンタからバッファへコピー

counter_to_buffer

		movlw	high seconds		;RTC バッファの先頭アドレス
		movwf	FSR1H			;
		movlw	low seconds		;
		movwf	FSR1L			;

		movf	bcd_ss,W		;秒_BCD カウンタ
		movwi	FSR1++			;Seconds

		movf	bcd_mm,W		;分_BCD カウンタ
		movwi	FSR1++			;Minutes

		movf	bcd_hh,W		;時_BCD カウンタ
		movwi	FSR1++			;Hours

		movf	bcd_ww,W		;曜日_BCD カウンタ
		movwi	FSR1++			;Day

		movf	bcd_dd,W		;日_BCD カウンタ
		movwi	FSR1++			;Date

		movf	bcd_nn,W		;月_BCD カウンタ
		movwi	FSR1++			;Month

		movf	bcd_yy,W		;年_BCD カウンタ
		movwi	FSR1++			;Year
		return

;
;==========================================================================
;	   メイン・ルーチン（メニューの表示と選択項目へ振り分け）
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │●│   │●│   │●│   │○│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		  DOWN スイッチ ..... 前のメニュー項目を表示
;		    UP スイッチ ..... 次のメニュー項目を表示

;		 ALARM スイッチ ..... アラーム音出力の有効／無効

;		  EXIT スイッチ ..... 選択したメニュー項目処理に移行

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

;--------------------------------------------------------------------------

main
		clrf	stat_flg		;進行状態フラグの初期設定
		clrf	stat2_flg		;進行状態-2フラグの初期設定

		movlw	h'0c'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク
		movlw	h'01'			;表示クリア（要 1.08 mS 以上のウエイト）
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
		call	buzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		movf	menu_no,W		;メニュー番号
		movwf	work1			;退避
		clrf	menu_no

		;	[ Select_  ]		;１行目 ... Select_ の表示
		;     ( [ ClockDsp ] )		;２行目 ... メニュー項目の表示
		;	  01234567

		movlw	h'80'			;表示位置指定 (１行目先頭)
		call	menu_display		;メニュー選択の表示(１行目)

		movf	work1,W			;復帰
		movwf	menu_no			;メニュー番号

main01		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		movlw	h'0c'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク

		;     ( [ Select_  ] )		;１行目 ... Select_ の表示
		;	[ ClockDsp ]		;２行目 ... メニュー項目の表示
		;	  01234567

		movlw	h'c0'			;表示位置指定 (２行目先頭)
		call	menu_display		;メニュー項目の表示(２行目)

		movlw	h'87'			;
		call	I2cLcd_Cmd		;表示位置指定 
		movf	menu_no,W		;メニュー番号
		iorlw	h'30'			;数字に変換
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movlw	h'87'			;
		call	I2cLcd_Cmd		;表示位置指定 
		movlw	h'0d'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=1: ブリンク

		; 各スイッチの入力チェック

main02		btfss	PORTB,_swUP		;UP スイッチ = ON か？
		call	menu_up_switch		;Yes

		btfss	PORTB,_swDWN		;DOWN スイッチ = ON か？
		call	menu_down_switch	;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	main01			;Yes

		btfss	PORTB,_swALM		;ALARM スイッチ = ON か？
		call	menu_alm_switch		;Yes

		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	main02			;No

		; メニュー番号別処理への振り分け

main03		movlw	h'0c'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク
		movlw	h'01'			;表示クリア（要 1.08 mS 以上のウエイト）
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
		call	wait_15ms		;チャッタリング吸収

		decf	menu_no,W		;0 始まりにする
		movwf	FSR1L
		lslf	FSR1L,F			;2 倍する
		movlw	low jump_addr_tbl
		addwf	FSR1L,F			;ジャンプアドレステーブルの先頭 low アドレスを足す
		clrf	FSR1H
		movlw	high jump_addr_tbl
		addwfc	FSR1H,F			;ジャンプアドレステーブルの先頭 high アドレスを足す

		moviw	0[FSR1]			;
		movwf	PCLATH			;
		moviw	1[FSR1]			;
		movwf	PCL			;選択したメニュー項目処理にジャンプ

;--------------------------------------------------------------------------

		; メニュー番号別ジャンプアドレステーブル

jump_addr_tbl
		dt	high clock_display	;menu_no = 1	;(ページ 0)
		dt	low  clock_display
		dt	high detail_stopwatch	;menu_no = 2	;(ページ 1)
		dt	low  detail_stopwatch
		dt	high interval_timer	;menu_no = 3	;(ページ 1)
		dt	low  interval_timer
		dt	high long_stopwatch	;menu_no = 4	;(ページ 1)
		dt	low  long_stopwatch
		dt	high memory_display	;menu_no = 5	;(ページ 1)
		dt	low  memory_display
		dt	high wk_timer_setting	;menu_no = 6	;(ページ 1)
		dt	low  wk_timer_setting
		dt	high wk_timer_display	;menu_no = 7	;(ページ 1)
		dt	low  wk_timer_display
		dt	high clock_adjust	;menu_no = 8	;(ページ 0)
		dt	low  clock_adjust
		dt	high sleep_time_set	;menu_no = 9	;(ページ 1)
		dt	low  sleep_time_set
jump_addr_tbl_end

;--------------------------------------------------------------------------
;		メイン・メニューの表示
;--------------------------------------------------------------------------

menu_display
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力（表示位置を指定）

		movf	menu_no,W		;メニュー番号
		movwf	addr_low
		lslf	addr_low,F		;x 2 倍
		lslf	addr_low,F		;x 4 倍
		lslf	addr_low,F		;x 8 倍
		addwf	addr_low,F		;x 9 倍

		movlw	high menu_table		;テーブルデータの先頭 high アドレス
		movwf	addr_high		;
		movlw	low menu_table		;テーブルデータの先頭 low アドレス
		addwf	addr_low,F		;
		btfsc	STATUS,C		;オーバーフローした場合は
		incf	addr_high,F		;high アドレスの更新

		call	I2cLcd_Disp		;I2C LCD へ文字列データを出力
		return

		; メニュー データテーブル
menu_table
		dt	"Select_ ",0		; (例外)   0	「メニューの選択」

		dt	"ClockDsp",0		;menu_no = 1	「現在時刻の表示」
		dt	"DtlStopW",0		;          2	「ストップウオッチ(詳細)」
		dt	"ItvTimer",0		;          3	「インターバル（間隔）タイマー」
		dt	"LngStopW",0		;          4	「ストップウオッチ(長時間)」
		dt	"MemoDisp",0		;          5	「記録内容の表示」
		dt	"WkTimSet",0		;          6	「週間タイマーの時刻設定」
		dt	"WkTimDsp",0		;          7	「週間タイマーの設定表示と消去」
		dt	"ClockAdj",0		;          8	「現在時刻の設定」
		dt	"SleepTim",0		;          9	「スリープ移行時間の変更」
;			 01234567

;--------------------------------------------------------------------------
;	    UP スイッチの処理 ...「メニューの選択」から CALL
;--------------------------------------------------------------------------

menu_up_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swUP		;再度 UP スイッチ = ON か？
		goto	menup02			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		incf	menu_no,F		;メニュー番号 + 1 更新

		movlw	(jump_addr_tbl_end - jump_addr_tbl) / 2 + 1
		subwf	menu_no,W
		btfss	STATUS,Z		;メニュー番号 = max + 1 か？
		goto	menup01			;No

		movlw	1			;メニュー番号 = 1 設定
		movwf	menu_no

menup01		btfss	PORTB,_swUP		;UP スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

menup02		return

;--------------------------------------------------------------------------
;	    DOWN スイッチの処理 ...「メニューの選択」から CALL
;--------------------------------------------------------------------------

menu_down_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	mendw02			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		decf	menu_no,F		;メニュー番号 - 1 更新

		btfss	STATUS,Z		;メニュー番号 - 1 = 0 か？
		goto	mendw01			;No

		movlw	(jump_addr_tbl_end - jump_addr_tbl) / 2
		movwf	menu_no			;メニュー番号 = max 設定

mendw01		btfss	PORTB,_swDWN		;DOWN スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

mendw02		return

;--------------------------------------------------------------------------
;	    ALARM スイッチの処理 ...「メニューの選択」から CALL
;--------------------------------------------------------------------------

menu_alm_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swALM		;再度 ALARM スイッチ = ON か？
		goto	menal01			;No

		movlw	h'80'
		xorwf	alm_flg,W		;アラーム音出力フラグの更新
		movwf	work1			;退避

		bsf	alm_flg,7		;
		btfsc	work1,7			;アラーム音出力フラグ = 1 か？
		call	buzzer_pipi		;Yes. 有効  "ピピッ" アラーム音出力
		btfss	work1,7			;アラーム音出力フラグ = 0 か？
		call	buzzer_buu		;Yes. 無効  "ブー" アラーム音出力

		movf	work1,W
		movwf	alm_flg			;復帰

		btfss	PORTB,_swALM		;ALARM スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

menal01		return

;
;==========================================================================
; menu_no = 1	    現在時刻（年月日、(曜日) AM/PM、時分秒）の表示
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │●│   │●│   │●│   │○│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		 TMODE スイッチ ..... 12時間表示／24時間表示の切り替え

;		  ZERO スイッチ ..... 毎正時 00 分 00 秒に設定

;		ENABLE スイッチ + 
;		  EXIT スイッチ ..... 「現在時刻の設定」に移行

;		  EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				> bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				> bit7: 処理終了（エグジット）フラグ
;				> bit6: 例外終了（次処理に移行）フラグ
;				  bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				  bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				> bit2: 状態変化割り込み記憶フラグ
;				> bit1: スリープ中状態フラグ
;				> bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

clock_display

		call	clock_rtc_read		;RTC DS3231 から年月日、時分秒を読み出し
		bsf	INTCON,INTE		;INT 外部割り込み許可 = 1

		call	buzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)
		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1（スリープ移行時間カウンタの初期設定のため）

cldsp01		btfss	stat_flg,0		;現在時刻更新フラグ = 1 か？
		goto	cldsp04			;No

		bcf	stat_flg,0		;現在時刻更新フラグ = 0

		movlw	h'80'			;表示位置指定 (１行目先頭)
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力

		btfsc	bcd_ss,0		;偶数秒 か？
		goto	cldsp02			;No

		;	[ xx/xx/xx ]		;１行目 ... 年月日の表示
		;	  01234567

		call	yy_disp			;年の表示
		movlw	'/'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	nn_disp			;月の表示
		movlw	'/'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	dd_disp			;日の表示
		goto	cldsp03

		;	[ (SUN) AM ]		;１行目 ... 曜日 AM/PM の表示
		;	  01234567

cldsp02		movlw	'('
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	ww_disp			;曜日の表示
		movlw	')'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		movlw	' '
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	ampm_disp		;AM/PM の表示

		;	[ xx:xx:xx ]		;２行目 ... 時分秒の表示
		;	  01234567

cldsp03		movlw	h'c0'			;表示位置指定 (２行目先頭)
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力

		call	hh_disp			;時の表示
		movlw	':'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	mm_disp			;分の表示
		movlw	':'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	ss_disp			;秒の表示

		movlp	high alarm_sound
		call	alarm_sound		;時報音、タイマー一致音のアラーム出力
		movlp	high $

		; 各スイッチの入力チェック

cldsp04		btfss	PORTB,_swMOD		;TMODE スイッチ = ON か？
		call	clk_mode_switch		;Yes

		btfss	PORTB,_swZER		;ZERO スイッチ = ON か？
		call	clk_zero_switch		;Yes

		btfss	PORTB,_swEN		;ENABLE スイッチ = ON か？
		bsf	stat_flg,6		;Yes. スイッチ入力有りフラグ = 1

		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		call	clk_exit_switch		;Yes

		movlw	h'c0'
		andwf	stat2_flg,W
		btfss	STATUS,Z		;処理終了フラグ or 例外終了フラグ = 1 か？
		goto	cldsp06			;Yes

		btfss	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	cldsp05			;No

		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
						;スリープ移行時間カウンタの初期設定
		movf	menu_1,W		;menu_1 分カウンタ
		movlp	high mul8x8_16
		call	mul8x8_16		;8 x 8 ビット = 16 ビットの乗算
		movlp	high $
 		bsf	stat_flg,0		;現在時刻更新フラグ = 1
		goto	cldsp01

		; スリープ移行時間の監視（60 x 3 秒）

cldsp05		movlp	high sleep_mode
		call	sleep_mode		;時間の監視とスリープモードに移行
		movlp	high $
		btfss	stat2_flg,1		;スリープ中状態フラグ = 1 か？
		goto	cldsp01			;No

		bcf	stat2_flg,1		;スリープ中状態フラグ = 0
		bsf	stat_flg,0		;現在時刻更新フラグ = 1
		goto	cldsp01

		; 「現在時刻（年月日、時分秒）の表示」の終了

cldsp06		bcf	INTCON,INTE		;INT 外部割り込み許可 = 0
		bcf	stat_flg,0		;現在時刻更新フラグ = 0

		btfss	stat2_flg,6		;例外終了フラグ = 1 か？
		goto	main			;No. 「メニューの選択」に戻る

		movlw	8
		movwf	menu_no			;メニュー番号 = 8 設定
		goto	clock_adjust		;「現在時刻の設定」に移行

;--------------------------------------------------------------------------
;	  TIME MODE スイッチの処理 ...「現在時刻の表示」から CALL
;--------------------------------------------------------------------------

clk_mode_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swMOD		;再度 TMODE スイッチ = ON か？
		goto	clmod01			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movlw	b'00000010'
		xorwf	time_flg,F		;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		bsf	stat_flg,0		;現在時刻更新フラグ = 1

		btfss	PORTB,_swMOD		;TMODE スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

clmod01		return

;--------------------------------------------------------------------------
;	    ZERO スイッチの処理 ...「現在時刻の表示」から CALL
;--------------------------------------------------------------------------

clk_zero_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swZER		;再度 ZERO スイッチ = ON か？
		goto	clzer05			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movlw	h'06'
		subwf	bcd_mm,W
		btfsc	STATUS,C		;分_BCD カウンタ < h'06' か？
		goto	clzer01			;No

		bcf	INTCON,INTE		;INT 外部割り込み許可 = 0
		goto	clzer03

clzer01		movlw	h'55'
		subwf	bcd_mm,W
		btfss	STATUS,C		;分_BCD カウンタ >= h'55' か？
		goto	clzer04			;No. 無視

		bcf	INTCON,INTE		;INT 外部割り込み許可 = 0
		call	bcd_hh_inc		;時_BCD カウンタのインクリメント
		movf	bcd_hh,W
		btfss	STATUS,Z		;時_BCD カウンタ = h'00' か？
		goto	clzer03			;No

		call	bcd_dd_inc		;日_BCD カウンタのインクリメント
		movlw	h'01'
		subwf	bcd_dd,W
		btfss	STATUS,Z		;日_BCD カウンタ = h'01' か？
		goto	clzer02			;No

		call	bcd_nn_inc		;月_BCD カウンタのインクリメント
		movlw	h'01'
		subwf	bcd_nn,W
		btfss	STATUS,Z		;月_BCD カウンタ = h'01' か？
		goto	clzer02			;No

		call	bcd_yl_inc		;年(下位2桁)_BCD カウンタのインクリメント

clzer02		call	day_week		;該当日の曜日を取得
		movwf	bcd_ww			;曜日_BCD カウンタ

clzer03		btfss	PORTB,_swZER		;ZERO スイッチ = OFF か？
		goto	$ - 1			;No

		clrf	bcd_mm			;分_BCD カウンタのクリア
		clrf	bcd_ss			;秒_BCD カウンタのクリア
		call	counter_to_buffer
		Rtc_Write_M  seconds,7		;RTC DS3231 へ年月日、時分秒を書き込み

		bsf	INTCON,INTE		;INT 外部割り込み許可 = 1

clzer04		call	wait_15ms		;チャッタリング吸収

clzer05		return

;--------------------------------------------------------------------------
;       EXIT スイッチの処理 ...「現在時刻の表示」から CALL
;			       「ストップウオッチ（長時間）」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		ENABLE スイッチ + 
;		  EXIT スイッチ ..... （例外終了フラグ = 1 にする）
;				      「現在時刻の設定」に移行 ... 「現在時刻の表示」のとき
;				      「記録内容の表示」に移行 ... 「ストップウオッチ（長時間）」のとき

;		  EXIT スイッチ ..... （処理終了フラグ = 1 にする）
;				      「メニューの選択」に戻る

clk_exit_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	clext02			;No

		btfss	PORTB,_swEN		;ENABLE スイッチ = ON か？
		bsf	stat2_flg,6		;Yes. 例外終了フラグ = 1
		btfsc	PORTB,_swEN		;ENABLE スイッチ = ON か？
		bsf	stat2_flg,7		;No.  処理終了フラグ = 1

clext01		comf	PORTB,W			;全ビットを反転
		andlw	h'60'
		btfss	STATUS,Z		;EXIT スイッチ and ENABLE スイッチ = OFF か？
		goto	clext01			;No

		call	wait_15ms		;チャッタリング吸収

clext02		return

;--------------------------------------------------------------------------
;		年、月、日、(曜日)、AM/PM、時、分、秒 の表示
;--------------------------------------------------------------------------

		; 年の表示
yy_disp
		swapf	bcd_yy,W		;10 Year
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	bcd_yy,W		;Year
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------

		; 月の表示
nn_disp
		swapf	bcd_nn,W		;10 Month
		andlw	h'01'			;
		iorlw	h'30'			;'0'～'1'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	bcd_nn,W		;Month
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------

		; 日の表示
dd_disp
		swapf	bcd_dd,W		;10 Date
		andlw	h'03'			;
		iorlw	h'30'			;'0'～'3'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	bcd_dd,W		;Date
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------

		; 曜日の表示
ww_disp
		movf	bcd_ww,W		;曜日_BCD カウンタ
		movwf	addr_low		;
		lslf	addr_low,F		;x 2 倍
		lslf	addr_low,F		;x 4 倍

		movlw	high week_table		;テーブルデータの先頭 high アドレス
		movwf	addr_high		;
		movlw	low week_table		;テーブルデータの先頭 low アドレス
		addwf	addr_low,F		;
		btfsc	STATUS,C		;オーバーフローした場合は
		incf	addr_high,F		;high アドレスの更新

		call	I2cLcd_Disp		;I2C LCD へ文字列データを出力
		return

		; 曜日 データテーブル
week_table
		dt	"DAY",0     ;= "EDAY"	;         0 (例外)

		dt	"SUN",0			;bcd_ww = 1
		dt	"MON",0			;         2
		dt	"TUE",0			;         3
		dt	"WED",0			;         4
		dt	"THU",0			;         5
		dt	"FRI",0			;         6
		dt	"SAT",0			;         7

		;	[ (SUN) AM ]		;曜日 AM/PM の表示
		;	  01234567

;--------------------------------------------------------------------------

		; AM/PM の表示
ampm_disp
		btfss	time_flg,1		;時間表示モードフラグ.bit1=0:24/1:12 = 1(12) か？
		goto	apmdp01			;No

		movlw	'A'			;'A'
		btfsc	time_flg,0		;時間表示モードフラグ.bit0=0:AM/1:PM = 0(AM) か？
		movlw	'P'			;No. 'P'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movlw	'M'			;'M'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		goto	apmdp02

apmdp01		movlw	' '			;' '
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		movlw	' '			;' '
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

apmdp02		return

;--------------------------------------------------------------------------

		; 時の表示
hh_disp
		movf	bcd_hh,W		;時_BCD カウンタ
		movwf	temp_hh			;仮の時_BCD カウンタ
		btfsc	time_flg,1		;時間表示モードフラグ.bit1=0:24/1:12 = 1(12) か？
		call	cnv_24to12		;Yes. 24時間表示を12時間表示に変換

		swapf	temp_hh,W		;10 Hours
		andlw	h'03'			;
		btfss	STATUS,Z		;10 Hours = 0 か？
		goto	hhdp01			;No

		btfss	time_flg,1		;時間表示モードフラグ.bit1=0:24/1:12 = 1(12) か？
		goto	hhdp01			;No

		movlw	' '			;' ' ゼロサプレス
		goto	hhdp02

hhdp01		iorlw	h'30'			;'0'～'2'

hhdp02		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	temp_hh,W		;Hours
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------

		; 分の表示
mm_disp
		swapf	bcd_mm,W		;10 Minutes
		andlw	h'07'			;
		iorlw	h'30'			;'0'～'5'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	bcd_mm,W		;Minutes
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------

		; 秒の表示
ss_disp
		swapf	bcd_ss,W		;10 Seconds
		andlw	h'07'			;
		iorlw	h'30'			;'0'～'5'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	bcd_ss,W		;Seconds
		andlw	h'0f'			;
		iorlw	h'30'			;'0'～'9'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------
;		24時間表示を12時間表示に変換
;--------------------------------------------------------------------------

;(24H) 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 
;(12H) 12  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11
;      am am am am am am am am am am am am pm pm pm pm pm pm pm pm pm pm pm pm
;                                          -----------------------------------
;     +12                                 -12
;    ( 12 ef f0 f1 f2 f3 f4 f5 f6 f7 fe ff 00 01 02 03 04 05 06 07 0e 0f 10 11 )

cnv_24to12
		; (am)
		bcf	time_flg,0		;時間表示モードフラグ.bit0=0: am に設定

		movf	temp_hh,W
		btfss	STATUS,Z		;仮の時_BCD カウンタ = h'00' か？
		goto	cnv01			;No

		movlw	h'12'
		movwf	temp_hh			;仮の時_BCD カウンタ temp_hh = h'12'
		goto	cnv02

cnv01		movlw	h'12'
		subwf	temp_hh,W
		btfss	STATUS,C		;仮の時_BCD カウンタ < h'12' か？
		goto	cnv02			;Yes

		; (pm)
		bsf	time_flg,0		;時間表示モードフラグ.bit0=1: pm に設定

		btfsc	STATUS,Z		;仮の時_BCD カウンタ = h'12' か？
		goto	cnv02			;Yes

		movwf	temp_hh			;仮の時_BCD カウンタ temp_hh = temp_hh - 12
		movlw	h'0e'
		subwf	temp_hh,W
		btfss	STATUS,C		;仮の時_BCD カウンタ < h'0e' か？
		goto	cnv02			;Yes

		movlw	h'10'
		subwf	temp_hh,W
		btfsc	STATUS,C		;仮の時_BCD カウンタ < h'10' か？
		goto	cnv02			;No

		movlw	h'06'
		subwf	temp_hh,F		;補正

cnv02		return

;
;==========================================================================
; menu_no = 8		現在時刻（年月日、時分秒）の設定変更
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │●│   │●│   │●│   │●│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		  LEFT スイッチ ..... ブリンク位置のポインタを - 1
;		 RIGHT スイッチ ..... ブリンク位置のポインタを + 1

;		  DOWN スイッチ ..... ブリンク位置の値を - 1
;		    UP スイッチ ..... ブリンク位置の値を + 1

;		  EXIT スイッチ ..... 「現在時刻の設定」を終了し、「現在時刻の表示」に移行

;		  LEFT スイッチ + 
;		 RIGHT スイッチ ..... 「現在時刻の設定」を中断し、「現在時刻の表示」に移行

;		 RIGHT スイッチ + 
;		  LEFT スイッチ ..... 「現在時刻の設定」を中断し、「現在時刻の表示」に移行

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				> bit7: 処理終了（エグジット）フラグ
;				  bit6: 例外終了（次処理に移行）フラグ
;				> bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				  bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				  bit2: 状態変化割り込み記憶フラグ
;				  bit1: スリープ中状態フラグ
;				  bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

clock_adjust

		call	buzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		call	clock_rtc_read		;RTC DS3231 から年月日、時分秒を読み出し
		clrf	stat2_flg		;進行状態-2フラグの初期設定
		clrf	blk_point		;ブリンク位置 = 0 初期設定

		; 「現在時刻（年月日、時分秒）設定変更」画面の表示

cladj01		movlw	h'0c'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク

		movlw	3
		subwf	blk_point,W		;
		btfsc	STATUS,C		;ブリンク位置 < 3 か？
		goto	cladj02			;No

		;	[ Date Set ]		;１行目 ... 年月日設定メッセージ
		;	  01234567

		Disp_I2cLcd	h'80',date_set_msg,1	;表示位置指定 (１行目先頭)

		;	[ xx/xx/xx ]		;２行目 ... 年月日の表示
		;	  01234567

		movlw	h'c0'			;表示位置指定 (２行目先頭)
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
		call	yy_disp			;年の表示
		movlw	'/'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	nn_disp			;月の表示
		movlw	'/'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	dd_disp			;日の表示
		goto	cladj03

		;	[ Time Set ]		;１行目 ... 時分秒設定メッセージ
		;	  01234567

cladj02		Disp_I2cLcd	h'80',time_set_msg,1	;表示位置指定 (１行目先頭)

		;	[ xx:xx:xx ]		;２行目 ... 時分秒の表示
		;	  01234567

		movlw	h'c0'			;表示位置指定 (２行目先頭)
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
		call	hh_disp			;時の表示
		movlw	':'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	mm_disp			;分の表示
		movlw	':'
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		call	ss_disp			;秒の表示

		; 各スイッチの入力チェック

cladj03		bcf	stat2_flg,5		;画面変更フラグ = 0
		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		call	blk_point_table		;ブリンク表示位置の DDRAM アドレスを取得
		iorlw	h'c0'			;表示位置 (ブリンク位置)を指定 (２行目)
		call	I2cLcd_Cmd		;LCD へコマンドを出力
		movlw	h'0d'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=1: ブリンク

cladj04		btfss	PORTB,_swLEF		;LEFT スイッチ = ON か？
		call	adj_left_switch		;Yes

		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		call	adj_right_switch	;Yes

		btfsc	stat2_flg,7		;処理終了フラグ = 1 (中断) か？
		goto	cladj05			;Yes

		btfsc	stat2_flg,5		;画面変更フラグ = 1 か？
		goto	cladj01			;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	cladj03			;Yes

		btfss	PORTB,_swDWN		;DOWN スイッチ = ON か？
		call	adj_down_switch		;Yes

		btfss	PORTB,_swUP		;UP スイッチ = ON か？
		call	adj_up_switch		;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	cladj01			;Yes

		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	cladj04			;No

		; 「現在時刻（年月日、時分秒）設定変更」の終了

		call	wait_15ms		;チャッタリング吸収
		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

		call	counter_to_buffer
		Rtc_Write_M  seconds,7		;RTC DS3231 へ年月日、時分秒を書き込み

cladj05		movlw	h'0c'			;表示オン／オフコントロール
		call	I2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク

		clrf	stat2_flg		;進行状態-2フラグの初期設定
		call	wait_15ms		;チャッタリング吸収

		movlw	1
		movwf	menu_no			;メニュー番号 = 1 設定
		goto	clock_display		;「現在時刻の表示」に移行

;--------------------------------------------------------------------------

		; ブリンク表示位置テーブル

blk_point_table
		movf	blk_point,W		;ブリンク位置ポインタ
		brw

		;	0     1     2
		dt	h'00',h'03',h'06'

		;	3     4     5
		dt	h'40',h'43',h'46'

;--------------------------------------------------------------------------
;	     LEFT スイッチの処理 ...「現在時刻の設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 LEFT スイッチ = ON ..... ブリンク位置のポインタを - 1

;		 LEFT スイッチ = ON + 
;		RIGHT スイッチ = ON ..... 「現在時刻の設定」を中断し、「現在時刻の表示」に移行

		;	0     1     2	 	 0  1  2
		;	h'00',h'03',h'06'	"xx/xx/xx"
		;	"YH"  "NH"  "DH"	 01234567

		;	3     4     5	 	 3  4  5
		;	h'40',h'43',h'46'	"xx:xx:xx"
		;	"HH"  "MH"  "SH"	 01234567

adj_left_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swLEF		;再度 LEFT スイッチ = ON か？
		goto	ajlef05			;No
 
		; (左移動のとき)

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		decf	blk_point,F		;ブリンク位置ポインタ - 1
		incf	blk_point,W
		movlw	5
		btfsc	STATUS,Z		;blk_point = -1(W=0) か？
		movwf	blk_point		;Yes. blk_point = 5 に設定

		movlw	2			;"DH" 桁
		subwf	blk_point,W
		btfsc	STATUS,Z		;blk_point = 2 か？
		goto	ajlef01			;Yes

		movlw	5			;"SH" 桁
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 5 か？
		goto	ajlef02			;No

ajlef01		bsf	stat2_flg,5		;画面変更フラグ = 1

ajlef02		btfsc	PORTB,_swLEF		;LEFT スイッチ = ON か？
		goto	ajlef04			;No

		btfsc	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		goto	ajlef02			;No

		bsf	stat2_flg,7		;処理終了フラグ = 1 (中断)

ajlef03		comf	PORTB,W			;全ビットを反転
		andlw	h'c0'
		btfss	STATUS,Z		;LEFT スイッチ and RIGHT スイッチ = OFF か？
		goto	ajlef03			;No

ajlef04		call	wait_15ms		;チャッタリング吸収

ajlef05		return

;--------------------------------------------------------------------------
;	    RIGHT スイッチの処理 ...「現在時刻の設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		RIGHT スイッチ = ON ..... ブリンク位置のポインタを + 1

;		RIGHT スイッチ = ON + 
;		 LEFT スイッチ = ON ..... 「現在時刻の設定」を中断し、「現在時刻の表示」に移行

		;	0     1     2	 	 0  1  2
		;	h'00',h'03',h'06'	"xx/xx/xx"
		;	"YH"  "NH"  "DH"	 01234567

		;	3     4     5	 	 3  4  5
		;	h'40',h'43',h'46'	"xx:xx:xx"
		;	"HH"  "MH"  "SH"	 01234567

adj_right_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swRIG		;再度 RIGHT スイッチ = ON か？
		goto	ajrig05			;No

		; (右移動のとき)

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		incf	blk_point,F		;ブリンク位置ポインタ + 1
		movlw	5 + 1
		subwf	blk_point,W		;blk_point - (5 + 1)
		btfsc	STATUS,C		;blk_point < (5 + 1) か？
		clrf	blk_point		;No. blk_point = 0 に設定

		movf	blk_point,W		;"YH" 桁
		btfsc	STATUS,Z		;blk_point = 0 か？
		goto	ajrig01			;Yes

		movlw	3			;"HH" 桁
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 3 か？
		goto	ajrig02			;No

ajrig01		bsf	stat2_flg,5		;画面変更フラグ = 1

ajrig02		btfsc	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		goto	ajrig04			;No

		btfsc	PORTB,_swLEF		;LEFT スイッチ = ON か？
		goto	ajrig02			;No

		bsf	stat2_flg,7		;処理終了フラグ = 1 (中断)

ajrig03		comf	PORTB,W			;全ビットを反転
		andlw	h'c0'
		btfss	STATUS,Z		;RIGHT スイッチ and LEFT スイッチ = OFF か？
		goto	ajrig03			;No

ajrig04		call	wait_15ms		;チャッタリング吸収

ajrig05		return

;--------------------------------------------------------------------------
;	    DOWN スイッチの処理 ...「現在時刻の設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		DOWN スイッチ = ON ..... ブリンク位置の値を - 1

		;	0     1     2	 	 0  1  2
		;	h'00',h'03',h'06'	"xx/xx/xx"
		;	"YH"  "NH"  "DH"	 01234567

		;	3     4     5	 	 3  4  5
		;	h'40',h'43',h'46'	"xx:xx:xx"
		;	"HH"  "MH"  "SH"	 01234567

adj_down_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	ajdwn08			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	blk_point,W
		btfss	STATUS,Z		;blk_point = 0 か？
		goto	ajdwn01			;No

		call	bcd_yl_dec		;年_BCD カウンタのデクリメント
		goto	ajdwn03

ajdwn01		movlw	1
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 1 か？
		goto	ajdwn02			;No

		call	bcd_nn_dec		;月_BCD カウンタのデクリメント
		goto	ajdwn03

ajdwn02		movlw	2
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 2 か？
		goto	ajdwn04			;No

		call	bcd_dd_dec		;日_BCD カウンタのデクリメント

ajdwn03		call	day_week		;該当日の曜日を取得
		movwf	bcd_ww			;曜日_BCD カウンタ
		goto	ajdwn07

ajdwn04		movlw	3
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 3 か？
		goto	ajdwn05			;No

		call	bcd_hh_dec		;時_BCD カウンタのデクリメント
		goto	ajdwn07

ajdwn05		movlw	4
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 4 か？
		goto	ajdwn06			;No

		call	bcd_mm_dec		;分_BCD カウンタのデクリメント
		goto	ajdwn07

ajdwn06	;	movlw	5
	;	subwf	blk_point,W
	;	btfss	STATUS,Z		;blk_point = 5 か？
	;	goto	ajdwn07			;No

		call	bcd_ss_dec		;秒_BCD カウンタのデクリメント

ajdwn07	;	btfss	PORTB,_swDWN		;DOWN スイッチ = OFF か？
	;	goto	$ - 1			;No

	;	call	wait_15ms		;チャッタリング吸収
		call	wait_200ms		;早送りの速度調整

ajdwn08		return

;--------------------------------------------------------------------------
;	     UP スイッチの処理 ...「現在時刻の設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		UP スイッチ = ON ..... ブリンク位置の値を + 1

		;	0     1     2	 	 0  1  2
		;	h'00',h'03',h'06'	"xx/xx/xx"
		;	"YH"  "NH"  "DH"	 01234567

		;	3     4     5	 	 3  4  5
		;	h'40',h'43',h'46'	"xx:xx:xx"
		;	"HH"  "MH"  "SH"	 01234567

adj_up_switch

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swUP		;再度 UP スイッチ = ON か？
		goto	ajup08			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	blk_point,W
		btfss	STATUS,Z		;blk_point = 0 か？
		goto	ajup01			;No

		call	bcd_yl_inc		;年_BCD カウンタのインクリメント
		goto	ajup03

ajup01		movlw	1
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 1 か？
		goto	ajup02			;No

		call	bcd_nn_inc		;月_BCD カウンタのインクリメント
		goto	ajup03

ajup02		movlw	2
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 2 か？
		goto	ajup04			;No

		call	bcd_dd_inc		;日_BCD カウンタのインクリメント

ajup03		call	day_week		;該当日の曜日を取得
		movwf	bcd_ww			;曜日_BCD カウンタ
		goto	ajup07

ajup04		movlw	3
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 3 か？
		goto	ajup05			;No

		call	bcd_hh_inc		;時_BCD カウンタのインクリメント
		goto	ajup07

ajup05		movlw	4
		subwf	blk_point,W
		btfss	STATUS,Z		;blk_point = 4 か？
		goto	ajup06			;No

		call	bcd_mm_inc		;分_BCD カウンタのインクリメント
		goto	ajup07

ajup06	;	movlw	5
	;	subwf	blk_point,W
	;	btfss	STATUS,Z		;blk_point = 5 か？
	;	goto	ajup07			;No

		call	bcd_ss_inc		;秒_BCD カウンタのインクリメント

ajup07	;	btfss	PORTB,_swUP		;UP スイッチ = OFF か？
	;	goto	$ - 1			;No

	;	call	wait_15ms		;チャッタリング吸収
		call	wait_200ms		;早送りの速度調整

ajup08		return

;==========================================================================
;	    各 BCD カウンタのインクリメント / デクリメント計算
;==========================================================================
;--------------------------------------------------------------------------
;		日_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_dd_inc
		call	month_days		;各月の日数計算
		subwf	bcd_dd,W
		btfss	STATUS,Z		;日_BCD カウンタ = 各月の最終日 か？
		goto	ddinc01			;No

		movlw	h'01'
		movwf	bcd_dd			;日_BCD カウンタ = h'01' 設定
		goto	ddinc02

ddinc01		movlw	high bcd_dd		;日_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_dd		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント

ddinc02		return

;--------------------------------------------------------------------------

;		各月の日数計算

month_days
		movlw	h'02'
		subwf	bcd_nn,W
		btfss	STATUS,Z		;月_BCD カウンタ = h'02' か？
		goto	mday02			;No

		movf	bcd_yl,W		;年(下位2桁)_BCD カウンタ
		movwf	cur_yl
		movf	bcd_yh,W		;年(上位2桁)_BCD カウンタ
		movwf	cur_yh
		call	uruu_check		;平年／閏年の判定
		btfss	uru_flg,0		;閏年 か？
		goto	mday01			;No

		movlw	h'29'			;閏年 2月
		goto	mday04

mday01		movlw	h'28'			;平年 2月
		goto	mday04

mday02		movlw	h'04'
		subwf	bcd_nn,W
		btfsc	STATUS,Z		;月_BCD カウンタ = h'04' か？
		goto	mday03			;Yes

		movlw	h'06'
		subwf	bcd_nn,W
		btfsc	STATUS,Z		;月_BCD カウンタ = h'06' か？
		goto	mday03			;Yes

		movlw	h'09'
		subwf	bcd_nn,W
		btfsc	STATUS,Z		;月_BCD カウンタ = h'09' か？
		goto	mday03			;Yes

		movlw	h'11'
		subwf	bcd_nn,W
		btfsc	STATUS,Z		;月_BCD カウンタ = h'11' か？
		goto	mday03			;Yes

		movlw	h'31'			;h'01', h'03', h'05', h'07', h'08', h'10', h'12'
		goto	mday04

mday03		movlw	h'30'			;h'04', h'06', h'09', h'11'

mday04		return

;--------------------------------------------------------------------------

;		平年／閏年の判定

uruu_check
		clrf	uru_flg			;平年に設定

		movf	cur_yl,W		;年(下位2桁)(変)_BCD カウンタ
		call	bcd2_to_binary		;BCD (2桁) からバイナリ変換
		andlw	h'03'			;下位2ビット
		btfss	STATUS,Z		;下位2ビット = b'00' か？
		goto	uru02			;No. 平年 ... 4で割れない

		movf	cur_yl,W
		btfss	STATUS,Z		;年(下位2桁)(変)_BCD カウンタ = h'00' か？
		goto	uru01			;No. 閏年 ... 100で割れない

		movf	cur_yh,W		;年(上位2桁)(変)_BCD カウンタ
		call	bcd2_to_binary		;BCD (2桁) からバイナリ変換
		andlw	h'03'			;下位2ビット
		btfss	STATUS,Z		;下位2ビット = b'00' か？
		goto	uru02			;No. 平年 ... 400で割れない

uru01		bsf	uru_flg,0		;閏年に設定

uru02		return

;--------------------------------------------------------------------------

;		BCD (2桁) からバイナリ変換

bcd2_to_binary
		movwf	work2			;退避
		swapf	work2,W			;上位4ビット(10位)を BCD からバイナリ変換
		andlw	h'0f'
		movwf	work1
		lslf	work1,F			;2倍
		lslf	work1,F			;4倍
		addwf	work1,F			;5倍
		lslf	work1,F			;10倍

		movf	work2,W			;下位4ビット(単位)
		andlw	h'0f'
		addwf	work1,W			;10位 + 単位 = W レジスタ
		return

;--------------------------------------------------------------------------
;		月_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_nn_inc
		movlw	high bcd_nn		;月_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_nn		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント

		movlw	h'13'
		subwf	bcd_nn,W
		btfss	STATUS,Z		;月_BCD カウンタ = h'13' か？
		goto	nninc01			;No

		movlw	h'01'
		movwf	bcd_nn			;月_BCD カウンタ = h'01' 設定

nninc01		return

#ifdef comment
;--------------------------------------------------------------------------
;		年(4桁)_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_yyyy_inc
		call	bcd_yl_inc		;年(下位2桁)_BCD カウンタのインクリメント
		btfss	STATUS,C		;年(下位2桁)_BCD カウンタ >= 'a0' か？
		goto	yyinc01			;No

		call	bcd_yh_inc		;年(上位2桁)_BCD カウンタのインクリメント
		btfss	STATUS,C		;年(上位2桁)_BCD カウンタ >= 'a0' か？
		goto	yyinc01			;No

		movlw	h'01'
		movwf	bcd_yl			;9999 → (0000) → 0001

yyinc01		return
#endif

;--------------------------------------------------------------------------
;		年(下位2桁)_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_yl_inc
		movlw	high bcd_yl		;年(下位2桁)_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_yl		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント

		movlw	h'a0'
		subwf	bcd_yl,W
		btfss	STATUS,Z		;年(下位2桁)_BCD カウンタ = 'a0' か？
		goto	ylinc01			;No

		clrf	bcd_yl			;年(下位2桁)_BCD カウンタ = h'00' 設定

ylinc01		return

#ifdef comment
;--------------------------------------------------------------------------
;		年(上位2桁)_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_yh_inc
		movlw	high bcd_yh		;年(上位2桁)_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_yh		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント

		movlw	h'a0'
		subwf	bcd_yh,W
		btfss	STATUS,Z		;年(上位2桁)_BCD カウンタ = 'a0' か？
		goto	yhinc01			;No

		clrf	bcd_yh			;年(上位2桁)_BCD カウンタ = h'00' 設定

yhinc01		return
#endif

;--------------------------------------------------------------------------
;		日_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_dd_dec
		decf	bcd_dd,F		;日_BCD カウンタ -1 更新
		btfss	STATUS,Z		;日_BCD カウンタ = h'00' か？
		goto	dddec01			;No

		call	month_days		;各月の日数計算
		movwf	bcd_dd			;日_BCD カウンタ 設定
		goto	dddec02

dddec01		movf	bcd_dd,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0f'
		btfss	STATUS,Z		;下位4ビット = h'0f' か？
		goto	dddec02			;No

		movlw	h'06'
		subwf	bcd_dd,F		;日_BCD カウンタ 更新

dddec02		return

;--------------------------------------------------------------------------
;		月_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_nn_dec
		decf	bcd_nn,F		;月_BCD カウンタ -1 更新
		btfss	STATUS,Z		;月_BCD カウンタ = h'00' か？
		goto	nndec01			;No

		movlw	h'12'
		goto	nndec02

nndec01		movlw	h'0f'
		subwf	bcd_nn,W
		btfss	STATUS,Z		;月_BCD カウンタ = h'0f' か？
		goto	nndec03			;No

		movlw	h'09'

nndec02		movwf	bcd_nn			;月_BCD カウンタの設定

nndec03		return

#ifdef comment
;--------------------------------------------------------------------------
;		年(4桁)_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_yyyy_dec
		call	bcd_yl_dec		;年(下位2桁)_BCD カウンタのデクリメント
		movf	bcd_yl,W
		btfsc	STATUS,Z		;年(下位2桁)_BCD カウンタ <> '00' か？
		goto	yydec01			;No
		
		movlw	h'99'
		subwf	bcd_yl,W
		btfss	STATUS,Z		;年(下位2桁)_BCD カウンタ = '99' か？
		goto	yydec02			;No

		call	bcd_yh_dec		;年(上位2桁)_BCD カウンタのデクリメント
		goto	yydec02

yydec01		movf	bcd_yh,W
		btfss	STATUS,Z		;年(上位2桁)_BCD カウンタ = '00' か？
		goto	yydec02			;No

		movlw	h'99'
		movwf	bcd_yh
		movwf	bcd_yl			;0001 → (0000) → 9999

yydec02		return
#endif

;--------------------------------------------------------------------------
;		年(下位2桁)_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_yl_dec
		decf	bcd_yl,F		;年(下位2桁)_BCD カウンタ -1 更新
		incf	bcd_yl,W
		btfss	STATUS,Z		;年(下位2桁)_BCD カウンタ = h'ff' か？
		goto	yldec01			;No

		movlw	h'66'
		subwf	bcd_yl,F		;年(下位2桁)_BCD カウンタ 更新
		goto	yldec02

yldec01		movf	bcd_yl,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0f'
		btfss	STATUS,Z		;下位4ビット = h'0f' か？
		goto	yldec02			;No

		movlw	h'06'
		subwf	bcd_yl,F		;年(下位2桁)_BCD カウンタ 更新

yldec02		return

#ifdef comment
;--------------------------------------------------------------------------
;		年(上位2桁)_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_yh_dec
		decf	bcd_yh,F		;年(上位2桁)_BCD カウンタ -1 更新
		incf	bcd_yh,W
		btfss	STATUS,Z		;年(上位2桁)_BCD カウンタ = h'ff' か？
		goto	yhdec01			;No

		movlw	h'66'
		subwf	bcd_yh,F		;年(上位2桁)_BCD カウンタ 更新
		goto	yhdec02

yhdec01		movf	bcd_yh,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0f'
		btfss	STATUS,Z		;下位4ビット = h'0f' か？
		goto	yhdec02			;No

		movlw	h'06'
		subwf	bcd_yh,F		;年(上位2桁)_BCD カウンタ 更新

yhdec02		return	
#endif

;--------------------------------------------------------------------------
;		秒_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_ss_inc
		movlw	high bcd_ss		;秒_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_ss		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'60'
		subwf	bcd_ss,W
		btfsc	STATUS,C		;秒_BCD カウンタ < h'60' か？
		clrf	bcd_ss			;No. 秒_BCD カウンタのクリア
		return

;--------------------------------------------------------------------------
;		分_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_mm_inc
		movlw	high bcd_mm		;分_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_mm		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'60'
		subwf	bcd_mm,W
		btfsc	STATUS,C		;分_BCD カウンタ < h'60' か？
		clrf	bcd_mm			;No. 分_BCD カウンタのクリア
		return

;--------------------------------------------------------------------------
;		時_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_hh_inc
		movlw	high bcd_hh		;時_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_hh		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'24'
		subwf	bcd_hh,W
		btfsc	STATUS,C		;時_BCD カウンタ < h'24' か？
		clrf	bcd_hh			;No. 時_BCD カウンタのクリア
		return

;--------------------------------------------------------------------------
;		秒_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_ss_dec
		movlw	high bcd_ss		;秒_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_ss		;
		movwf	FSR0L			;間接アドレスに設定
		call	dec_bcd			;BCDデクリメント
		movlw	h'f9'			;h'00' - h'01' - h'06'
		subwf	bcd_ss,W
		btfss	STATUS,Z		;秒_BCD カウンタ = h'f9' か？
		goto	ssdec01			;No

		movlw	h'59'
		movwf	bcd_ss			;秒_BCD カウンタ = h'59' 設定

ssdec01		return

;--------------------------------------------------------------------------
;		分_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_mm_dec
		movlw	high bcd_mm		;分_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_mm		;
		movwf	FSR0L			;間接アドレスに設定
		call	dec_bcd			;BCDデクリメント
		movlw	h'f9'			;h'00' - h'01' - h'06'
		subwf	bcd_mm,W
		btfss	STATUS,Z		;分_BCD カウンタ = h'f9' か？
		goto	mmdec01			;No

		movlw	h'59'
		movwf	bcd_mm			;分_BCD カウンタ = h'59' 設定

mmdec01		return

;--------------------------------------------------------------------------
;		時_BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_hh_dec
		movlw	high bcd_hh		;時_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low bcd_hh		;
		movwf	FSR0L			;間接アドレスに設定
		call	dec_bcd			;BCDデクリメント
		movlw	h'f9'			;h'00' - h'01' - h'06'
		subwf	bcd_hh,W
		btfss	STATUS,Z		;時_BCD カウンタ = h'f9' か？
		goto	hhdec01			;No

		movlw	h'23'
		movwf	bcd_hh			;時_BCD カウンタ = h'23' 設定

hhdec01		return

;--------------------------------------------------------------------------

;		BCD インクリメント

inc_bcd
		incf	INDF0,F			;BCD カウンタ +1 更新
		movf	INDF0,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0a'
		btfss	STATUS,Z		;下位4ビット = d'10' か？
		return				;No. Z = 0: 桁上がり指定 = 0 (なし) 

		movlw	h'06'
		addwf	INDF0,F			;下位4ビット = 0, 上位4ビット = + 1
		bsf	STATUS,Z		;    Z = 1: 桁上がり指定 = 1 (あり) 
		return

;--------------------------------------------------------------------------

;		BCD デクリメント

dec_bcd
		decf	INDF0,F			;BCD カウンタ -1 更新
		movf	INDF0,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0f'
		btfss	STATUS,Z		;下位4ビット = h'0f' か？
		return				;No. Z = 0: 桁上がり指定 = 0 (なし) 

		movlw	h'06'
		subwf	INDF0,F			;下位4ビット = 9, (上位4ビット = -1)
		bsf	STATUS,Z		;    Z = 1: 桁上がり指定 = 1 (あり) 
		return

;--------------------------------------------------------------------------
;		該当日の曜日を取得
;--------------------------------------------------------------------------

; 入力:		bcd_yh: 年(上位2桁)_BCD カウンタ, bcd_yl: 年(下位2桁)_BCD カウンタ,
;		bcd_nn: 月_BCD カウンタ, bcd_dd: 日_BCD カウンタ

; 出力:		cur_week: ( 0:日, 1:月, 2:火, 3:水, 4:木, 5:金, 6:土 )
;  (+1して出力)	cur_week: ( 1:日, 2:月, 3:火, 4:水, 5:木, 6:金, 7:土 )

; ワーク:	cur_yh, cur_yl, xxx_yh, work2
; call:		bcd2_to_binary, uruu_check, inc_bcd, month_day2

day_week
		movlw	h'01'
		movwf	cur_yl			;西暦元年 = '0001' とする
		clrf	cur_yh			;

		movlw	h'01'
		movwf	cur_week		;初期設定 (西暦元年1月1日 = 月曜日 とする)

		; 年の変換 (400年後毎の同月同日は同じ曜日)

		movf	bcd_yh,W		;年(上位2桁)_BCD カウンタ
		call	bcd2_to_binary		;バイナリ変換
		movwf	xxx_yh			;
						;
dweek01		movlw	4			;
		subwf	xxx_yh,W		;
		btfss	STATUS,C		;xxx_yh < 4 か？
		goto	dweek03			;Yes
						;
		btfss	STATUS,Z		;xxx_yh = 4 か？
		goto	dweek02			;No
						;
		movf	bcd_yl,W		;
		btfsc	STATUS,Z		;bcd_yl = 0 か？
		goto	dweek03			;Yes
						;
dweek02		movlw	4			;
		subwf	xxx_yh,F		;
		goto	dweek01			;

		; 年の計算

dweek03		movf	bcd_yl,W		;年(下位2桁)_BCD カウンタ
		subwf	cur_yl,W
		btfss	STATUS,Z		;cur_yl = bcd_yl か？
		goto	dweek04			;No

		movf	xxx_yh,W		;xxx_yh =< 4 (400年以下に変換)
		subwf	cur_yh,W
		btfsc	STATUS,Z		;cur_yh = xxx_yh か？
		goto	dweek05			;Yes

dweek04		movlw	365 % 7			;365 % 7 = 365 - 7 * 52 = 1
		addwf	cur_week,F
		call	uruu_check		;平年／閏年の判定
		btfsc	uru_flg,0		;平年 か？
		incf	cur_week,F		;No. 閏年

		movlw	7
		subwf	cur_week,W
		btfsc	STATUS,C		;cur_week < 7 か？
		movwf	cur_week		;No

		movlw	high cur_yl		;年(下位2桁)(変)_BCD カウンタの番地
		movwf	FSR0H			;
		movlw	low cur_yl		;
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント

		movlw	h'a0'
		subwf	cur_yl,W
		btfss	STATUS,Z		;年(下位2桁)(変)_BCD カウンタ = h'a0' か？
		goto	dweek03			;No

		clrf	cur_yl			;年(下位2桁)(変)_BCD カウンタ = h'00' 設定

		movlw	low cur_yh		;年(上位2桁)(変)_BCD カウンタの番地
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント
		goto	dweek03

		; 月の計算

dweek05		movlw	h'01'
		movwf	cur_nn			;月(変)_BCD カウンタ

dweek06		movf	bcd_nn,W		;月_BCD カウンタ
		subwf	cur_nn,W
		btfsc	STATUS,Z		;cur_nn = bcd_nn か？
		goto	dweek08			;Yes

		movf	cur_nn,W
		call	bcd2_to_binary		;BCD (2桁) からバイナリ変換
		movwf	work2			;退避
		call	month_day2		;月データのテーブル読み出し
		addwf	cur_week,F
		movlw	h'02'
		subwf	cur_nn,W
		btfss	STATUS,Z		;cur_nn = 2 か？
		goto	dweek07			;No

		call	uruu_check		;平年／閏年の判定
		btfsc	uru_flg,0		;平年 か？
		incf	cur_week,F		;No. 閏年

dweek07		movlw	7
		subwf	cur_week,W
		btfsc	STATUS,C		;cur_week < 7 か？
		movwf	cur_week		;No

		movlw	low cur_nn		;月(変)_BCD カウンタの番地
		movwf	FSR0L			;間接アドレスに設定
		call	inc_bcd			;BCD インクリメント
		goto	dweek06

		; 日の計算

dweek08		movf	bcd_dd,W		;日_BCD カウンタ
		call	bcd2_to_binary		;BCD (2桁) からバイナリ変換
		addwf	cur_week,F
		decf	cur_week,F		;-1（当日分）

dweek09		movlw	7
		subwf	cur_week,W
		btfss	STATUS,C		;cur_week < 7 か？
		goto	dweek10			;Yes

		movwf	cur_week		;No
		goto	dweek09

dweek10		incf	cur_week,F		;0～6 → 1～7 に変換

		movf	cur_week,W		;;
		return

;--------------------------------------------------------------------------

month_day2
		decf	work2,W
		brw

day_tbl		retlw	31 % 7			; 1:  31 % 7 = 3
		retlw	28 % 7			; 2:  28 % 7 = 0
		retlw	31 % 7			; 3:  31 % 7 = 3
		retlw	30 % 7			; 4:  30 % 7 = 2
		retlw	31 % 7			; 5:  31 % 7 = 3
		retlw	30 % 7			; 6:  30 % 7 = 2
		retlw	31 % 7			; 7:  31 % 7 = 3
		retlw	31 % 7			; 8:  31 % 7 = 3
		retlw	30 % 7			; 9:  30 % 7 = 2
		retlw	31 % 7			;10:  31 % 7 = 3
		retlw	30 % 7			;11:  30 % 7 = 2
;		retlw	31 % 7			;12:  31 % 7 = 3  (使用しない)


;==========================================================================
;		アラーム（ブザー）音出力ルーチン
;==========================================================================

		; 時報予報音 "プッ" アラーム音出力 (100 mS)
buzzer_pu
		Sound_M		f_ra, 100

		; 時報正報音 "ポッ～～ン" アラーム音出力 (1000 mS)
buzzer_poon
		call	buzzer_po_1_4
		call	buzzer_po_1_4
		call	buzzer_po_1_4

		; "ポッ～～ン" 1/4 アラーム音出力
buzzer_po_1_4
		Sound_M		f_rah, 250

		;"ピッピッ" アラーム音 (230 mS)
buzzer_pipi
		call	buzzer_pi		;"ピッ" アラーム音出力
		call	wait_30ms

		; "ピッ" アラーム音出力 (100 mS)
buzzer_pi
		Sound_M		f_soh, pi_tim

		; "ポッ" アラーム音出力 (100 mS)
buzzer_po
		Sound_M		f_do2, po_tim

		; "ポッポッポッポッ" アラーム音出力 (520 mS)
buzzer_po4
		movlw	4
		movwf	wt3cnt

po4		call	buzzer_po		;"ポッ" アラーム音出力
		call	wait_30ms
		decfsz	wt3cnt,F
		goto	po4

		return

		; "ブッ" アラーム音出力 (100 mS)
buzzer_bu
		Sound_M		f_do, bu_tim

		; "ブー" アラーム音出力 (250 mS)
buzzer_buu
		Sound_M		f_do, buu_tim

		; "ブッブー" アラーム音出力 (450 mS)
buzzer_bubuu
		call	buzzer_bu		;"ブッ" アラーム音出力
		call	wait_100ms
		call	buzzer_buu		;"ブー" アラーム音出力
		return

		; "ドー" アラーム音出力 (200 mS)
buzzer_dl
		Sound_M		f_doh, dms_tim

		; "ミー" アラーム音出力 (200 mS)
buzzer_mi
		Sound_M		f_mih, dms_tim

		; "ソー" アラーム音出力 (200 mS)
buzzer_so
		Sound_M		f_soh, dms_tim

		; "ドー" アラーム音出力 (200 mS)
buzzer_dh
		Sound_M		f_do2, dms_tim

		; ブザー音出力コントロール
buzzer_control
		btfsc	alm_flg,7		;アラーム音出力フラグ = 1 か？
		goto	bzcon01			;Yes

		call	wait_xxms		;入力 W: 音長（ループカウンタ）
		goto	bzcon02

bzcon01		movlb	1			;バンク 1
		bsf	PIE1,TMR1IE		;TMR1 オーバーフロー割り込み許可 = 1
		movlb	0			;バンク 0

		call	wait_xxms		;入力 W: 音長（ループカウンタ）

		movlb	1			;バンク 1
		bcf	PIE1,TMR1IE		;TMR1 オーバーフロー割り込み許可 = 0
		movlb	0			;バンク 0

bzcon02		return

;--------------------------------------------------------------------------

		; "ピポッピポッ" アラーム音出力 (Total 520 mS)

buzzer_pipo2
		call	buzzer_pipo		;"ピポッ" アラーム音出力

		; "ピポッ" アラーム音出力と LED(緑)点滅 (Total 260 mS)
buzzer_pipo
		call	buzzer_pi		;"ピッ" アラーム音出力
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	wait_30ms
		bcf	PORTA,_ledG		;LED(緑) 消灯
		call	buzzer_po		;"ポッ" アラーム音出力
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	wait_30ms
		bcf	PORTA,_ledG		;LED(緑) 消灯
		return

		; ストップウオッチ動作開始: 
		; "ドーミーソードー" アラーム音出力と LED(緑)(赤)交互点滅 (Total 1150 mS)
dl_mi_so_dh
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	buzzer_dl		;"ド" アラーム音出力
		bcf	PORTA,_ledG		;LED(緑) 消灯
		call	wait_50ms
		bsf	PORTA,_ledR		;LED(赤) 点灯
		call	buzzer_mi		;"ミ" アラーム音出力
		bcf	PORTA,_ledR		;LED(赤) 消灯
		call	wait_50ms
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	buzzer_so		;"ソ" アラーム音出力
		bcf	PORTA,_ledG		;LED(緑) 消灯
		call	wait_50ms
		bsf	PORTA,_ledR		;LED(赤) 点灯
		call	buzzer_dh		;"ド" アラーム音出力
		bcf	PORTA,_ledR		;LED(赤) 消灯
		return

		; ストップウオッチ動作終了: 
		; "ドーソーミードー" アラーム音出力と LED(緑)(赤)交互点滅 (Total 1150 mS)
dh_so_mi_dl
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	buzzer_dh		;"ド" アラーム音出力
		bcf	PORTA,_ledG		;LED(緑) 消灯
		call	wait_50ms
		bsf	PORTA,_ledR		;LED(赤) 点灯
		call	buzzer_so		;"ソ" アラーム音出力
		bcf	PORTA,_ledR		;LED(赤) 消灯
		call	wait_50ms
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	buzzer_mi		;"ミ" アラーム音出力
		bcf	PORTA,_ledG		;LED(緑) 消灯
		call	wait_50ms
		bsf	PORTA,_ledR		;LED(赤) 点灯
		call	buzzer_dl		;"ド" アラーム音出力
		bcf	PORTA,_ledR		;LED(赤) 消灯
		return

;==========================================================================
;		ウェイト・ルーチン (4 MHz)
;==========================================================================

		; 100μ秒 ウェイトルーチン
wait_100us
		movlw	19			;1
		movwf	wt1cnt			;1

wu01		goto	$ + 1			;2
		decfsz	wt1cnt,F		;1,2
		goto	wu01			;2,0	1+1+(2+1+2)*18+(2+2+0)=96

		goto	$ + 1			;2
		return				;2	96+2+2=100
						;Total	100/4MHz*4 = 100 μS = 0.1 mS

		; 15m 秒 ウェイトルーチン
wait_15ms
		movlw	15
		goto	wait_xxms

		; 30m 秒 ウェイトルーチン
wait_30ms
		movlw	30
		goto	wait_xxms

		; 50m 秒 ウェイトルーチン
wait_50ms
		movlw	50
		goto	wait_xxms

		; 100m 秒 ウェイトルーチン
wait_100ms
		movlw	100
		goto	wait_xxms

		; 200m 秒 ウェイトルーチン
wait_200ms
		movlw	200
		goto	wait_xxms

		; 1m 秒 ウェイトルーチン
wait_1ms
		movlw	1

		; xx m 秒（ 1m 秒 x W ）ウェイトルーチン
wait_xxms
		movwf	wt2cnt			;1

w1m01		movlw	110			;1
		movwf	wt1cnt			;1

w1m02		goto	$ + 1			;2
		goto	$ + 1			;2
		goto	$ + 1			;2
		decfsz	wt1cnt,F		;1,2
		goto	w1m02			;2,0	(2+2+2+1+2)*109+(2+2+2+2+0)=989

		goto	$ + 1			;2
		goto	$ + 1			;2
		decfsz	wt2cnt,F		;1,2
		goto	w1m01			;2,0	(1+1+989+2+2+1+2)*(W-1)+(1+1+989+2+2+2+0)=998(W-1)+997
						;                                                =998*W-1
		return				;2	1+(998*W-1)+2=998*W+2
						;Total	(998*W+2)/4MHz*4 = (998*W + 2) μS

		; 500m 秒 ウェイトルーチン
wait_500ms
		movlw	5
		goto	w1s01

		; 1 秒 ウェイトルーチン
wait_1sec
		movlw	10
w1s01		movwf	wt3cnt

w1s02		call	wait_100ms
		decfsz	wt3cnt,F
		goto	w1s02
		return

;
;==========================================================================
;--------------------------------------------------------------------------
 		org	h'0800'			;(Page 1)
;--------------------------------------------------------------------------
;==========================================================================

xclock_rtc_read
		movlp	high clock_rtc_read
		call	clock_rtc_read		;RTC DS3231 から年月日、時分秒を読み出し
		movlp	high $
		return

xI2cLcd_Cmd
		movlp	high I2cLcd_Cmd
		call	I2cLcd_Cmd		;I2C LCD へコマンドを出力
		movlp	high $
		return

xI2cLcd_Data
		movlp	high I2cLcd_Data
		call	I2cLcd_Data		;I2C LCD へデータを１文字出力
		movlp	high $
		return

xI2cLcd_Disp
		movlp	high I2cLcd_Disp
		call	I2cLcd_Disp		;I2C LCD １行メッセージ表示
		movlp	high $
		return

xbuzzer_pipo2
		movlp	high buzzer_pipo2
		call	buzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)
		movlp	high $
		return

xbuzzer_pipi
		bsf	PORTA,_ledG		;LED(緑) 点灯
		movlp	high buzzer_pipi
		call	buzzer_pipi		;"ピッピッ" アラーム音出力 (230 mS)
		movlp	high $
		bcf	PORTA,_ledG		;LED(緑) 消灯
		return

xhh_disp
		movlp	high hh_disp
		call	hh_disp			;時の表示
		movlp	high $
		return

xmm_disp
		movlp	high mm_disp
		call	mm_disp			;分の表示
		movlp	high $
		return

xbcd_mm_inc
		movlp	high bcd_mm_inc
		call	bcd_mm_inc		;分_BCD カウンタのインクリメント
		movlp	high $
		return

xbcd_mm_dec
		movlp	high bcd_mm_dec
		call	bcd_mm_dec		;分_BCD カウンタのデクリメント
		movlp	high $
		return

xinc_bcd	
		movlp	high inc_bcd	
		call	inc_bcd			;BCD インクリメント
		movlp	high $
		return

xmenu_display
		movlp	high menu_display	
		call	menu_display		;メニュー項目の表示
		movlp	high $
		return

;--------------------------------------------------------------------------

xwait_100us
		movlp	high wait_100us
		call	wait_100us		; 100μ秒 ウェイトルーチン
		movlp	high $
		return

xwait_xxms
		movlp	high wait_xxms
		call	wait_xxms		; xx m 秒（ 1m 秒 x W ）ウェイトルーチン
		movlp	high $
		return

xwait_1ms					; 1m 秒 ウェイトルーチン
		movlw	1
		goto	xwait_xxms

xwait_15ms					; 15m 秒 ウェイトルーチン
		movlw	15
		goto	xwait_xxms

xwait_30ms					; 30m 秒 ウェイトルーチン
		movlw	30
		goto	xwait_xxms

xwait_200ms					; 200m 秒 ウェイトルーチン
		movlw	200
		goto	xwait_xxms

xwait_1sec
		movlp	high wait_1sec
		call	wait_1sec		; 1 秒 ウェイトルーチン
		movlp	high $
		return

;
;==========================================================================
; menu_no = 2		ストップウオッチ（詳細）
;==========================================================================

;	[スイッチ操作]
;		                                               ENABLE   START/
;		Start                         ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   　┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│■│   │●│     │●│   │○│   │○│   │○│   │○│
;		└■┘   └─┘     └─┘   └─┘   └─┘   └─┘   └─┘
;		 Stop    CLEAR       EXIT     DOWN      UP      LEFT     RIGHT

;		トグルスイッチ = Start（LINE IN = "L"*）..... 動作スタート

;		トグルスイッチ = Stop （LINE IN = "H"*）..... 動作ストップ

;			*スタート信号 (RA4 入力) はインバータにより反転する

;		 CLEAR スイッチ ..... 全桁 "00" にクリア表示

;		  EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat2_flg: 進行状態-2フラグ

;				  bit7: 処理終了（エグジット）フラグ
;				  bit6: 例外終了（次処理に移行）フラグ
;				  bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				> bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				  bit2: 状態変化割り込み記憶フラグ
;				  bit1: スリープ中状態フラグ
;				  bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

detail_stopwatch

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		;     ( [ 00:00:00 ]		;１行目 ... スプリットタイムの初期値 )
		;	[ (StW) 00 ]		;２行目 ... ストップウオッチ(詳細)開始メッセージ
		;	  01234567

#ifdef xx_debug				;(2/6)
		movlb	1			;バンク 1
		movlw	b'01101101'		;RB6-RB5,RB3-RB2,RB0:入力, RB7,RB4,RB1:出力
		movwf	TRISB			;ポートB の I/O 設定
		movlb	0			;バンク 0
		bsf	PORTB,7
#endif

		xDisp_I2cLcd	h'c0',detail_stw_msg,1	;表示位置指定 (２行目)

stwdt01		clrf	bcd_hh_w		;時_BCD カウンタ (ワーク用)
		clrf	bcd_mm_w		;分_BCD カウンタ
		clrf	bcd_ss_w		;秒_BCD カウンタ
		clrf	bcd_xx_w		;1/100秒_BCD カウンタ

		clrf	dsp_point		;全桁 "00" 表示
		call	dt_time_display		;I2C LCD への "HH:MM:SS","XX" 表示

		; スタート信号の監視チェック

stwdt02		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	stwdt06			;Yes

		btfss	PORTA,_Start		;スタート信号 = 'H' か？
		goto	stwdt02			;No

		; ストップウオッチ（詳細）の処理

		call	time_control		;ストップウオッチ／タイマー共通処理

		bsf	PORTA,_ledG		;LED(緑) 点灯 (END 表示)
		movlp	high buzzer_po4
		call	buzzer_po4		;"ポッポッポッポッ" アラーム音出力
		movlp	high $

		; 各スイッチの入力チェック

stwdt04		btfsc	PORTA,_swCLR		;CLEAR スイッチ = ON か？
		goto	stwdt05			;No

#ifdef xx_debug				;(3/6)
		bcf	stat2_flg,4		;タイムアウトフラグ = 0
#endif

		call	xwait_15ms		;チャッタリング吸収
		bcf	PORTA,_ledG		;LED(緑) 消灯
		goto	stwdt01

stwdt05		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	stwdt04			;No

		bcf	PORTA,_ledG		;LED(緑) 消灯

		; 「ストップウオッチ（詳細）」の終了

stwdt06		call	xwait_15ms		;チャッタリング吸収
		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

#ifdef xx_debug				;(4/6)
		movlb	1			;バンク 1
		movlw	b'11101101'		;RB7-RB5,RB3-RB2,RB0:入力, RB4,RB1:出力
		movwf	TRISB			;ポートB の I/O 設定
		movlb	0			;バンク 0
#endif

		call	xwait_15ms		;チャッタリング吸収
		movlp	high main
		goto	main

;--------------------------------------------------------------------------
;	    ストップウオッチ／インターバルタイマーの共通処理
;--------------------------------------------------------------------------

time_control
		movf	alm_flg,W		;アラーム音出力フラグ
		movwf	cur_week		;退避 （cur_week: ワークとして使用）
		bcf	alm_flg,7		;アラーム音出力フラグ = 0

#ifdef xx_debug				;(5/6)
		bsf	PORTA,_ledR		;LED(赤) 点灯
		bcf	PORTB,7
#endif

		; TMR1 オーバーフロー割り込みの初期設定

		movlw	high basic_const	;
		movwf	TMR1H			;TMR1H に設定
		movlw	low basic_const		;
		movwf	TMR1L			;TMR1L に設定

		movlw	100			;10 mS * 100 = 1000 mS = 1 Sec
		btfsc	menu_no,0		;メニュー番号 = 3:「インターバル（間隔）タイマー」か？
		movwf	bsc_cnt			;Yes

		movlb	1			;バンク 1
		bsf	PIE1,TMR1IE		;TMR1 オーバーフロー割り込み許可 = 1
		movlb	0			;バンク 0

		; "HH:MM:SS", ("XX") の表示

cont01		btfss	stat2_flg,3		;1/100秒更新フラグ or 1 秒更新フラグ = 1 か？
		goto	cont02			;No

		bcf	stat2_flg,3		;1/100秒更新フラグ or 1 秒更新フラグ = 0

		btfss	menu_no,0		;menu_no = 2 か？
		call	dt_time_display		;Yes. I2C LCD への "HH:MM:SS","XX" 表示
		btfsc	menu_no,0		;menu_no = 3 か？
		call	itv_time_display	;Yes. I2C LCD への "HH:MM:SS" 表示

cont02		btfsc	stat2_flg,4		;タイムアウトフラグ(タイマー処理で使用) = 1 か？
		goto	cont03			;Yes

		btfsc	PORTA,_Start		;スタート信号 = 'L' (終了) か？
		goto	cont01			;No

		movlb	1			;バンク 1
		bcf	PIE1,TMR1IE		;TMR1 オーバーフロー割り込み許可 = 0
		movlb	0			;バンク 0

cont03

#ifdef xx_debug				;(6/6)
		bsf	PORTB,7
		bcf	PORTA,_ledR		;LED(赤) 消灯
#endif

		movf	cur_week,W		;アラーム音出力フラグ
		movwf	alm_flg			;復帰 （cur_week: ワークとして使用）
		return

;--------------------------------------------------------------------------
;	  I2C LCD への "HH:MM:SS","XX" 表示 (menu_no = 2 の場合)
;--------------------------------------------------------------------------

;	0     1     2     3     4     5      ;  01 23 45  ... dsp_point
;	"HH"  "HL"  "MH"  "ML"  "SH"  "SL"   ; "xx:xx:xx" ... 桁
;	                                     ;  01234567
;	h'00',h'01',h'03',h'04',h'06',h'07'  ;            ... DDRAM のアドレス (１行目)

;	                        6     7      ;        67  ... dsp_point
;	                        "XH"  "XL"   ; "(StW) xx" ... 桁
;	                                     ;  01234567
;	                        h'46',h'47'  ;            ... DDRAM のアドレス (２行目)

		; "HH:MM:SS","XX" の表示

dt_time_display

		call	dsp_point_table		;表示位置テーブル
		iorlw	h'80'			;表示位置指定 
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力

		movlw	high bcd_hh_w		;時_BCD カウンタのアドレス（ワーク用）
		movwf	FSR0H			;
		lsrf	dsp_point,W		;1/2
		addlw	low bcd_hh_w		;時_BCD カウンタのアドレス
		movwf	FSR0L			;間接アドレスの先頭アドレスの設定

dtdsp01		swapf	INDF0,W			;    上位４ビット
		btfsc	dsp_point,0		;今から表示するポイント = 偶数 か？
		moviw	FSR0++			;No. 下位４ビット

		andlw	h'0f'
		iorlw	h'30'
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		incf	dsp_point,F		;表示位置ポインタ + 1
		btfsc	dsp_point,3		;dsp_point = 8 か？
		goto	dtdsp03			;Yes

		btfsc	dsp_point,0		;次に表示するポイント = 偶数 か？
		goto	dtdsp01			;No

		movlw	6
		subwf	dsp_point,W
		btfsc	STATUS,Z		;dsp_point = 6 か？
		goto	dtdsp02			;Yes

		movlw	':'
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		goto	dtdsp01

dtdsp02		movlw	h'c6'			;表示位置指定 
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力
		goto	dtdsp01

dtdsp03		return

;--------------------------------------------------------------------------
;	    I2C LCD への "HH:MM:SS" 表示 (menu_no = 3 の場合)
;--------------------------------------------------------------------------

;	0     1     2     3     4     5      ;  01 23 45  ... dsp_point
;	"HH"  "HL"  "MH"  "ML"  "SH"  "SL"   ; "xx:xx:xx" ... 桁
;					     ;  01234567
;	h'00',h'01',h'03',h'04',h'06',h'07'  ;            ... DDRAM のアドレス

		; "HH:MM:SS" の表示

itv_time_display

		call	dsp_point_table		;表示位置テーブル
		iorlw	h'c0'			;表示位置指定  (２行目)
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力

		movlw	high bcd_hh_w		;時_BCD カウンタのアドレス（ワーク用）
		movwf	FSR0H			;
		lsrf	dsp_point,W		;1/2
		addlw	low bcd_hh_w		;時_BCD カウンタのアドレス
		movwf	FSR0L			;間接アドレスの先頭アドレスの設定

itdsp01		swapf	INDF0,W			;    上位４ビット
		btfsc	dsp_point,0		;今から表示するポイント = 偶数 か？
		moviw	FSR0++			;No. 下位４ビット

		andlw	h'0f'
		iorlw	h'30'
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		incf	dsp_point,F		;表示位置ポインタ + 1
		movlw	6
		subwf	dsp_point,W
		btfsc	STATUS,Z		;dsp_point = 6 か？
		goto	itdsp02			;Yes

		movlw	':'
		btfss	dsp_point,0		;次に表示するポイント = 偶数 か？
		call	xI2cLcd_Data		;Yes. I2C LCD へデータを１文字出力
		goto	itdsp01

itdsp02		return

;--------------------------------------------------------------------------

		; 表示位置テーブル（menu_no = 2:「ストップウオッチ（詳細）」で使用）
		;		  （menu_no = 3:「インターバル（間隔）タイマー」で使用）

dsp_point_table
		movf	dsp_point,W		;表示位置ポインタ
		brw

		;	0     1     2     3     4     5      ;  01 23 45  ... dsp_point
		;	"HH"  "HL"  "MH"  "ML"  "SH"  "SL"   ; "xx:xx:xx" ... 桁
		;					     ;  01234567
		dt	h'00',h'01',h'03',h'04',h'06',h'07'  ;            ... DDRAM のアドレス (１行目)

		;	                        6     7      ;        67  ... dsp_point
		;	                        "XH"  "XL"   ; "(StW) xx" ... 桁
		;					     ;  01234567
		dt	                        h'46',h'47'  ;            ... DDRAM のアドレス (２行目)

;
;==========================================================================
; menu_no = 3		インターバル（間隔）タイマー
;==========================================================================

;	[スイッチ操作]
;		                                               ENABLE   START/
;		Start                         ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   　┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│■│   │●│     │●│   │●│   │●│   │●│   │●│
;		└■┘   └─┘     └─┘   └─┘   └─┘   └─┘   └─┘
;		 Stop    CLEAR       EXIT     DOWN      UP      LEFT     RIGHT

;		トグルスイッチ = Start（LINE IN = "L"*）..... 動作スタート

;		トグルスイッチ = Stop （LINE IN = "H"*）..... 動作ストップ

;			*スタート信号 (RA4 入力) はインバータにより反転する

;		CLEAR スイッチ ..... 全桁 "00" にクリア表示

;		 LEFT スイッチ ..... ブリンク位置のポインタを - 1
;		RIGHT スイッチ ..... ブリンク位置のポインタを + 1

;		 DOWN スイッチ ..... ブリンク位置の値を - 1
;		   UP スイッチ ..... ブリンク位置の値を + 1

;		 EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				  bit7: 処理終了（エグジット）フラグ
;				  bit6: 例外終了（次処理に移行）フラグ
;				  bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				> bit4: タイムアウトフラグ
;				> bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				  bit2: 状態変化割り込み記憶フラグ
;				  bit1: スリープ中状態フラグ
;				  bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

;		bcd_hh_l, bcd_mm_l, bcd_ss_l ... EEPROM のバックアップ値

;		bcd_hh_s, bcd_mm_s, bcd_ss_s ... 設定値の記憶用

;		bcd_hh_w, bcd_mm_w, bcd_ss_w ... 設定値用（カウントダウンで値が常に変化する）

interval_timer

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		; 「インターバルタイマー」画面の表示

		;	[ ItvTimer ]		;本機能の略名を表示
		;	[ xx:xx:xx ]		;タイマー時間の設定値
		;	  01234567

		movlw	h'80'			;表示位置指定 (１行目先頭)
		; menu_no = 3
		call	xmenu_display		;メニュー項目の表示(１行目)
		call	read_itv_eeprom		;タイマー設定値を EEPROM から読み出し

itvtm01		movf	bcd_hh_s,W		;時_BCD カウンタ （前回の設定値を復帰）
		movwf	bcd_hh_w
		movf	bcd_mm_s,W		;分_BCD カウンタ
		movwf	bcd_mm_w
		movf	bcd_ss_s,W		;秒_BCD カウンタ
		movwf	bcd_ss_w
		bcf	stat2_flg,4		;タイムアウトフラグ = 0
		clrf	dsp_point		;

itvtm02		movf	dsp_point,W		;退避
		movwf	work1
		clrf	dsp_point		;"HH" 桁指定, 全桁 "00" 表示
		call	itv_time_display	;I2C LCD への "HH:MM:SS" 表示
		movf	work1,W
		movwf	dsp_point		;復帰

		; 各スイッチの入力チェック-1

itvtm03		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		call	dsp_point_table		;表示位置テーブル
		iorlw	h'c0'			;表示位置 (ブリンク位置)を指定 (２行目)
		call	xI2cLcd_Cmd		;LCD へコマンドを出力
		movlw	h'0d'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=1: ブリンク

itvtm04		btfss	PORTB,_swLEF		;LEFT スイッチ = ON か？
		call	itv_left_switch		;Yes

		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		call	itv_right_switch	;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	itvtm03			;Yes

		btfss	PORTB,_swDWN		;DOWN　スイッチ = ON か？
		call	itv_down_switch		;Yes

		btfss	PORTB,_swUP		;UP スイッチ = ON か？
		call	itv_up_switch		;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	itvtm02			;Yes

		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	itvtm08			;Yes

		; スタート信号の監視チェック

		btfss	PORTA,_Start		;スタート信号 = 'H' か？
		goto	itvtm04			;No

		; インターバルタイマーの処理

		movf	bcd_hh_w,W		;（今回の設定値をチェック）
		iorwf	bcd_mm_w,W
		iorwf	bcd_ss_w,W
		btfss	STATUS,Z		;各 BCD カウンタはすべて h'00' か？
		goto	itvtm05			;No. OK

		; エラー表示
		call	buzzer_bu_led		;"ブッ" アラーム音出力 (Total 130 mS) と LED(赤) 点滅
		goto	itvtm03

itvtm05		movf	bcd_hh_w,W		;時_BCD カウンタ （今回の設定値を記憶）
		movwf	bcd_hh_s
		movf	bcd_mm_w,W		;分_BCD カウンタ
		movwf	bcd_mm_s
		movf	bcd_ss_w,W		;秒_BCD カウンタ
		movwf	bcd_ss_s

		movlw	h'0c'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク
		call	time_control		;ストップウオッチ／タイマー共通処理

		bsf	PORTA,_ledG		;LED(緑) 点灯 (END 表示)
		movlp	high buzzer_po4
		call	buzzer_po4		;"ポッポッポッポッ" アラーム音出力
		movlp	high $

		; 各スイッチの入力チェック-2

itvtm06		btfsc	PORTA,_swCLR		;CLEAR スイッチ = ON か？
		goto	itvtm07			;No

		bcf	PORTA,_ledG		;LED(緑) 消灯
		call	xwait_15ms		;チャッタリング吸収
		btfss	PORTA,_swCLR		;CLEAR スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収
		goto	itvtm01

itvtm07		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	itvtm06			;No

		bcf	PORTA,_ledG		;LED(緑) 消灯

		; 「インターバルタイマー」の終了

itvtm08		movf	bcd_hh_s,W		;時_BCD カウンタ （直前の設定値を復帰）
		subwf	bcd_hh_l,W		;前回の EEPROM のバックアップ値
		btfss	STATUS,Z		;bcd_hh_s = bcd_hh_l か？
		goto	itvtm09			;No

		movf	bcd_mm_s,W		;分_BCD カウンタ
		subwf	bcd_mm_l,W
		btfss	STATUS,Z		;bcd_mm_s = bcd_mm_l か？
		goto	itvtm09			;No

		movf	bcd_ss_s,W		;秒_BCD カウンタ
		subwf	bcd_ss_l,W
		btfss	STATUS,Z		;bcd_ss_s = bcd_ss_l か？

itvtm09		call	write_itv_eeprom	;No. タイマー設定値を EEPROM へ書き込み

		call	xwait_15ms		;チャッタリング吸収
		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収
		movlp	high main
		goto	main

;--------------------------------------------------------------------------
;	  LEFT スイッチの処理 ...「インターバルタイマー」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 LEFT スイッチ ..... ブリンク位置のポインタを - 2

itv_left_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swLEF		;再度 LEFT スイッチ = ON か？
		goto	itlef01			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movlw	2
		subwf	dsp_point,F		;ブリンク位置ポインタ - 2
		addwf	dsp_point,W
		movlw	4
		btfsc	STATUS,Z		;dsp_point = -2(W=0) か？
		movwf	dsp_point		;Yes. dsp_point = 4 に設定

		btfss	PORTB,_swLEF		;LEFT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収

itlef01		return

;--------------------------------------------------------------------------
;	 RIGHT スイッチの処理 ...「インターバルタイマー」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		RIGHT スイッチ ..... ブリンク位置のポインタを + 2

itv_right_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swRIG		;再度 RIGHT スイッチ = ON か？
		goto	itrig01			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movlw	2
		addwf	dsp_point,F		;ブリンク位置ポインタ + 2
		movlw	6
		subwf	dsp_point,W		;dsp_point - 6
		btfsc	STATUS,C		;dsp_point < 6 か？
		clrf	dsp_point		;No. dsp_point = 0 に設定

		btfss	PORTB,_swRIG		;RIGHT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収

itrig01		return

;--------------------------------------------------------------------------
;	 DOWN スイッチの処理 ...「インターバルタイマー」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 DOWN スイッチ ..... ブリンク位置の値を - 1

itv_down_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	itdwn04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	dsp_point,W
		btfss	STATUS,Z		;dsp_point = 0 か？
		goto	itdwn01			;No

		movf	bcd_hh_w,W		;時_BCD カウンタ = h'00' ～ h'99'
		movwf	bcd_yy
		movlp	high bcd_yl_dec
		call	bcd_yl_dec		;年(下位2桁)_BCD カウンタのデクリメント で代用
		movlp	high $
		movf	bcd_yy,W
		movwf	bcd_hh_w		;時_BCD カウンタ
		goto	itdwn03

itdwn01		movlw	2
		subwf	dsp_point,W
		btfss	STATUS,Z		;dsp_point = 2 か？
		goto	itdwn02			;No

		movf	bcd_mm_w,W		;分_BCD カウンタ
		movwf	bcd_mm
		call	xbcd_mm_dec		;分_BCD カウンタのデクリメント
		movf	bcd_mm,W
		movwf	bcd_mm_w		;分_BCD カウンタ
		goto	itdwn03

itdwn02	;	movlw	4
	;	subwf	dsp_point,W
	;	btfss	STATUS,Z		;dsp_point = 4 か？
	;	goto	itdwn03			;No

		movf	bcd_ss_w,W		;秒_BCD カウンタ
		movwf	bcd_ss
		movlp	high bcd_ss_dec
		call	bcd_ss_dec		;秒_BCD カウンタのデクリメント
		movlp	high $
		movf	bcd_ss,W
		movwf	bcd_ss_w		;秒_BCD カウンタ
;		goto	itdwn03

itdwn03	;	btfss	PORTB,_swDWN		;DOWN スイッチ = OFF か？
	;	goto	$ - 1			;No

	;	call	xwait_15ms		;チャッタリング吸収
		call	xwait_200ms		;早送りの速度調整

itdwn04		return

;--------------------------------------------------------------------------
;	  UP スイッチの処理 ...「インターバルタイマー」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		   UP スイッチ ..... ブリンク位置の値を + 1

itv_up_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swUP		;再度 UP スイッチ = ON か？
		goto	itup04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	dsp_point,W
		btfss	STATUS,Z		;dsp_point = 0 か？
		goto	itup01			;No

		movf	bcd_hh_w,W		;時_BCD カウンタ = h'00' ～ h'99'
		movwf	bcd_yy
		movlp	high bcd_yl_inc
		call	bcd_yl_inc		;年(下位2桁)_BCD カウンタのインクリメント で代用
		movlp	high $
		movf	bcd_yy,W
		movwf	bcd_hh_w		;時_BCD カウンタ
		goto	itup03

itup01		movlw	2
		subwf	dsp_point,W
		btfss	STATUS,Z		;dsp_point = 2 か？
		goto	itup02			;No

		movf	bcd_mm_w,W		;分_BCD カウンタ
		movwf	bcd_mm
		call	xbcd_mm_inc		;分_BCD カウンタのインクリメント
		movf	bcd_mm,W
		movwf	bcd_mm_w		;分_BCD カウンタ
		goto	itup03

itup02	;	movlw	4
	;	subwf	dsp_point,W
	;	btfss	STATUS,Z		;dsp_point = 4 か？
	;	goto	itup03			;No

		movf	bcd_ss_w,W		;秒_BCD カウンタ
		movwf	bcd_ss
		movlp	high bcd_ss_inc
		call	bcd_ss_inc		;秒_BCD カウンタのインクリメント
		movlp	high $
		movf	bcd_ss,W
		movwf	bcd_ss_w		;秒_BCD カウンタ
;		goto	itup03

itup03	;	btfss	PORTB,_swUP		;UP スイッチ = OFF か？
	;	goto	$ - 1			;No

	;	call	xwait_15ms		;チャッタリング吸収
		call	xwait_200ms		;早送りの速度調整

itup04		return

;--------------------------------------------------------------------------
;		タイマー設定値を EEPROM へ書き込み
;--------------------------------------------------------------------------

write_itv_eeprom

		movlw	high bcd_hh_s		;時_BCD カウンタのアドレス
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	3			;書き込みバイト数
		movwf	lp_cnt1			;ループカウンタ1

		movlb	3			;バンク 3
		movlw	low itv_timer_memory
		movwf	EEADRL			;EEPROM の記録アドレスを設定
		bcf	EECON1,CFGS		;フラッシュプログラム/データ EEPROM メモリを選択
		bcf	EECON1,EEPGD		;データ EEPROM メモリにアクセス

writv01		movlb	3			;バンク 3
		moviw	FSR0++			;BCD カウンタデータの読み出し
		movwf	EEDATL			;書き込みデータを設定

		bsf	EECON1,WREN		;プログラム/消去サイクルを許可
	;	bcf	INTCON,GIE		;割り込みを禁止
		movlw	h'55'
		movwf	EECON2			;h'55' を EECON2 に書き込む
		movlw	h'aa'
		movwf	EECON2			;h'aa' を EECON2 に書き込む

		bsf	EECON1,WR		;書き込み開始
	;	bsf	INTCON,GIE		;割り込みを許可
		bcf	EECON1,WREN		;プログラム/消去サイクルを禁止
		btfsc	EECON1,WR		;書き込み 終了か?
		goto	$ - 1			;No

		incf	EEADRL,F		;記録アドレスの更新

		movlb	0			;バンク 0
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	writv01			;No

		return

;--------------------------------------------------------------------------
;		タイマー設定値を EEPROM から読み出し
;--------------------------------------------------------------------------

read_itv_eeprom

		movlw	high bcd_hh_s		;時_BCD カウンタのアドレス
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	high bcd_hh_l		;時_BCD カウンタのアドレス（記憶用）
		movwf	FSR1H			;
		movlw	low bcd_hh_l		;
		movwf	FSR1L			;間接アドレスに設定

		movlw	3			;読み出しバイト数
		movwf	lp_cnt1			;ループカウンタ1

		movlb	3			;バンク 3
		movlw	low itv_timer_memory
		movwf	EEADRL			;EEPROM の記録アドレスを設定
		bcf	EECON1,CFGS		;フラッシュプログラム/データ EEPROM メモリを選択
		bcf	EECON1,EEPGD		;データ EEPROM メモリにアクセス

rditv01		movlb	3			;バンク 3
		bsf	EECON1,RD		;読み出し制御 = ON
		movf	EEDATL,W		;データの読み出し
		movwi	FSR0++			;BCD カウンタデータへ書き込み
		movwi	FSR1++			;BCD カウンタデータへ書き込み（記憶用）
		incf	EEADRL,F		;記録アドレスの更新

		movlb	0			;バンク 0
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	rditv01			;No

		return

;
;==========================================================================
; menu_no = 4		ストップウオッチ（長時間）
;==========================================================================

;	     （スプリットタイムのカウントが [ 00:00:00 ] から開始される）
;	        ↓
;
;	│      |                                                   |      |
;	│      |←-----------------------------------------SPLITn→|      |   ;スプリット（SPLIT）タイム
;	│      |←------------------------SPLITn-1→|              |      |   ;スタートしてからゴールまでの途中経過時間
;	│      |                                    |              |      |
;	│      |←-------------------SPLIT2→|      |              |      |
;	│      |←----SPLIT1→|              |      |              |      |   ;ラップ（LAP）タイム
;	│      |              |              |      |              |      |   ;スタートからゴールまでの区間経過時間
;	│      |←---LAP1---→|←---LAP2---→|------|←---LAPn---→|      |
;	│      |              |              |      |              |      |
;	│─--─|───────|───────|─--─|───────|─--─|
;
;	↑-----(1)            (1)            (1)----(1)            (2)----(3)（「記録内容の表示」に移行）
;	│     START                                              GOAL    (4)（「メニューの選択」に戻る）
;	│
;     （「メニューの選択」から「ストップウオッチ」に移行）                                        

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │○│   │○│   │●│   │●│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;	    (1)        ENABLE スイッチ +
;		        START スイッチ ..... （通常のちょん押し） START / SPLIT(LAP)

;	    (2) ENABLE スイッチ 長押し +
;		 START スイッチ 長押し ..... （３秒以上の長押し） GOAL

;	    (3)        ENABLE スイッチ +
;		         EXIT スイッチ ..... 「記録内容の表示」に移行

;	    (4)          EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				> bit5: ラップタイム表示済みフラグ
;				> bit4: ラップタイム表示指示フラグ
;				> bit3: ストップウオッチ動作終了フラグ
;				> bit2: ストップウオッチ動作中フラグ
;				> bit1: 経過時間更新フラグ
;				> bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				> bit7: 処理終了（エグジット）フラグ
;				> bit6: 例外終了（次処理に移行）フラグ
;				  bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				  bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				> bit2: 状態変化割り込み記憶フラグ
;				> bit1: スリープ中状態フラグ
;				> bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

long_stopwatch

		call	xclock_rtc_read		;RTC DS3231 から年月日、時分秒を読み出し
		bsf	INTCON,INTE		;INT 外部割り込み許可 = 1

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)
						;スリープ移行時間カウンタの初期設定
		movf	menu_4,W		;menu_4 分カウンタ
		call	mul8x8_16		;8 x 8 ビット = 16 ビットの乗算

		;	[ LngStopW ]		;本機能の略名を表示
		;	[ xx:xx:xx ]		;現在時刻 "HH:MM:SS" を刻々と刻みながら表示
		;	  01234567

stwlg01		movlw	h'80'			;表示位置指定 (１行目先頭)
		; menu_no = 4
		call	xmenu_display		;メニュー項目の表示(１行目)
		goto	stwlg04

stwlg02		btfsc	stat_flg,4		;ラップタイム表示指示フラグ = 1 か？
		goto	stwlg05			;Yes

		btfss	stat_flg,3		;ストップウオッチ動作終了フラグ = 1 か？
		goto	stwlg03			;No

		btfss	stat_flg,2		;ストップウオッチ動作中フラグ = 1 か？
		goto	stwlg04			;No

		;	[ StpW End ]		;ストップウオッチの動作が終了した
		;     ( [ xx:xx:xx ]		;時刻表示 )
		;	  01234567

		xDisp_I2cLcd	h'80',long_end_msg,1	;表示位置指定 (１行目)

		bcf	stat_flg,2		;ストップウオッチ動作中フラグ = 0
		bsf	stat_flg,0		;現在時刻更新フラグ = 1
		goto	stwlg04

		; 経過時間（スプリットタイム）の表示 (１行目)

stwlg03		btfss	stat_flg,1		;経過時間更新フラグ = 1 か？
		goto	stwlg04			;No

		movlw	high bcd_hh_s		;時_BCD カウンタの番地（スプリット: 経過時間用）
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	h'80'			;表示位置指定 (１行目先頭)
		call	time_display		;I2C LCD への "HH:MM:SS" 表示
		bcf	stat_flg,1		;経過時間更新フラグ = 0

		; 現在時刻の表示 (２行目)

stwlg04		btfss	stat_flg,0		;現在時刻更新フラグ = 1 か？
		goto	stwlg08			;No

		movlw	high bcd_hh		;時_BCD カウンタの番地（現在時刻用）
		movwf	FSR0H			;
		movlw	low bcd_hh		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	h'c0'			;表示位置指定 (２行目先頭)
		call	time_display		;I2C LCD への "HH:MM:SS" 表示
		bcf	stat_flg,0		;現在時刻更新フラグ = 0

		call	alarm_sound		;時報音、タイマー一致音のアラーム出力
		goto	stwlg08

		; スプリット／ラップ番号の表示 (１行目)

stwlg05		btfsc	stat_flg,5		;ラップタイム表示済みフラグ = 1 か？
		goto	stwlg08			;Yes

		;	[ ** xx ** ]		;スプリット記録番号 xx を表示
		;	  01234567

		call	split_no_disp		;スプリット／ラップ番号の表示

		; 区間経過時間（ラップタイム）の表示 (２行目)

		decfsz	split_cnt,W		;スプリット番号カウンタ - 1 = 0 か？
		goto	stwlg06			;No

		movlw	high bcd_hh_s		;今回 時_BCD カウンタ（スプリット: 経過時間用）
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定
		goto	stwlg07

stwlg06		decf	split_cnt,F		;前回スプリット番号を指定
		call	read_split_memory	;前回スプリットタイムの読み出し
		incf	split_cnt,F		;今回スプリット番号に復帰

		call	lap_time_calc		;ラップタイムの計算

		movlw	high bcd_hh_l		;時_BCD カウンタの番地（ラップ: 区間経過時間用）
		movwf	FSR0H			;
		movlw	low bcd_hh_l		;
		movwf	FSR0L			;間接アドレスに設定

stwlg07		movlw	h'c0'			;表示位置指定 (２行目先頭)
		call	time_display		;I2C LCD への "HH:MM:SS" 表示
		bsf	stat_flg,5		;ラップタイム表示済みフラグ = 1

		; 各スイッチの入力チェック

stwlg08		btfsc	PORTB,_swSTA		;START スイッチ = ON か？
		goto	stwlg09			;No

		call	start_switch		;START/GOAL スイッチの処理

		btfsc	stat_flg,4		;ラップタイム表示指示フラグ = 1 か？
		goto	stwlg05			;Yes

		btfsc	stat_flg,3		;ストップウオッチ動作終了フラグ = 1 か？
		goto	stwlg02			;Yes

stwlg09		btfss	PORTB,_swEN		;ENABLE スイッチ = ON か？
		bsf	stat_flg,6		;Yes. スイッチ入力有りフラグ = 1

		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	stwlg10			;No

		movlp	high clk_exit_switch
		call	clk_exit_switch		;EXIT スイッチの処理 (Page 0)
		movlp	high $

		movlw	h'c0'
		andwf	stat2_flg,W
		btfss	STATUS,Z		;処理終了フラグ or 例外終了フラグ = 1 か？
		goto	stwlg13			;Yes
						;No （になることはない！ はず）

stwlg10		btfss	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	stwlg11			;No

		call	xwait_15ms		;チャッタリング吸収
		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
						;スリープ移行時間カウンタの初期設定
		movf	menu_4,W		;menu_4 分カウンタ
		call	mul8x8_16		;8 x 8 ビット = 16 ビットの乗算
		goto	stwlg02

		; スリープ移行時間の監視（60 x 1 秒）

stwlg11		call	sleep_mode		;時間の監視とスリープモードに移行
		btfss	stat2_flg,1		;スリープ中状態フラグ = 1 か？
		goto	stwlg02			;No

		bcf	stat2_flg,1		;スリープ中状態フラグ = 0
		bsf	stat_flg,0		;現在時刻更新フラグ = 1

		; ウェイクアップ後のジャンプ先振り分け

		btfsc	stat_flg,3		;ストップウオッチ動作終了フラグ = 1 か？
		goto	stwlg12			;Yes

		btfss	stat_flg,2		;ストップウオッチ動作中フラグ = 1 か？
		goto	stwlg01			;No. (動作開始メッセージ)

		bsf	stat_flg,1		;経過時間更新フラグ = 1
		goto	stwlg02			;(動作中)

stwlg12		bsf	stat_flg,2		;ストップウオッチ動作中フラグ = 1
		goto	stwlg02			;(動作終了メッセージ)

		; 「ストップウオッチ（長時間）」の終了

stwlg13		bcf	INTCON,INTE		;INT 外部割り込み許可 = 0
		btfss	stat2_flg,6		;例外終了フラグ = 1 か？
		goto	stwlg14			;No

		clrf	stat2_flg		;進行状態-2フラグの初期設定
		movlw	5
		movwf	menu_no			;メニュー番号 = 5 設定
		goto	memory_display		;「記録内容の表示」に移行

stwlg14		movlp	high main
		goto	main			;「メニューの選択」に戻る

;--------------------------------------------------------------------------
;    （スプリット: 経過時間用）秒、分、時_BCD カウンタのインクリメント
;--------------------------------------------------------------------------

ssmmhh_inc
		movlw	high bcd_ss_s		;（経過時間用）秒_BCD カウンタ
		movwf	FSR0H			;
		movlw	low bcd_ss_s		;
		movwf	FSR0L			;間接アドレスに設定

		call	xinc_bcd		;秒 bcd_ss BCDインクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		movlw	h'60'
		subwf	INDF0,W
		btfss	STATUS,C		;bcd_ss >= h'60' か？
		return				;No

		clrf	INDF0			;bcd_ss = h'00'
		addfsr	FSR0,-1			;間接アドレス - 1
		call	xinc_bcd		;分 bcd_mm BCDインクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		movlw	h'60'
		subwf	INDF0,W
		btfss	STATUS,C		;bcd_mm >= h'60' か？
		return				;No

		clrf	INDF0			;bcd_mm = h'00'
		addfsr	FSR0,-1			;間接アドレス - 1
		call	xinc_bcd		;時 bcd_hh BCDインクリメント
		btfss	STATUS,Z		;桁上がり指定 = 1 (あり) か？
		return				;No

		movlw	h'a0'
		subwf	INDF0,W
		btfss	STATUS,C		;bcd_hh >= h'a0' か？
		return				;No

		clrf	INDF0			;bcd_hh = h'00'
		return

;--------------------------------------------------------------------------
;		I2C LCD への "HH:MM:SS" 表示
;--------------------------------------------------------------------------

;  (例)		movlw	high bcd_hh		;時_BCD カウンタの番地
;		movwf	FSR0H			;
;		movlw	low bcd_hh		;
;		movwf	FSR0L			;間接アドレスに設定
;		movlw	h'c0'			;表示位置指定 (２行目)

time_display
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力

		movlw	3
		movwf	lp_cnt2			;ループカウンタ2

tdisp01		swapf	INDF0,W			;上位4ビット
		andlw	h'0f'
		iorlw	h'30'			;数字に変換
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		moviw	FSR0++			;下位4ビット
		andlw	h'0f'
		iorlw	h'30'			;数字に変換
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		decf	lp_cnt2,W
		btfsc	STATUS,Z		;ループカウンタ2 - 1 = 0 か？
		goto	tdisp02			;Yes

		movlw	':'
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

tdisp02		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	tdisp01			;No

		return

;--------------------------------------------------------------------------
;		スプリット／ラップ番号の表示
;--------------------------------------------------------------------------

split_no_dispx
		movlw	h'01'			;クリアディスプレイ
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力
		call	xwait_1ms		;1m 秒 ウェイト
		call	xwait_100us		;100μ秒 ウェイト

split_no_disp
		;	[ ** xx ** ]		;１行目 ... 番号テンプレート出力
		;	  01234567

		xDisp_I2cLcd	h'80',number_msg,1	;表示位置指定 (１行目)

		movlw	h'83'			;表示位置指定 
		call	xI2cLcd_Cmd		;I2C LCD へコマンドを出力

		movf	split_cnt,W		;スプリット番号カウンタ
dec2chr_disp
		call	bin8_dec2chr		;２桁の数字に変換
		movf	chr_wk2,W
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		movf	chr_wk1,W
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		return

;--------------------------------------------------------------------------

		; ８ビット（１バイト）数値を１０進数２桁の数字文字列に変換
bin8_dec2chr
		movwf	work1			;変換する値
		movlw	high (chr_wk1 + 1)	;
		movwf	FSR0H			;
		movlw	low (chr_wk1 + 1)	;
		movwf	FSR0L			;間接アドレスに設定

		call	dev_10			;最下位変換
		call	dev_10
;		call	dev_10			;最上位変換（本来は３桁（255まで）に変換）
		return

		; １０で除算
dev_10
		movlw	8
		movwf	lp_cnt2			;ループカウンタ
		clrf	work2			;余りの初期値

dev01		lslf	work1,F
		rlf	work2,F
		movlw	-10			;h'f6'
		addwf	work2,W
		btfsc	STATUS,C
		movwf	work2
		btfsc	STATUS,C
		incf	work1,F
		decfsz	lp_cnt2,F		;ループカウンタ - 1 = 0 か？
		goto	dev01			;No

		movf	work2,W			;余り
		iorlw	h'30'			;数字に変換
		movwi	--FSR0
		return

;--------------------------------------------------------------------------
;	START/GOAL スイッチの処理 ...「ストップウオッチ」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;	    (1)        ENABLE スイッチ +
;		        START スイッチ ..... （通常のちょん押し） START / SPLIT(LAP)

;	    (2) ENABLE スイッチ 長押し +
;		 START スイッチ 長押し ..... （３秒以上の長押し） GOAL

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				> bit5: ラップタイム表示済みフラグ
;				> bit4: ラップタイム表示指示フラグ
;				> bit3: ストップウオッチ動作終了フラグ
;				> bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

start_switch
		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swSTA		;再度 START スイッチ = ON か？
		goto	stasw06			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		btfsc	PORTB,_swEN		;ENABLE スイッチ = ON か？
		goto	stasw05			;No

		btfsc	stat_flg,3		;ストップウオッチ動作終了フラグ = 1 か？
		goto	stasw05			;Yes

		btfsc	stat_flg,2		;ストップウオッチ動作中フラグ = 1 か？
		goto	stasw01			;Yes

		; ストップウオッチ動作の開始

		;	[ 00:00:00 ]		;１行目 ... スプリットタイムの初期値を表示
		;	[ xx:xx:xx ]
		;	  01234567

		clrf	bcd_hh_s		;時_BCD カウンタ (経過時間用)
		clrf	bcd_mm_s		;分_BCD カウンタ
		clrf	bcd_ss_s		;秒_BCD カウンタ

		movlw	high bcd_hh_s		;時_BCD カウンタの番地（スプリット: 経過時間用）
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定
		movlw	h'80'			;表示位置指定 (１行目先頭)
		call	time_display		;I2C LCD への "HH:MM:SS" 表示

		clrf	split_cnt		;スプリット番号カウンタの初期設定
		bsf	stat_flg,2		;ストップウオッチ動作中フラグ = 1

		movlp	high dl_mi_so_dh	;ストップウオッチ動作の開始音
		call	dl_mi_so_dh		;"ドーミーソードー" アラーム音出力と LED(緑)(赤)交互点滅 (Total 1150 mS)
		movlp	high $

		btfss	PORTB,_swSTA		;START スイッチ = OFF か？
		goto	$ - 1			;No
		goto	stasw05			;開始時は長押し時間監視とメモリ書き込みをしない

		; 経過時間（スプリットタイム）をメモリ書き込み

stasw01		call	write_split_memory	;経過時間（スプリットタイム）を書き込み

		clrf	hold_cnt		;				   64ms x 47 = 3,008 mS = 3 秒間の監視
		incf	hold_cnt,F		;長押し監視カウンタ = 1 始まり
		movlw	256 - 250		;(4/4MHz) * 250 * 256(Prescaler) = 64000μS = 64 mS
		movwf	TMR0		
		bsf	INTCON,TMR0IE		;TMR0 オーバーフロー割り込み許可 = 1

		; メモリ書き込み報告

		; "ポッポッ" アラーム音出力 (Total 260 mS) と LED(緑) 点滅
		call	memory_complete		;メモリ書き込み報告

		movlw	split_capacity		;スプリットタイムの記憶容量の最大値
		subwf	split_cnt,W		;スプリット番号カウンタ - split_capacity
		btfss	STATUS,C		;メモリ満タンになった か？
		goto	stasw02			;No

		; メモリ満タンメッセージの表示 (２行目)

		bcf	INTCON,TMR0IE	 	;TMR0 オーバーフロー割り込み許可 = 0
		bsf	stat_flg,3		;ストップウオッチ動作終了フラグ = 1
	;;	bcf	stat_flg,2		;ストップウオッチ動作中フラグ = 0

		;	[ xx:xx:xx ]
		;	[ Mem Full ]		;２行目 ... メモリ満タンメッセージ
		;	  01234567

		; "ブッブッブッブッ" アラーム音出力 (Total 520 mS) と LED(赤) 点滅
		call	memory_full		;メモリ満タンメッセージ
		goto	stasw03

		; START スイッチの長押し時間監視

stasw02		btfsc	stat_flg,3		;ストップウオッチ動作終了フラグ = 1 か？
		goto	stasw04			;Yes

		btfsc	INTCON,TMR0IE		;TMR0 オーバーフロー割り込み許可 = 0 か？
;	      ( "TMR0 オーバーフロー割り込み処理" 内で 64ms x 47 = 3,008 mS = 3 秒間の監視後に TMR0IE = 0 にされる )
		goto	stasw04			;No

		; 3 秒間の経過で GOAL した
		bsf	stat_flg,3		;ストップウオッチ動作終了フラグ = 1
	;;	bcf	stat_flg,2		;ストップウオッチ動作中フラグ = 0

stasw03		movlp	high dh_so_mi_dl	;ストップウオッチ動作の終了音
		call	dh_so_mi_dl		;"ドーソーミードー" アラーム音出力と LED(緑)(赤)交互点滅 (Total 1150 mS)
		movlp	high $

stasw04		btfss	PORTB,_swSTA		;START スイッチ = OFF か？
		goto	stasw02			;No

		btfsc	INTCON,TMR0IE		;TMR0 オーバーフロー割り込み許可 = 1 か？
;	      ( 3 秒間の監視内に START スイッチ を OFF にしたとき )

		bcf	INTCON,TMR0IE	 	;TMR0 オーバーフロー割り込み許可 = 0

		bsf	stat_flg,4		;ラップタイム表示指示フラグ = 1
		bcf	stat_flg,5		;ラップタイム表示済みフラグ = 0
		movlw	5			;（約 5 秒）
		movwf	laptim_cnt		;ラップタイム表示時間カウンタの初期設定

stasw05		call	xwait_15ms		;チャッタリング吸収

stasw06		return

;--------------------------------------------------------------------------

		; メモリ書き込み報告

memory_complete
		call	buzzer_po_led		;"ポッポッ" アラーム音出力 (Total 260 mS)

buzzer_po_led
		movlp	high buzzer_po
		call	buzzer_po		;"ポッ" アラーム音出力 (Total 130 mS)
		movlp	high $
		bsf	PORTA,_ledG		;LED(緑) 点灯
		call	xwait_30ms
		bcf	PORTA,_ledG		;LED(緑) 消灯
		return

;--------------------------------------------------------------------------

		; メモリ満タンメッセージの表示 (２行目)

		;	[ xx:xx:xx ]
		;	[ Mem Full ]		;２行目 ... メモリ満タンメッセージ
		;	  01234567

memory_full
		xDisp_I2cLcd	h'c0',mem_full_msg,1	;２行目表示

		movlw	4			;"ブッブッブッブッ" アラーム音出力 (Total 520 mS)
		movwf	lp_cnt1			;アラーム音の出力回数

mmful01		call	buzzer_bu_led		;"ブッ" アラーム音出力 (130 mS)
		decfsz	lp_cnt1,F		;アラーム音の出力回数 = 終了 か？
		goto	mmful01			;No

		call	xwait_1sec		; 2.5 秒 ウェイトルーチン
		call	xwait_1sec
		movlp	high wait_500ms
		call	wait_500ms
		movlp	high $
		return

buzzer_bu_led
		movlp	high buzzer_bu
		call	buzzer_bu		;"ブッ" アラーム音出力 (100 mS)
		movlp	high $
		bsf	PORTA,_ledR		;LED(赤) 点灯
		call	xwait_30ms
		bcf	PORTA,_ledR		;LED(赤) 消灯
		return

;--------------------------------------------------------------------------
;		経過時間（スプリットタイム）を書き込み
;--------------------------------------------------------------------------

write_split_memory

		movlw	high split_memory	;スプリット用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low split_memory	;
		movwf	FSR1L			;

		movf	split_cnt,W
		btfsc	STATUS,Z		;スプリット番号カウンタ = 0 か？
		goto	wrmem02			;Yes

		movwf	lp_cnt2			;ループカウンタ2

wrmem01		addfsr	FSR1,3			;
		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	wrmem01			;No

wrmem02		movf	bcd_hh_s,W		;
		movwi	FSR1++			;時_BCD カウンタ 書き込み

		movf	bcd_mm_s,W		;
		movwi	FSR1++			;分_BCD カウンタ 書き込み

		movf	bcd_ss_s,W		;
		movwi	FSR1++			;秒_BCD カウンタ 書き込み

		incf	split_cnt,F		;スプリット番号カウンタ + 1
		return

;--------------------------------------------------------------------------
;		経過時間（スプリットタイム）を読み出し
;--------------------------------------------------------------------------

read_split_memory

		movlw	high split_memory	;スプリット用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low split_memory	;
		movwf	FSR1L			;

		decf	split_cnt,W
		btfsc	STATUS,Z		;スプリット番号カウンタ - 1 = 0 か？
		goto	rdmem02			;Yes

		movwf	lp_cnt2			;ループカウンタ2

rdmem01		addfsr	FSR1,3			;
		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	rdmem01			;No

rdmem02		moviw	FSR1++			;
		movwf	bcd_hh_w		;時_BCD カウンタ 読み出し

		moviw	FSR1++			;
		movwf	bcd_mm_w		;分_BCD カウンタ 読み出し

		moviw	FSR1++			;
		movwf	bcd_ss_w		;秒_BCD カウンタ 読み出し

		return

;--------------------------------------------------------------------------
;    区間経過時間（ラップタイム bcd_xx_l = bcd_xx_s - bcd_xx_w）の計算
;--------------------------------------------------------------------------

;	 入力： bcd_ss_s, bcd_mm_s, bcd_hh_s ...  今回のスプリットタイム
;		bcd_ss_w, bcd_mm_w, bcd_hh_w ...  前回のスプリットタイム
;	 出力： bcd_ss_l, bcd_mm_l, bcd_hh_l ...（今回の）  ラップタイム

;      （もっと簡潔な方法があるかもしれないが、とりあえず次の方法で計算）

lap_time_calc

		; bcd_ss_s (今回 秒_BCD カウンタ) - bcd_ss_w (前回 秒_BCD カウンタ)

		movf	bcd_ss_s,W		;今回の下位4ビット
		andlw	h'0f'
		movwf	work1
		movf	bcd_ss_w,W		;前回の下位4ビット
		andlw	h'0f'

		subwf	work1,F			;(1)
		btfsc	STATUS,C		;work1 >= 0 か?
		goto	laptim01		;Yes. C bit = 1

		movlw	h'0a'
		addwf	work1,F			;補正
		bcf	STATUS,C		;(1) の C bit = 0 引継ぎ

laptim01	movf	work1,W
		movwf	bcd_ss_l		;ラップタイム 秒_BCD 下位4ビット
;
		swapf	bcd_ss_s,W		;今回の上位4ビット
		andlw	h'0f'
		movwf	work1
		swapf	bcd_ss_w,W		;前回の上位4ビット
		andlw	h'0f'
		btfss	STATUS,C		;(1) の結果: C bit = 0 か?
		addlw	1			;Yes

		subwf	work1,F			;(2)
		btfsc	STATUS,C		;work1 >= 0 か?
		goto	laptim02		;Yes. C bit = 1

		movlw	h'06'
		addwf	work1,F			;補正
		bcf	STATUS,C		;(2) の C bit = 0 引継ぎ

laptim02	swapf	work1,W
		iorwf	bcd_ss_l,F		;ラップタイム 秒_BCD 上位4ビット

		; bcd_mm_s (今回 分_BCD カウンタ) - bcd_mm_w (前回 分_BCD カウンタ)

		movf	bcd_mm_s,W		;今回の下位4ビット
		andlw	h'0f'
		movwf	work1
		movf	bcd_mm_w,W		;前回の下位4ビット
		andlw	h'0f'
		btfss	STATUS,C		;(2) の結果: C bit = 0 か?
		addlw	1			;Yes

		subwf	work1,F			;(3)
		btfsc	STATUS,C		;work1 >= 0 か?
		goto	laptim03		;Yes. C bit = 1

		movlw	h'0a'
		addwf	work1,F			;補正
		bcf	STATUS,C		;(3) の C bit = 0 引継ぎ

laptim03	movf	work1,W
		movwf	bcd_mm_l		;ラップタイム 分_BCD 下位4ビット
;
		swapf	bcd_mm_s,W		;今回の上位4ビット
		andlw	h'0f'
		movwf	work1
		swapf	bcd_mm_w,W		;前回の上位4ビット
		andlw	h'0f'
		btfss	STATUS,C		;(3) の結果: C bit = 0 か?
		addlw	1			;Yes

		subwf	work1,F			;(4)
		btfsc	STATUS,C		;work1 >= 0 か?
		goto	laptim04		;Yes. C bit = 1

		movlw	h'06'
		addwf	work1,F			;補正
		bcf	STATUS,C		;(4) の C bit = 0 引継ぎ

laptim04	swapf	work1,W
		iorwf	bcd_mm_l,F		;ラップタイム 分_BCD 上位4ビット

		; bcd_hh_s (今回 時_BCD カウンタ) - bcd_hh_w (前回 時_BCD カウンタ)

		movf	bcd_hh_s,W		;今回の下位4ビット
		andlw	h'0f'
		movwf	work1
		movf	bcd_hh_w,W		;前回の下位4ビット
		andlw	h'0f'
		btfss	STATUS,C		;(4) の結果: C bit = 0 か?
		addlw	1			;Yes

		subwf	work1,F			;(5)
		btfsc	STATUS,C		;work1 >= 0 か?
		goto	laptim05		;Yes. C bit = 1

		movlw	h'0a'
		btfsc	bcd_hh_s,5		;上位4ビット = 2 か?
		movlw	h'04'			;Yes
		addwf	work1,F			;補正
		bcf	STATUS,C		;(5) の C bit = 0 引継ぎ

laptim05	movf	work1,W
		movwf	bcd_hh_l		;ラップタイム 時_BCD 下位4ビット
;
		swapf	bcd_hh_s,W		;今回の上位4ビット
		andlw	h'0f'
		movwf	work1
		swapf	bcd_hh_w,W		;前回の上位4ビット
		andlw	h'0f'
		btfss	STATUS,C		;(5) の結果: C bit = 0 か?
		addlw	1			;Yes

		subwf	work1,F			;(6)
		btfsc	STATUS,C		;work1 >= 0 か?
		goto	laptim06		;Yes. C bit = 1

		movlw	h'03'
		addwf	work1,F			;補正
;		bcf	STATUS,C		;(6) の C bit = 0 引継ぎ

laptim06	swapf	work1,W
		iorwf	bcd_hh_l,F		;ラップタイム 時_BCD 上位4ビット
		return

;--------------------------------------------------------------------------

;   （参考）	;	 10	0000.1010
		;	  9	0000.1001
		;	  8	0000.1000
		;	  7	0000.0111
		;	  6	0000.0110
		;	  5	0000.0101
		;	  4	0000.0100
		;	  3	0000.0011
		;	  2	0000.0010
		;	  1 	0000.0001
		;	  0	0000.0000
		;	 -1	1111.1111
		;	 -2	1111.1110
		;	 -3	1111.1101
		;	 -4	1111.1100
		;	 -5	1111.1011
		;	 -6	1111.1010
		;	 -7	1111.1001
		;	 -8	1111.1000
		;	 -9	1111.0111
		;	-10	1111.0110

;--------------------------------------------------------------------------
;		スリープモードに移行とウェイクアップ
;--------------------------------------------------------------------------

sleep_mode

		btfss	stat2_flg,0		;スリープ移行時間チェックフラグ = 1 か？
		goto	sleep08			;No

		bcf	stat2_flg,0		;スリープ移行時間チェックフラグ = 0

		movf	slp_cnt_h,W
		btfss	STATUS,Z		;slp_cnt_h = 0 か？
		goto	sleep08			;No

		movlw	3 + 1
		subwf	slp_cnt_l,W		;
		btfsc	STATUS,C		;スリープ移行までの時間 < 3 + 1 か？
		goto	sleep08			;No

		movf	slp_cnt_l,W		;
		btfsc	STATUS,Z		;slp_cnt_l = 0 か？
		goto	sleep01			;Yes

		bsf	PORTA,_ledG		;LED(緑) 点灯
		movlp	high buzzer_bu
		call	buzzer_bu		;"ブッ" アラーム音出力 (100 mS)
		movlp	high $
		bcf	PORTA,_ledG		;LED(緑) 消灯
		goto	sleep08

		; スリープモードに移行準備

sleep01
	movlw	h'01'		;;;;;（仮）	;表示クリア（要 1.08 mS 以上のウエイト）
	call	xI2cLcd_Cmd	;;;;;（仮）	;I2C LCD へコマンドを出力

		bsf	PORTA,_ledG		;LED(緑) 点灯
		movlp	high buzzer_bubuu
		call	buzzer_bubuu		;"ブッブー" アラーム音出力 (450 mS)
		movlp	high $
		bcf	PORTA,_ledG		;LED(緑) 消灯

		bsf	PORTA,_PWcntl		;LCD 電源 OFF
		bsf	stat2_flg,1		;スリープ中状態フラグ = 1
		clrf	slp_cnt_l		;スリープ時間カウンタの初期設定

		decf	menu_no,W
		movlw	b'01101100'		;RB6-RB5,RB3-RB2
		btfss	STATUS,Z		;メニュー番号 = 1「現在時刻の表示」か？
		movlw	b'11100000'		;No. RB7-RB5
		movlb	7			;バンク 7
		movwf	IOCBN			;ポートB の立ち下がりエッジ状態変化割り込み
		clrf	IOCBF			;状態変化割り込みフラグをクリア
		movlb	0			;バンク 0
		bcf	INTCON,IOCIF		;状態変化割り込みフラグ = 0 ...（必須）
		bsf	INTCON,IOCIE		;状態変化割り込み許可 = 1

sleep02		sleep				;スリープモード
		; 
		;				;wake up
		btfsc	stat2_flg,2		;状態変化割り込み記憶フラグ = 1 か？
		goto	sleep04			;Yes

		; INT 外部割り込みのとき

		call	alarm_sound		;時報音、タイマー一致音のアラーム出力
		btfss	alm_flg,6		;アラーム音出力済みフラグ = 1 か？
		goto	sleep03			;No

		clrf	slp_cnt_l		;            アラーム音出力時は以下を省略して
		goto	sleep02			;再度 sleep. １分カウントを新たにし直す

sleep03		movf	slp_cnt_l,W		;スリープ移行時間カウンタを別目的で使用
		movlw	61
		btfsc	STATUS,Z		;スリープ時間カウンタ = 0 か？
		movwf	slp_cnt_l		;Yes. スリープ時間カウンタ = 61 設定

		decf	slp_cnt_l,F		;スリープ時間カウンタ - 1
		btfss	STATUS,Z		;スリープ時間カウンタ = 0 か？
		goto	sleep02			;No. 再度 sleep

						;スリープ中は１分間隔で以下の動作をする
		bsf	PORTA,_ledR		;LED(赤) 点灯
		movlp	high buzzer_pi
		call	buzzer_pi		;"ピッ" アラーム音出力 (100 mS)
		movlp	high $
		bcf	PORTA,_ledR		;LED(赤) 消灯
		goto	sleep02			;再度 sleep

		; 状態変化割り込みのとき

sleep04		bcf	PORTA,_PWcntl		;LCD 電源 ON
		movlp	high I2cLcd_Init
		call	I2cLcd_Init		;I2C LCD (AQM0802A) の初期設定
		movlp	high $

		call	xbuzzer_pipi		;"ピッピッ" アラーム音出力 (230 mS)と LED(緑)点滅
		bcf	stat2_flg,2		;状態変化割り込み記憶フラグ = 0
	;;	bcf	stat2_flg,1		;スリープ中状態フラグ = 0

		; スリープ移行時間カウンタの初期設定

		movlw	4
		subwf	menu_no,W
		btfsc	STATUS,C		;menu_no < 4 か？
		goto	sleep05			;No

		movf	menu_1,W		;menu_1 分カウンタ
		goto	sleep07

sleep05		btfss	STATUS,Z		;menu_no = 4 か？
		goto	sleep06			;No

		movf	menu_4,W		;menu_4 分カウンタ
		goto	sleep07

sleep06		movf	menu_5,W		;menu_5 分カウンタ

sleep07		call	mul8x8_16		;8 x 8 ビット = 16 ビットの乗算

sleep08		return

;--------------------------------------------------------------------------
;		8 x 8 ビット = 16 ビットの乗算
;--------------------------------------------------------------------------

;			W reg		;乗数

;		変数:	slp_cnt_h	;結果（上位）
;			slp_cnt_l	;結果（下位）

mul8x8_16
		movwf	slp_cnt_l		;乗数を代入
		clrf	slp_cnt_h		;クリア

		movlw	8
		movwf	lp_cnt1			;ループカウンタ

mul8x01		bcf	STATUS,C		;キャリフラグのクリア		
		btfss	slp_cnt_l,0	;*1	;最下位ビット = 0 か？
		goto	mul8x02			;Yes

		movlw	60			;被乗数
		addwf	slp_cnt_h,F	;*2

mul8x02		rrf	slp_cnt_h,F	;*3	;
		rrf	slp_cnt_l,F	;*4	;
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	mul8x01			;No

		return

;     例． 60 x 2 = 120,    x 印: 実行されない,  - 印: キャリフラグ = 1

;	*1 slp_cnt_l	*2 slp_cnt_h	*3 slp_cnt_h	*4 slp_cnt_l
;1	0000.0010	0000.0000x	0000.0000	0000.0001
;2	0000.0001	0011.1100	0001.1110	0000.0000-
;3	0000.0000	0001.1110x	0000.1111	0000.0000
;4	0000.0000	0000.1111x	0000.0111-	1000.0000
;5	1000.0000	0000.0111x	0000.0011-	1100.0000
;6	1100.0000	0000.0011x	0000.0001-	1110.0000
;7	1110.0000	0000.0001x	0000.0000-	1111.0000
;8	1111.0000	0000.0000x	0000.0000-	0111.1000

;
;==========================================================================
; menu_no = 5		記録データ（メモリ内容）の読み出しと表示
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │○│   │○│   │●│   │●│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		  LEFT スイッチ ..... １つ前のデータを表示
;		 RIGHT スイッチ ..... １つ後のデータを表示

;		  EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				> bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				  bit7: 処理終了（エグジット）フラグ
;				  bit6: 例外終了（次処理に移行）フラグ
;				> bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				  bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				> bit2: 状態変化割り込み記憶フラグ
;				> bit1: スリープ中状態フラグ
;				> bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

memory_display

		call	xclock_rtc_read		;RTC DS3231 から年月日、時分秒を読み出し
		bsf	INTCON,INTE		;INT 外部割り込み許可 = 1

		movf	split_cnt,W		;スプリット番号カウンタ
		movwf	split_cntx		;スプリット番号カウンタに退避
		clrf	split_cnt		;スプリット番号カウンタの初期設定

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)
						;スリープ移行時間カウンタの初期設定
		movf	menu_5,W		;menu_5 分カウンタ
		call	mul8x8_16		;8 x 8 ビット = 16 ビットの乗算

		; 「記録（メモリ）内容の表示」画面の表示

		;	[ MemoDisp ]		;本機能の略名を表示
		;	[ xx:xx:xx ]		;現在時刻 "HH:MM:SS" を刻々と刻みながら表示
		;	  01234567

mmdsp01		movlw	h'80'			;表示位置指定 (１行目先頭)
		; menu_no = 5
		call	xmenu_display		;メニュー項目の表示(１行目)
		bsf	stat2_flg,5		;現在時刻表示指示フラグ = 1

		movf	split_cntx,W		;
		btfss	STATUS,Z		;スプリット番号カウンタ = 0 か？
		goto	mmdsp02			;No

		; 記録データがないときの処理

		;	[ MemoDisp ]		;本機能の略名を表示
		;	[   None   ]		;"None" がブリンク表示
		;	  01234567

		movlw	h'c2'			;表示位置指定 (２行目)
		call	none_blk_disp		;"None" の文字列のブリンク表示
		goto	mmdsp05

		; 現在時刻の表示 (２行目)

mmdsp02		btfss	stat2_flg,5		;現在時刻表示指示フラグ = 1 か？
		goto	mmdsp03			;No

		btfss	stat_flg,0		;現在時刻更新フラグ = 1 か？
		goto	mmdsp03			;No

		movlw	high bcd_hh		;時_BCD カウンタの番地（現在時刻用）
		movwf	FSR0H			;
		movlw	low bcd_hh		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	h'c0'			;表示位置指定 (２行目)
		call	time_display		;I2C LCD への "HH:MM:SS" 表示
		bcf	stat_flg,0		;現在時刻更新フラグ = 0
		call	alarm_sound		;時報音、タイマー一致音のアラーム出力

		; 各スイッチの入力チェック

mmdsp03		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	mmdsp05			;Yes

		btfss	PORTB,_swLEF		;LEFT スイッチ = ON か？
		call	mm_left_switch		;Yes

		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		call	mm_right_switch		;Yes

		btfss	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	mmdsp04			;No

		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		bcf	stat2_flg,5		;現在時刻表示指示フラグ = 0
		call	split_lap_disp		;スプリットタイムとラップタイムの表示

						;スリープ移行時間カウンタの初期設定
		movf	menu_5,W		;menu_5 分カウンタ
		call	mul8x8_16		;8 x 8 ビット = 16 ビットの乗算
		goto	mmdsp03

		; スリープ移行時間の監視（60 x 1 秒）

mmdsp04		call	sleep_mode		;時間の監視とスリープモードに移行
		btfss	stat2_flg,1		;スリープ中状態フラグ = 1 か？
		goto	mmdsp02			;No

		bcf	stat2_flg,1		;スリープ中状態フラグ = 0
		goto	mmdsp01

		; 「記録（メモリ）内容の表示」の終了

mmdsp05		call	xwait_15ms		;チャッタリング吸収
		bcf	INTCON,INTE		;INT 外部割り込み許可 = 0
		movf	split_cntx,W		;スプリット番号カウンタ退避用
		movwf	split_cnt		;スプリット番号カウンタに復帰

		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収
		movlp	high main
		goto	main			;「メニューの選択」に戻る

;--------------------------------------------------------------------------
;		スプリットタイムとラップタイムの表示
;--------------------------------------------------------------------------

split_lap_disp

		; スプリットタイムの読み出し（今回 = split_cnt）

		call	read_split_memory	;今回のスプリットタイムの読み出し

		movf	bcd_hh_w,W		;ラップタイムの計算のために必要
		movwf	bcd_hh_s		;今回 時_BCD カウンタ（スプリットタイム）
		movf	bcd_mm_w,W
		movwf	bcd_mm_s		;今回 分_BCD カウンタ
		movf	bcd_ss_w,W
		movwf	bcd_ss_s		;今回 秒_BCD カウンタ

		; スプリット（SPLIT）タイムの表示 (１行目)

		movlw	high bcd_hh_s		;時_BCD カウンタの番地（スプリット: 経過時間用）
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	h'80'			;表示位置指定 
		call	time_display		;I2C LCD への "HH:MM:SS" 表示

		decf	split_cnt,W		;先頭番号 (= 1) か？
		btfss	STATUS,Z		;スプリット番号カウンタ - 1 = 0 か？
		goto	sldsp01			;No

		movlw	high bcd_hh_s		;時_BCD カウンタの番地（スプリット: 経過時間用）
		movwf	FSR0H			;
		movlw	low bcd_hh_s		;
		movwf	FSR0L			;間接アドレスに設定
		goto	sldsp02

		; スプリットタイムの読み出し（前回 = split_cnt - 1）とラップタイムの計算

sldsp01		decf	split_cnt,F		;スプリット番号カウンタ - 1 :前の値に更新
		call	read_split_memory	;前回のスプリットタイムの読み出し
		incf	split_cnt,F		;スプリット番号カウンタ + 1 :元の値に復帰

		call	lap_time_calc		;ラップタイムの計算（bcd_xx_l = bcd_xx_s - bcd_xx_w）

		; ラップ（LAP）タイムの表示 (２行目)

		movlw	high bcd_hh_l		;時_BCD カウンタ（ラップタイム）
		movwf	FSR0H			;
		movlw	low bcd_hh_l		;
		movwf	FSR0L			;間接アドレスに設定

sldsp02		movlw	h'c0'			;表示位置指定 
		call	time_display		;I2C LCD への "HH:MM:SS" 表示

		return

;--------------------------------------------------------------------------
;	    LEFT スイッチの処理 ...「記録内容の表示」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;			   LEFT スイッチ ..... １つ前のデータを表示
;			( RIGHT スイッチ ..... １つ後のデータを表示 )

mm_left_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swLEF		;再度 LEFT スイッチ = ON か？
		goto	mmlef03			;No

		movf	split_cnt,W
		btfsc	STATUS,Z		;スプリット番号カウンタ = 0 か？
		goto	mmlef01			;Yes. 初回のみ

		decf	split_cnt,F
		btfss	STATUS,Z		;スプリット番号カウンタ - 1 = 0 か？
		goto	mmlef02			;No

mmlef01		movf	split_cntx,W
		movwf	split_cnt		;スプリット番号カウンタ = スプリット番号カウンタ退避用 に初期設定

;			[ ** xx ** ]
mmlef02		call	split_no_dispx		;スプリット／ラップ番号の表示

		btfss	PORTB,_swLEF		;LEFT スイッチ = OFF か？
		goto	$ - 1			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		call	xwait_15ms		;チャッタリング吸収

mmlef03		return

;--------------------------------------------------------------------------
;	    RIGHT スイッチの処理 ...「記録内容の表示」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;			( LEFT スイッチ ..... １つ前のデータを表示 )
;			 RIGHT スイッチ ..... １つ後のデータを表示

mm_right_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swRIG		;再度 RIGHT スイッチ = ON か？
		goto	mmrig03			;No

		movf	split_cnt,W
		btfsc	STATUS,Z		;スプリット番号カウンタ = 0 か？
		goto	mmrig01			;Yes. 初回のみ

		incf	split_cnt,F		;スプリット番号カウンタ + 1
		incf	split_cntx,W		;スプリット番号カウンタ退避用 + 1
		subwf	split_cnt,W
		btfss	STATUS,C		;スプリット番号カウンタ < スプリット番号カウンタ退避用 + 1 か？
		goto	mmrig02			;Yes

mmrig01		movlw	1
		movwf	split_cnt		;スプリット番号カウンタ = 1 に初期設定

;			[ ** xx ** ]
mmrig02		call	split_no_dispx		;スプリット／ラップ番号の表示

		btfss	PORTB,_swRIG		;RIGHT スイッチ = OFF か？
		goto	$ - 1			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		call	xwait_15ms		;チャッタリング吸収

mmrig03		return

;
;==========================================================================
; menu_no = 6		週間タイマーの時刻設定
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │●│   │●│   │●│   │●│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		  LEFT スイッチ ..... ブリンク位置のポインタを - 1
;		 RIGHT スイッチ ..... ブリンク位置のポインタを + 1

;		  DOWN スイッチ ..... ブリンク位置の値を - 1
;		    UP スイッチ ..... ブリンク位置の値を + 1

;		  EXIT スイッチ ..... タイマー用メモリに書き込み、次の設定に移る

;		  LEFT スイッチ + 
;		 RIGHT スイッチ ..... 「週間タイマーの時刻設定」を中断し、「メニューの選択」に戻る

;		 RIGHT スイッチ + 
;		  LEFT スイッチ ..... 「週間タイマーの時刻設定」を中断し、「メニューの選択」に戻る

;	  LEFT(ENABLE) スイッチ + 
;		  EXIT スイッチ ..... 「週間タイマーの設定表示と消去」に移行

;	   EXIT スイッチ 長押し ..... 「メニューの選択」に戻る（メモリ書き込みは行わない）

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				> bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				> bit7: 処理終了（エグジット）フラグ
;				> bit6: 例外終了（次処理に移行）フラグ
;				  bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				  bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				  bit2: 状態変化割り込み記憶フラグ
;				  bit1: スリープ中状態フラグ
;				  bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

wk_timer_setting

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		clrf	bcd_hh			;時_BCD カウンタの初期設定
		clrf	bcd_mm			;分_BCD カウンタ
		clrf	bcd_ww			;曜日_BCD カウンタ
		clrf	bup_flg			;EEPROM バックアップ要求フラグの初期設定
		clrf	blk_point		;ブリンク表示位置ポインタの初期設定

		; 「週間タイマーの時刻設定」の初期表示

		;	[ Set EDAY ]		;１行目 ... "Set ", 曜日名の表示
		;	[ 00:00  0 ]		;２行目 ... 時分, 曜日番号の表示
		;	  01234567

		movlw	h'80'			;(１行目先頭)
		call	xI2cLcd_Cmd		;
		movlw	0			;文字列 = 0
		call	str_disp		;"Set " を表示

tmset01		movlw	h'0c'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク
		movlw	h'c0'			;(２行目先頭)
		call	xI2cLcd_Cmd		;時の表示位置

		call	xhh_disp		;時の表示
		movlw	':'			;':'
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		call	xmm_disp		;分の表示

		movlw	' '			;
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		movlw	' '			;
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		call	week_disp		;曜日番号と曜日名の表示

		clrf	hold_cnt		;長押し監視カウンタの初期設定（この位置必須）

		; 各スイッチの入力チェック

tmset02		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		call	blk_point_table2	;ブリンク表示位置の DDRAM アドレスを取得
		iorlw	h'80'			;表示位置指定 (２行目)
		call	xI2cLcd_Cmd		;LCD へコマンドを出力
		movlw	h'0d'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=1: ブリンク

tmset03		btfss	PORTB,_swLEF		;LEFT スイッチ = ON か？
		call	tim_left_switch		;Yes

		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		call	tim_right_switch	;Yes

		btfsc	stat2_flg,7		;処理終了フラグ = 1 か？
		goto	tmset08			;Yes. 中断終了

		btfsc	stat2_flg,6		;例外終了フラグ = 1
		goto	tmset09			;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	tmset02			;Yes

		btfss	PORTB,_swDWN		;DOWN スイッチ = ON か？
		call	tim_down_switch		;Yes

		btfss	PORTB,_swUP		;UP スイッチ = ON か？
		call	tim_up_switch		;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	tmset01			;Yes

		; EXIT スイッチの入力チェック

		call	tim_exit_switch		;EXIT スイッチの長押し監視

		btfsc	stat_flg,7		;メモリ書き込み指示フラグ = 1 か？
		goto	tmset04			;Yes

		btfss	stat2_flg,7		;処理終了フラグ = 1 か？
		goto	tmset03			;No
		goto	tmset08			;Yes

tmset04		bcf	stat_flg,7		;メモリ書き込み指示フラグ = 0
		call	timer_memory_monitor	;タイマー用メモリの監視（一致検査）
		btfsc	STATUS,Z		;同一データがあった か？
		goto	tmset05			;Yes. エラー

		call	write_timer_memory	;タイマー用メモリへの書き込み
		btfsc	STATUS,C		;書き込みができた か？
		goto	tmset06			;No. メモリオーバーエラー

		; "ポッポッ" アラーム音出力 (Total 260 mS) と LED(緑) 点滅
		call	memory_complete		;メモリ書き込み報告
		goto	tmset01

		; "ブッ" アラーム音出力 (Total 130 mS) と LED(赤) 点滅
tmset05		call	buzzer_bu_led		;
		goto	tmset01

		; タイマー用メモリ満タンメッセージの表示

		;	[ Set Err! ]		;１行目
		;	[ Mem Full ]		;２行目
		;	  01234567

tmset06		movlw	h'84'			;(１行目)
		call	xI2cLcd_Cmd		;
		movlw	1			;文字列 = 1
		call	str_disp		;"Err!" を表示

		; "ブッブッブッブッ" アラーム音出力 (Total 520 mS) と LED(赤) 点滅
		call	memory_full		;メモリ満タンメッセージ

		; 「週間タイマーの時刻設定」の終了

tmset07		comf	PORTB,W			;全ビットを反転
		andlw	h'ec'
		btfss	STATUS,Z		;すべてのスイッチ = OFF か？
		goto	tmset07			;No

tmset08		call	xwait_15ms		;チャッタリング吸収
		call	write_eeprom_memory	;EEPROM にバックアップ
		movlp	high main
		goto	main			;「メニューの選択」に戻る

tmset09		call	write_eeprom_memory	;EEPROM にバックアップ
		movlw	7
		movwf	menu_no			;メニュー番号 = 7 設定
		goto	wk_timer_display	;「週間タイマーの設定表示と消去」に移行

;--------------------------------------------------------------------------

		; ブリンク表示位置テーブル

blk_point_table2
		movf	blk_point,W		;ブリンク位置ポインタ
		brw

		;	0     1     2   	;  0  1   2  ... blk_point
		;	"HH"  "MH"  "WL"	; "xx:xx  x" ... 桁
		;				;  01234567
		dt	h'40',h'43',h'47'	;            ... DDRAM のアドレス (２行目)

;--------------------------------------------------------------------------

		; 曜日番号と曜日名の表示
week_disp
		movlw	h'c7'			;曜日カウンタの表示位置
		call	xI2cLcd_Cmd		;
		movf	bcd_ww,W		;曜日カウンタの
		andlw	h'0f'			;下位4ビット
		iorlw	h'30'			;数字に変換
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		; 曜日名の表示
week_name_disp
		movlw	h'84'			;曜日名の表示位置
		call	xI2cLcd_Cmd		;
		movlw	' '
		movf	bcd_ww,F
		btfsc	STATUS,Z		;曜日_BCD カウンタ = 0 か？
		movlw	'E'			;Yes
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		movlp	high ww_disp
		call	ww_disp			;曜日_BCD カウンタを曜日名に変換表示
		movlp	high $
		return

;--------------------------------------------------------------------------

		; 文字列の表示
str_disp
		movwf	addr_low		;文字列番号
		lslf	addr_low,F		;x 2 倍
		lslf	addr_low,F		;x 4 倍
		addwf	addr_low,F		;x 5 倍

		movlw	high str_table		;テーブルデータの先頭 high アドレス
		movwf	addr_high		;
		movlw	low str_table		;テーブルデータの先頭 low アドレス
		addwf	addr_low,F		;
		btfsc	STATUS,C		;オーバーフローした場合は
		incf	addr_high,F		;high アドレスの更新

		call	xI2cLcd_Disp		;I2C LCD へ文字列データを出力
		return

		; 文字列 データテーブル
str_table
		dt	"Set ",0		;文字列番号 = 0
		dt	"Err!",0		;             1
		dt	"Dsp ",0		;             2
		dt	"None",0     		;             3
		dt	"    ",0		;             4

;--------------------------------------------------------------------------
;	 LEFT スイッチの処理 ...「週間タイマーの時刻設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		  LEFT スイッチ ..... ブリンク位置のポインタを - 1

;	  LEFT(ENABLE) スイッチ + 
;		  EXIT スイッチ ..... 「週間タイマーの設定表示と消去」に移行

;		  LEFT スイッチ + 
;		 RIGHT スイッチ ..... 「週間タイマーの時刻設定」を中断し、「メニューの選択」に戻る

tim_left_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swLEF		;再度 LEFT スイッチ = ON か？
		goto	tmlef05			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		decf	blk_point,F		;ブリンク位置ポインタ - 1
		incf	blk_point,W
		movlw	2
		btfsc	STATUS,Z		;blk_point = -1(W=0) か？
		movwf	blk_point		;Yes. blk_point = 2 に設定

tmlef01		btfsc	PORTB,_swLEF		;LEFT スイッチ = ON か？
		goto	tmlef04			;No

		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		goto	tmlef02			;Yes

		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	tmlef01			;No

		bsf	stat2_flg,6	;;	;例外終了フラグ = 1
		goto	tmlef03

tmlef02		bsf	stat2_flg,7	;;	;処理終了フラグ = 1 (中断終了)

tmlef03		comf	PORTB,W			;全ビットを反転
		andlw	h'e0'
		btfss	STATUS,Z		;LEFT and RIGHT and EXIT スイッチ = OFF か？
		goto	tmlef03			;No

tmlef04		call	xwait_15ms		;チャッタリング吸収

tmlef05		return

;--------------------------------------------------------------------------
;	 RIGHT スイッチの処理 ...「週間タイマーの時刻設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		RIGHT スイッチ ..... ブリンク位置のポインタを + 1

;		RIGHT スイッチ + 
;		 LEFT スイッチ ..... 「週間タイマーの時刻設定」を中断し、「メニューの選択」に戻る

tim_right_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swRIG		;再度 RIGHT スイッチ = ON か？
		goto	tmrig04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		incf	blk_point,F		;ブリンク位置ポインタ + 1
		movlw	2 + 1
		subwf	blk_point,W		;blk_point - (2 + 1)
		btfsc	STATUS,C		;blk_point < (2 + 1) か？
		clrf	blk_point		;No. blk_point = 0 に設定

tmrig01		btfsc	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		goto	tmrig03			;No

		btfsc	PORTB,_swLEF		;LEFT スイッチ = ON か？
		goto	tmrig01			;No

		bsf	stat2_flg,7	;;	;処理終了フラグ = 1 (中断終了)

tmrig02		comf	PORTB,W			;全ビットを反転
		andlw	h'c0'
		btfss	STATUS,Z		;RIGHT スイッチ and LEFT スイッチ = OFF か？
		goto	tmrig02			;No

tmrig03		call	xwait_15ms		;チャッタリング吸収

tmrig04		return

;--------------------------------------------------------------------------
;	 DOWN スイッチの処理 ...「週間タイマーの時刻設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 DOWN スイッチ ..... ブリンク位置の値を - 1

tim_down_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	tmdwn04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	blk_point,W
		btfss	STATUS,Z		;blk_point = 0 か？
		goto	tmdwn01			;No

		movlp	high bcd_hh_dec
		call	bcd_hh_dec		;時_BCD カウンタのデクリメント
		movlp	high $
		goto	tmdwn03

tmdwn01		decf	blk_point,W
		btfss	STATUS,Z		;blk_point = 1 か？
		goto	tmdwn02			;No

		call	xbcd_mm_dec		;分_BCD カウンタのデクリメント
		goto	tmdwn03

tmdwn02		decf	bcd_ww,F		;曜日_BCD カウンタ - 1
		incf	bcd_ww,W
		movlw	7
		btfsc	STATUS,Z		;bcd_ww = -1 (W=0) か？
		movwf	bcd_ww			;Yes. 曜日_BCD カウンタ = 7:"SAT"

tmdwn03	;	btfss	PORTB,_swDWN		;DOWN スイッチ = OFF か？
	;	goto	$ - 1			;No

	;	call	xwait_15ms		;チャッタリング吸収
		call	xwait_200ms		;早送りの速度調整

tmdwn04		return

;--------------------------------------------------------------------------
;	  UP スイッチの処理 ...「週間タイマーの時刻設定」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		   UP スイッチ ..... ブリンク位置の値を + 1

tim_up_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swUP		;再度 UP スイッチ = ON か？
		goto	tmup04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	blk_point,W
		btfss	STATUS,Z		;blk_point = 0 か？
		goto	tmup01			;No

		movlp	high bcd_hh_inc
		call	bcd_hh_inc		;時_BCD カウンタのインクリメント
		movlp	high $
		goto	tmup03

tmup01		decf	blk_point,W
		btfss	STATUS,Z		;blk_point = 1 か？
		goto	tmup02			;No

		call	xbcd_mm_inc		;分_BCD カウンタのインクリメント
		goto	tmup03

tmup02		incf	bcd_ww,F		;曜日_BCD カウンタ + 1
		movlw	7 + 1
		subwf	bcd_ww,W
		btfsc	STATUS,C		;bcd_ww < 7 + 1 か？
		clrf	bcd_ww			;No. 曜日_BCD カウンタ = 0: "EDAY"

tmup03	;	btfss	PORTB,_swUP		;UP スイッチ = OFF か？
	;	goto	$ - 1			;No

	;	call	xwait_15ms		;チャッタリング吸収
		call	xwait_200ms		;早送りの速度調整

tmup04		return

;--------------------------------------------------------------------------
;	 EXIT スイッチの処理 ...「週間タイマーの時刻設定」から CALL
;--------------------------------------------------------------------------

;		3 (64ms x 47 = 3,008 mS) 秒間以上 長押しの監視

;	[スイッチ操作]

;		EXIT スイッチ        ..... タイマー用メモリに書き込み、次の設定に移る

;		EXIT スイッチ 長押し ..... 「メニューの選択」に戻る  （３秒以上の長押し）

tim_exit_switch

		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	tmext01			;Yes

		movf	hold_cnt,F
		btfsc	STATUS,Z		;長押し監視カウンタ = 0 か？
		goto	tmext04			;Yes

		; (監視時間になる前に スイッチを OFF にした)
		bcf	INTCON,TMR0IE		;TMR0 オーバーフロー割り込み許可 = 0
		clrf	hold_cnt		;長押し監視カウンタの初期設定
		bsf	stat_flg,7	;;	;メモリ書き込み指示フラグ = 1
		goto	tmext03

tmext01		movf	hold_cnt,F
		btfss	STATUS,Z		;長押し監視カウンタ = 0 か？
		goto	tmext02			;No

		incf	hold_cnt,F		;長押し監視カウンタ = 1 始まり
		movlw	256 - 250		;(4/4MHz) * 250 * 256(Prescaler) = 64000μS = 64 mS
		movwf	TMR0
		bsf	INTCON,TMR0IE		;TMR0 オーバーフロー割り込み許可 = 1
		goto	tmext03

tmext02		btfsc	INTCON,TMR0IE		;TMR0 オーバーフロー割り込み許可 = 1 か？
		goto	tmext04			;Yes

		; (時間監視を終了しても スイッチが ON のとき)
		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

		bsf	stat2_flg,7	;;	;処理終了フラグ = 1

tmext03		call	xwait_15ms		;チャッタリング吸収

tmext04		return

;--------------------------------------------------------------------------
;		タイマー用メモリの構成
;--------------------------------------------------------------------------

; １メモリ単位 ... (タイマー制御バイト)、(時_BCD カウンタバイト)、(分_BCD カウンタバイト)

; (タイマー制御バイト) ／ fmmwwwss

;		fmmw.wwss	fmmw.wwss	fmmw.wwss	fmmw.wwss
;		:		 ::		   : ::		       ::
;		0  メモリ無効  *(00  OFF)	   0 00  EDAY	     *(01  SW1)
;		1  メモリ有効  *(01  ON)	   0 01  SUN	     *(10  SW2)
;			       *(10  SLP OFF)	   0 10  MON	     *(11  SW3)
;			       *(11  SLP ON)	   0 11  TUE	     *(00  SW4)
;						   1 00  WED
;						   1 01  THU
;						   1 10  FRI
;						   1 11  SAT

;		* 印 bit: 本プログラムでは使用しない

; (時_BCD カウンタバイト)

;		chhh.hhhh		chhh.hhhh	chhh.hhhh
;		:			 :::		     ::::
;	      *(1 メモリ自動消去有効)	 十時(0～2)	     時(0～9)

; (分_BCD カウンタバイト)

;					mmmm.mmmm	mmmm.mmmm
;					::::		     ::::
;					十分(0～5)	     分(0～9)

;--------------------------------------------------------------------------
;		タイマー用メモリへの書き込み
;--------------------------------------------------------------------------

;	  汎用変数:	lp_cnt1

write_timer_memory

		movlw	high timer_memory	;タイマー用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low timer_memory	;
		movwf	FSR1L			;

		movlw	timer_capacity		;タイマー用メモリの記憶容量の最大値
		movwf	lp_cnt1			;ループカウンタ

wrtmm01		btfss	INDF1,7			;fmmwwwss の f bit = 1 (有効) か？
		goto	wrtmm02			;No. 空き

		addfsr	FSR1,3			;間接アドレス + 3 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	wrtmm01			;No

		bsf	STATUS,C		;C フラグ = 1、メモリオーバーエラー表示
		goto	wrtmm03			;ERROR

		; タイマー用メモリへ書き込み

wrtmm02		lslf	bcd_ww,W		;2 ビット左にシフト
		movwf	INDF1			;
		lslf	INDF1,F			;www bit の設定
		bsf	INDF1,7			;f bit = 1 (有効) の設定
						;(タイマー制御バイト)を書き込み

		movf	bcd_hh,W		;時_BCD カウンタ
		movwi	1[FSR1]			;(時_BCD カウンタバイト)を書き込み

		movf	bcd_mm,W		;分_BCD カウンタ
		movwi	2[FSR1]			;(分_BCD カウンタバイト)を書き込み

		bsf	bup_flg,0		;EEPROM バックアップ要求フラグ = 1
		bcf	STATUS,C		;C フラグ = 0、書き込み済み

wrtmm03		return

;--------------------------------------------------------------------------
;		タイマー用メモリの読み出し
;--------------------------------------------------------------------------

;	  汎用変数:	work1, lp_cnt1

read_timer_memory

		; タイマー用メモリの検索

		movf	dsp_cnt,W		;表示カウンタ
		movwf	work1

		movlw	high timer_memory	;タイマー用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low timer_memory	;
		movwf	FSR1L			;

		movlw	timer_capacity		;タイマー用メモリの記憶容量の最大値
		movwf	lp_cnt1			;ループカウンタ

rdtmm01		btfss	INDF1,7			;fmmwwwss の f bit = 1 (有効) か？
		goto	rdtmm02			;No

		decf	work1,F			;表示カウンタ - 1
		btfsc	STATUS,Z		;表示カウンタ = 0 か？
		goto	rdtmm03			;Yes

rdtmm02		addfsr	FSR1,3			;間接アドレス + 3 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	rdtmm01			;No

		goto	rdtmm04			;この命令が実行されることはない！ はず

		; タイマー用メモリの読み出し

rdtmm03		movf	FSR1H,W			;消去対象（となるかもしれない）
		movwf	del_fsr_h		;タイマー用メモリアドレスを記憶
		movf	FSR1L,W			;
		movwf	del_fsr_l		;

		moviw	0[FSR1]			;(タイマー制御バイト)を読み出し
		movwf	fmmwwwss		;タイマー制御バイト

		moviw	1[FSR1]			;(時_BCD カウンタバイト)を読み出し
		movwf	bcd_hh			;時_BCD カウンタ

		moviw	2[FSR1]			;(分_BCD カウンタバイト)を読み出し
		movwf	bcd_mm			;分_BCD カウンタ

rdtmm04		return

;--------------------------------------------------------------------------
;		有効なタイマー用メモリ数のカウント
;--------------------------------------------------------------------------

;	  汎用変数:	lp_cnt1

valid_memory_count

		clrf	valid_cnt		;タイマー用メモリの有効数カウンタの初期設定
		movlw	high timer_memory	;タイマー用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low timer_memory	;
		movwf	FSR1L			;

		movlw	timer_capacity		;タイマー用メモリの記憶容量の最大値
		movwf	lp_cnt1			;ループカウンタ

valmm01		btfsc	INDF1,7			;fmmwwwss の f bit = 1 (有効) か？
		incf	valid_cnt,F		;Yes. タイマー用メモリの有効数カウンタ + 1

		addfsr	FSR1,3			;間接アドレス + 3 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	valmm01			;No

		return

;--------------------------------------------------------------------------
;		タイマー用メモリの監視（一致検査）
;--------------------------------------------------------------------------

;	  汎用変数:	lp_cnt1

timer_memory_monitor

		lslf	bcd_ww,W		;2 ビット左にシフト
		movwf	fmmwwwss		;
		lslf	fmmwwwss,F		;www bit の設定
		bsf	fmmwwwss,7		;f bit = 1 (有効) の設定

		movlw	high timer_memory	;タイマー用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low timer_memory	;
		movwf	FSR1L			;

		movlw	timer_capacity		;タイマー用メモリの記憶容量の最大値
		movwf	lp_cnt1			;ループカウンタ1

tmmon01		btfss	INDF1,7			;タイマー用メモリの f bit = 1 (有効) か？
		goto	tmmon03			;No

		moviw	0[FSR1]			;
		andlw	h'1c'			;www bit 
		btfsc	STATUS,Z		;www bit = 000 (EDAY) か？
		goto	tmmon02			;Yes

		moviw	0[FSR1]			;
		subwf	fmmwwwss,W
		btfss	STATUS,Z		;(タイマー制御バイト) = 一致した か？
		goto	tmmon03			;No

tmmon02		moviw	1[FSR1]			;
		subwf	bcd_hh,W
		btfss	STATUS,Z		;(時_BCD カウンタバイト) = 一致した か？
		goto	tmmon03			;No

		moviw	2[FSR1]			;
		subwf	bcd_mm,W
		btfsc	STATUS,Z		;(分_BCD カウンタバイト) = 一致した か？
		goto	tmmon04			;Yes. Z フラグ = 1、一致あり

tmmon03		addfsr	FSR1,3			;間接アドレス + 3 更新
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	tmmon01			;No

		bcf	STATUS,Z		;Z フラグ = 0、一致なし

tmmon04		return

;--------------------------------------------------------------------------
;		時報音、タイマー一致音フラグコントロール
;--------------------------------------------------------------------------

;	alm_flg: アラーム音出力フラグ

;	  bit7: アラーム音出力有効／無効フラグ
;	  bit6: アラーム音出力済みフラグ
;	  bit5: 
;	  bit4: 
;	  bit3: 時報正報音フラグ           ... "ポッ～～ン"   音  1 回 ... bcd_ss  = h'00' & bcd_mm = h'00'
;	  bit2: 時報予報音フラグ           ... "プッ"         音  3 回 ... bcd_ss >= h'57' & bcd_mm = h'59'
;	  bit1: タイマー一致音フラグ       ... "ピポッピポッ" 音 10 回 ... bcd_ss  = h'00' & タイマー条件
;	  bit0: タイマー一致音継続中フラグ				   bcd_ss  < h'10' & alm_flg.0 = 1

time_alarm_control

		btfss	alm_flg,7		;アラーム音出力フラグ = 1 か？
		goto	tacon04			;No

		movf	bcd_ss,W
		btfss	STATUS,Z		;bcd_ss = h'00' か？
		goto	tacon02			;No

		movf	bcd_mm,W
		btfss	STATUS,Z		;bcd_mm = h'00' か？
		goto	tacon01			;No

		; bcd_ss = h'00' & bcd_mm = h'00'
		bsf	alm_flg,3		;時報正報音フラグ = 1

		; bcd_ss = h'00'
tacon01		call	timer_memory_monitor	;タイマー用メモリの監視（一致検査）
		btfss	STATUS,Z		;一致 か？
		goto	tacon04			;No

		bsf	alm_flg,1		;タイマー一致音フラグ = 1
		bsf	alm_flg,0		;タイマー一致音継続中フラグ = 1
		goto	tacon04

tacon02		movlw	h'59'
		subwf	bcd_mm,W		;分_BCD カウンタ
		btfss	STATUS,Z		;bcd_mm = h'59' か？
		goto	tacon03			;No

		movlw	h'57'
		subwf	bcd_ss,W		;秒_BCD カウンタ
		btfss	STATUS,C		;bcd_ss >= h'57' か？
		goto	tacon03			;No

		; bcd_ss >= h'57' & bcd_mm = h'59'
		bsf	alm_flg,2		;時報予報音フラグ = 1
		goto	tacon04

tacon03		btfss	alm_flg,0		;タイマー一致音継続中フラグ = 1 か？
		goto	tacon04			;No

		; alm_flg.0 = 1
		movlw	h'10'
		subwf	bcd_ss,W		;秒_BCD カウンタ
		btfss	STATUS,C		;bcd_ss <  h'10' か？
		bsf	alm_flg,1		;Yes. タイマー一致音フラグ = 1
		btfsc	STATUS,C		;bcd_ss >= h'10' か？
		bcf	alm_flg,0		;Yes. タイマー一致音継続中フラグ = 0

tacon04		return

;--------------------------------------------------------------------------
;		時報音、タイマー一致音のアラーム出力
;--------------------------------------------------------------------------

;	出力の優先順位:  タイマー一致音 > 時報予報音 > 時報正報音

;	同時に複数のフラグ = 1 の場合は、優先順位の低いものは無視される

alarm_sound

;		btfss	alm_flg,7		;アラーム音出力許可フラグ = 1 か？
;		goto	alarm04			;（このフラグ = 0 のときは、
						;４つのフラグ = 1 になることはない）

		bcf	alm_flg,6		;アラーム音出力済みフラグ = 0
		movlw	h'0e'
		andwf	alm_flg,W
		btfsc	STATUS,Z		;どれかアラームフラグ = 1 か？
		goto	alarm04			;No

		btfss	alm_flg,1		;タイマー一致音フラグ = 1 か？
		goto	alarm01			;No

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力 (520 mS)
		goto	alarm03

alarm01		btfss	alm_flg,2		;時報予報音フラグ = ON か？
		goto	alarm02			;No

		movlp	high buzzer_pu
		call	buzzer_pu		;"プッ" アラーム音出力 (100 mS)
		movlp	high $
		goto	alarm03

alarm02	;	btfss	alm_flg,3		;時報正報音フラグ = ON か？
	;	goto	alarm03			;No

		movlp	high buzzer_poon
		call	buzzer_poon		;"ポッ～～ン" アラーム音出力 (1000 mS)
		movlp	high $
		bcf	PORTA,_BZ		;ブザー出力ビットを "L" にしておく

alarm03		movlw	h'81'
		andwf	alm_flg,F		;アラーム音フラグをクリア
		bsf	alm_flg,6		;アラーム音出力済みフラグ = 1

alarm04		return

;
;==========================================================================
; menu_no = 7		週間タイマーの設定表示と消去
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │●│   │●│   │●│   │●│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		  LEFT スイッチ ..... １つ前の登録情報を表示
;		 RIGHT スイッチ ..... １つ後の登録情報を表示

;		  DOWN スイッチ ..... 表示している登録情報を消去

;		    UP スイッチ +
;		  DOWN スイッチ ..... すべての登録情報を消去

;		  EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				  bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

;--------------------------------------------------------------------------

wk_timer_display

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		clrf	bup_flg			;EEPROM バックアップ要求フラグの初期設定

		; 「週間タイマーの設定表示と消去」の初期表示

		movlw	1
		movwf	dsp_cnt			;表示カウンタの初期設定

tmdsp01		movlw	h'0c'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク

		;	[ Dsp  SUN ]		;１行目
		;	[ xx:xx nn ]		;２行目 ... nn: 登録情報の番号
		;	  01234567

		movlw	h'80'			;(１行目先頭)
		call	xI2cLcd_Cmd		;
		movlw	2			;文字列 = 2
		call	str_disp		;"Dsp " を表示

tmdsp02		call	valid_memory_count	;有効なタイマー用メモリ数のカウント
		movf	valid_cnt,W
		btfss	STATUS,Z		;タイマー用メモリの有効数カウンタ > 0 か？
		goto	tmdsp03			;Yes

		; 有効数カウンタ = 0 のとき

		clrf	bcd_hh			;
		clrf	bcd_mm			;
		clrf	dsp_cnt			;
		goto	tmdsp04

		; 有効数カウンタ > 0 のとき

tmdsp03		call	read_timer_memory	;タイマー用メモリの読み出し
		movlw	h'1c'
		andwf	fmmwwwss,W		;タイマー制御バイトから www bit を取り出す
		movwf	bcd_ww
		lsrf	bcd_ww,F		;2 ビット右にシフト
		lsrf	bcd_ww,F		;www bit の設定
		call	week_name_disp		;曜日名 を表示

		; ２行目の表示

tmdsp04		movlw	h'c0'			;(２行目先頭)
		call	xI2cLcd_Cmd		;時の表示位置
		call	xhh_disp		;時 を表示
		movlw	':'			;':'
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力
		call	xmm_disp		;分 を表示

		movlw	h'c6'			;表示カウンタ nn の表示位置
		call	xI2cLcd_Cmd		;
		movf	dsp_cnt,W		;表示カウンタを
		call	dec2chr_disp		;nn: ２桁の数字に変換表示

		; 各スイッチの入力チェック

tmdsp05		movf	valid_cnt,W
		btfsc	STATUS,Z		;タイマー用メモリの有効数カウンタ = 0 か？
		goto	tmdsp06			;Yes

		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	tmdsp08			;Yes

		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		call	tim_dsp_right_switch	;Yes

		btfss	PORTB,_swLEF		;LEFT スイッチ = ON か？
		call	tim_dsp_left_switch	;Yes

		btfss	PORTB,_swDWN		;DOWN スイッチ = ON か？
		call	tim_dsp_down_switch	;Yes

		btfss	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	tmdsp05			;No
		goto	tmdsp02			;Yes

		; 登録情報がないときの処理

		;	[ Dsp None ]		;１行目 ... "None" の文字が 0.5 秒点 0.5 秒滅
		;	[ 00:00 00 ]		;２行目 ... nn=00: 登録情報の番号
		;	  01234567

tmdsp06		movlw	h'84'			;表示位置指定 (１行目)
		call	none_blk_disp		;"None" の文字列のブリンク表示

		; 「週間タイマーの設定表示と消去」の終了

tmdsp08		call	xwait_15ms		;チャッタリング吸収
		call	write_eeprom_memory	;EEPROM にバックアップ

		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収
		movlp	high main
		goto	main			;「メニューの選択」に戻る

;--------------------------------------------------------------------------

		; "None" 文字列のブリンク表示

none_blk_disp
		movwf	work1			;表示位置の退避
		clrf	work2

nodsp01		movf	work1,W			;表示位置指定
		call	xI2cLcd_Cmd		;

		movlw	3			;    文字列 = 3
		btfsc	work2,0			;work2 = 0 か？
		movlw	4			;No. 文字列 = 4
		call	str_disp		;"None" or "    " を表示

		btfss	work2,0			;work2 = 0 か？
		call	buzzer_bu_led		;Yes. "ブッ" アラーム音出力 (130 mS) と LED(赤) 点滅

		movlw	74			;500 - 130 = 5 ms * 74 = 370 ms
		btfsc	work2,0			;work2 = 0 か？
		movlw	100			;No. 5 ms * 100 = 500 ms
		movwf	lp_cnt1			;ループカウンタ1

nodsp02		movlw	5
		call	xwait_xxms		;5 m秒ウェイトルーチン

		btfss	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	nodsp03			;Yes

		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	nodsp02			;No

		movlw	1
		xorwf	work2,F			;トグル動作
		goto	nodsp01

nodsp03		return

;--------------------------------------------------------------------------
;     LEFT スイッチの処理 ...「週間タイマーの設定表示と消去」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 LEFT スイッチ ..... １つ前の登録情報を表示

tim_dsp_left_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swLEF		;再度 LEFT スイッチ = ON か？
		goto	tdlef01			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		movf	valid_cnt,W		;タイマー用メモリの有効数カウンタ
		decf	dsp_cnt,F		;表示カウンタ - 1
		btfsc	STATUS,Z		;dsp_cnt = 0 か？
		movwf	dsp_cnt			;Yes. dsp_cnt = valid_cnt に設定

		btfss	PORTB,_swLEF		;LEFT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収

tdlef01		return

;--------------------------------------------------------------------------
;     RIGHT スイッチの処理 ...「週間タイマーの設定表示と消去」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		RIGHT スイッチ ..... １つ後の登録情報を表示

tim_dsp_right_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swRIG		;再度 RIGHT スイッチ = ON か？
		goto	tdrig01			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		incf	dsp_cnt,F		;表示カウンタ + 1
		incf	valid_cnt,W		;タイマー用メモリの有効数カウンタ + 1
		subwf	dsp_cnt,W		;
		movlw	1
		btfsc	STATUS,C		;dsp_cnt < valid_cnt + 1 か？
		movwf	dsp_cnt			;No. dsp_cnt = 1 に設定

		btfss	PORTB,_swRIG		;RIGHT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収

tdrig01		return

;--------------------------------------------------------------------------
;     DOWN スイッチの処理 ...「週間タイマーの設定表示と消去」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		  DOWN スイッチ ..... 表示している登録情報を消去

;		    UP スイッチ +
;		  DOWN スイッチ ..... すべての登録情報を消去

tim_dsp_down_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	tddwn05			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		bsf	bup_flg,0		;EEPROM バックアップ要求フラグ = 1

		btfss	PORTB,_swUP		;UP スイッチ = ON か？
		goto	tddwn01			;Yes

		; 個別消去の場合

		movf	del_fsr_h,W		;消去対象の
		movwf	FSR1H			;タイマー用メモリアドレスを復帰
		movf	del_fsr_l,W		;
		movwf	FSR1L			;

		clrf	INDF1			;タイマー制御バイトを消去

		movf	valid_cnt,W		;タイマー用メモリの有効数カウンタ
		subwf	dsp_cnt,W		;
		btfsc	STATUS,Z		;dsp_cnt = valid_cnt か？
		decf	dsp_cnt,F		;Yes. 表示カウンタ - 1
		goto	tddwn03

		; 全消去の場合

tddwn01		movlw	high timer_memory	;タイマー用メモリの先頭アドレス
		movwf	FSR1H			;
		movlw	low timer_memory	;
		movwf	FSR1L			;

		movlw	timer_capacity * 3	;タイマー用メモリの記憶容量の最大値 * 3
		movwf	lp_cnt1			;ループカウンタ1

tddwn02		clrf	INDF1
		addfsr	FSR1,1			;間接アドレス + 1 更新

		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	tddwn02			;No

tddwn03		call	xbuzzer_pipi		;"ピッピッ" アラーム音出力 (230 mS)と LED(緑)点滅

tddwn04		comf	PORTB,W			;全ビットを反転
		andlw	h'0c'
		btfss	STATUS,Z		;DOWN スイッチ and UP スイッチ = OFF か？
		goto	tddwn04			;No

		call	xwait_15ms		;チャッタリング吸収

tddwn05		return

;==========================================================================

;--------------------------------------------------------------------------
;	    タイマー用メモリを EEPROM へ書き込み（バックアップ）
;--------------------------------------------------------------------------

;	メモリ有効フラグ = 1 だけの１メモリ単位（ = 3 バイト）ずつを順に書き込む
;	残ったタイマー用メモリのバックアップエリアには h'00' データを書き込む

write_eeprom_memory

		btfss	bup_flg,0		;EEPROM バックアップ要求フラグ = 1 か？
		goto	wreep05			;No

		movlb	3			;バンク 3
		movlw	low eep_timer_memory
		movwf	EEADRL			;EEPROM の記録アドレスを設定
		movlb	0			;バンク 0

		movlw	high timer_memory	;タイマー用メモリの先頭アドレスを
		movwf	FSR0H			;間接アドレスに設定
		movlw	low timer_memory	;
		movwf	FSR0L			;

		movlw	timer_capacity * 3	;１メモリ単位 = 3 バイト
		movwf	work1			;書き込みの総バイト数
		clrf	work2			;残り書き込みフラグ = 0

		movlw	timer_capacity		;タイマー用メモリの記憶容量の最大値
		movwf	lp_cnt1			;ループカウンタ1

wreep01		movlw	3			;１メモリ単位 = 3 バイト
		movwf	lp_cnt2			;ループカウンタ2

wreep02		btfsc	INDF0,7			;メモリ有効フラグ = 1 か？
		goto	wreep03			;Yes

		addfsr	FSR0,3			;間接アドレス +3 更新
		goto	wreep04

wreep03		btfss	work2,0			;残り書き込みフラグ = 1 か？
		moviw	FSR0++			;No. タイマー用メモリの読み出し
		btfsc	work2,0			;残り書き込みフラグ = 1 か？
		clrw				;Yes

		movlb	3			;バンク 3
		movwf	EEDATL			;書き込みデータを設定

		bcf	EECON1,CFGS		;フラッシュプログラム/データ EEPROM メモリを選択
		bcf	EECON1,EEPGD		;データ EEPROM メモリにアクセス
		bsf	EECON1,WREN		;プログラム/消去サイクルを許可

	;	bcf	INTCON,GIE		;割り込みを禁止
		movlw	h'55'
		movwf	EECON2			;h'55' を EECON2 に書き込む
		movlw	h'aa'
		movwf	EECON2			;h'aa' を EECON2 に書き込む

		bsf	EECON1,WR		;書き込み開始
	;	bsf	INTCON,GIE		;割り込みを許可
		bcf	EECON1,WREN		;プログラム/消去サイクルを禁止
		btfsc	EECON1,WR		;書き込み終了 か？
		goto	$ - 1			;No

		incf	EEADRL,F		;記録アドレスの更新
		movlb	0			;バンク 0

		decf	work1,F			;書き込みの総バイト数 - 1
		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	wreep03			;No

		btfsc	work2,0			;残り書き込みフラグ = 1 か？
		goto	wreep05			;Yes

wreep04		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	wreep01			;No

		movf	work1,W			;
		btfsc	STATUS,Z		;書き込みの総バイト数 = 0 か？
		goto	wreep05			;Yes

		movwf	lp_cnt2			;ループカウンタ2 に設定
		bsf	work2,0			;残り書き込みフラグ = 1
		goto	wreep03

wreep05		return

;--------------------------------------------------------------------------
;		タイマー用メモリを EEPROM から読み出し
;--------------------------------------------------------------------------

;	EEPROM バックアップエリアの先頭バイトが h'00'（書き込みを一度も行っていない初期値）
;	のときは、それ以降の読み出しを中止し、タイマー用メモリのすべてを h'00' クリアする

read_eeprom_memory

		movlw	high timer_memory	;タイマー用メモリの先頭アドレスを
		movwf	FSR0H			;間接アドレスに設定
		movlw	low timer_memory	;
		movwf	FSR0L			;

		clrf	work1			;先頭バイトチェック済みフラグ = 0
		movlw	timer_capacity * 3	;１メモリ単位 = 3 バイト
		movwf	lp_cnt1			;ループカウンタ1

		movlb	3			;バンク 3
		movlw	low eep_timer_memory
		movwf	EEADRL			;EEPROM の記録アドレスを設定
		bcf	EECON1,CFGS		;フラッシュプログラム/データ EEPROM メモリを選択
		bcf	EECON1,EEPGD		;データ EEPROM メモリにアクセス

rdeep01		movlb	3			;バンク 3
		bsf	EECON1,RD		;読み出し開始
		movf	EEDATL,W		;データの読み出し
		incf	EEADRL,F		;記録アドレスの更新
		movlb	0			;バンク 0

		btfsc	work1,0			;先頭バイトチェック済みフラグ = 1 か？
		goto	rdeep02			;Yes

		; 先頭バイトのチェック

		movwf	work2
		bsf	work1,0			;先頭バイトチェック済みフラグ = 1
		movf	work2,W
		btfsc	STATUS,Z		;先頭バイト = h'00' か？
		goto	rdeep03			;Yes

		; 先頭バイト != h'00' の場合

rdeep02		movwi	FSR0++			;タイマー用メモリへ書き込み
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	rdeep01			;No
		goto	rdeep04

		; 先頭バイト = h'00' の場合

rdeep03		clrw
		movwi	FSR0++			;タイマー用メモリへ書き込み
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	rdeep03			;No

rdeep04		return

;
;==========================================================================
; menu_no = 9		スリープまでの移行時間（分）の変更
;==========================================================================

;	[スイッチ操作]
;		                           ENABLE   START/
;		          ZERO    TMODE    /ALARM    GOAL
;		┌─┐   ┌─┐   ┌─┐   ┌─┐   ┌─┐
;		│●│   │●│   │●│   │●│   │●│
;		└─┘   └─┘   └─┘   └─┘   └─┘
;		 EXIT     DOWN      UP      LEFT     RIGHT

;		 LEFT スイッチ ..... ブリンク位置のポインタを - 1
;		RIGHT スイッチ ..... ブリンク位置のポインタを + 1

;		 DOWN スイッチ ..... ブリンク位置の値を - 1
;		   UP スイッチ ..... ブリンク位置の値を + 1

;		 DOWN スイッチ +
;		   UP スイッチ ..... すべてのデフォルト値を一括設定

;		   UP スイッチ +
;		 DOWN スイッチ ..... すべてのデフォルト値を一括設定

;		 LEFT スイッチ + 
;		RIGHT スイッチ ..... 「スリープ移行時間の変更」を中断し、「メニューの選択」に戻る

;		RIGHT スイッチ + 
;		 LEFT スイッチ ..... 「スリープ移行時間の変更」を中断し、「メニューの選択」に戻る

;		 EXIT スイッチ ..... 「メニューの選択」に戻る

;	(関連フラグ)	stat_flg: 進行状態フラグ

;				> bit7: メモリ書き込み指示フラグ
;				> bit6: スイッチ入力有りフラグ
;				  bit5: ラップタイム表示済みフラグ
;				  bit4: ラップタイム表示指示フラグ
;				  bit3: ストップウオッチ動作終了フラグ
;				  bit2: ストップウオッチ動作中フラグ
;				  bit1: 経過時間更新フラグ
;				  bit0: 現在時刻更新フラグ

;			stat2_flg: 進行状態-2フラグ

;				> bit7: 処理終了（エグジット）フラグ
;				  bit6: 例外終了（次処理に移行）フラグ
;				  bit5: 画面変更フラグ / 現在時刻表示指示フラグ（兼用）
;				  bit4: タイムアウトフラグ
;				  bit3: 1/100秒更新フラグ / 1 秒更新フラグ（兼用）
;				  bit2: 状態変化割り込み記憶フラグ
;				  bit1: スリープ中状態フラグ
;				  bit0: スリープ移行時間チェックフラグ

;--------------------------------------------------------------------------

sleep_time_set

		call	xbuzzer_pipo2		;"ピポッピポッ" アラーム音出力と LED(緑)点滅 (Total 520 mS)

		clrf	blk_point		;ブリンク位置 = 0 初期設定

		; 「スリープ移行時間の変更」画面の表示

		;	[ M1,M4,M5 ]		;１行目 ... スリープ移行時間メッセージ
		;	  01234567

		xDisp_I2cLcd	h'80',sleep_time_msg,1	;表示位置指定 (１行目先頭)

		;	[ xx xx xx ]		;２行目 ... 分カウンタの表示
		;	  01234567

slptm01		movlw	h'0c'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=0: 非ブリンク
		movlw	h'c0'			;(２行目先頭)
		call	xI2cLcd_Cmd		;M1 の表示位置

		movf	menu_1,W		;menu_1 分カウンタ
		call	dec2chr_disp		;menu_1 分カウンタの表示
		movlw	' '			;' '
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	menu_4,W		;menu_4 分カウンタ
		call	dec2chr_disp		;menu_4 分カウンタの表示
		movlw	' '			;' '
		call	xI2cLcd_Data		;I2C LCD へデータを１文字出力

		movf	menu_5,W		;menu_5 分カウンタ
		call	dec2chr_disp		;menu_5 分カウンタの表示

		; 各スイッチの入力チェック

slptm02		bcf	stat_flg,6		;スイッチ入力有りフラグ = 0
		call	blk_point_table3	;ブリンク表示位置の DDRAM アドレスを取得
		iorlw	h'c0'			;表示位置 (ブリンク位置)を指定 (２行目)
		call	xI2cLcd_Cmd		;LCD へコマンドを出力
		movlw	h'0d'			;表示オン／オフコントロール
		call	xI2cLcd_Cmd		;D=1: 表示オン, C=0: カーソル非表示, B=1: ブリンク

slptm03		btfss	PORTB,_swLEF		;LEFT スイッチ = ON か？
		call	slp_left_switch		;Yes

		btfss	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		call	slp_right_switch	;Yes

		btfsc	stat2_flg,7		;処理終了フラグ = 1 (中断) か？
		goto	slptm04			;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	slptm02			;Yes

		btfss	PORTB,_swDWN		;DOWN スイッチ = ON か？
		call	slp_down_switch		;Yes

		btfss	PORTB,_swUP		;UP スイッチ = ON か？
		call	slp_up_switch		;Yes

		btfsc	stat_flg,6		;スイッチ入力有りフラグ = 1 か？
		goto	slptm01			;Yes

		btfsc	PORTB,_swEXT		;EXIT スイッチ = ON か？
		goto	slptm03			;No

		; 「スリープ移行時間の変更」の終了

		call	xwait_15ms		;チャッタリング吸収
		btfss	PORTB,_swEXT		;EXIT スイッチ = OFF か？
		goto	$ - 1			;No

		call	xwait_15ms		;チャッタリング吸収
		btfsc	stat_flg,7		;メモリ書き込み指示フラグ = 1 か？
		call	write_sleep_time	;Yes. EEPROM にバックアップ
		goto	slptm05

slptm04		btfsc	stat_flg,7		;メモリ書き込み指示フラグ = 1 か？
		call	read_sleep_time		;Yes. EEPROM のバックアップデータに戻す

slptm05		movlp	high main
		goto	main			;「メニューの選択」に戻る

;--------------------------------------------------------------------------

		; ブリンク表示位置テーブル

blk_point_table3
		movf	blk_point,W		;ブリンク位置ポインタ
		brw

		;	0     1     2   	;  0  1   2  ... blk_point
		;	"M1"  "M4"  "M5"	; "xx xx xx" ... 桁
		;				;  01234567
		dt	h'40',h'43',h'46'	;            ... DDRAM のアドレス (２行目)

;--------------------------------------------------------------------------
;	  LEFT スイッチの処理 ...「スリープ移行時間の変更」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 LEFT スイッチ ..... ブリンク位置のポインタを - 1

;		 LEFT スイッチ + 
;		RIGHT スイッチ ..... 「スリープ移行時間の変更」を中断し、「メニューの選択」に戻る

slp_left_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swLEF		;再度 LEFT スイッチ = ON か？
		goto	sllef04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		decf	blk_point,F		;ブリンク位置ポインタ - 1
		incf	blk_point,W
		movlw	2
		btfsc	STATUS,Z		;blk_point = -1(W=0) か？
		movwf	blk_point		;Yes. blk_point = 2 に設定

sllef01		btfsc	PORTB,_swLEF		;LEFT スイッチ = ON か？
		goto	sllef03			;No

		btfsc	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		goto	sllef01			;No

		bsf	stat2_flg,7	;;	;処理終了フラグ = 1 (中断終了)

sllef02		comf	PORTB,W			;全ビットを反転
		andlw	h'c0'
		btfss	STATUS,Z		;LEFT スイッチ and RIGHT スイッチ = OFF か？
		goto	sllef02			;No

sllef03		call	xwait_15ms		;チャッタリング吸収

sllef04		return

;--------------------------------------------------------------------------
;	 RIGHT スイッチの処理 ...「スリープ移行時間の変更」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		RIGHT スイッチ ..... ブリンク位置のポインタを + 1

;		RIGHT スイッチ + 
;		 LEFT スイッチ ..... 「スリープ移行時間の変更」を中断し、「メニューの選択」に戻る

slp_right_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swRIG		;再度 RIGHT スイッチ = ON か？
		goto	slrig04			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		incf	blk_point,F		;ブリンク位置ポインタ + 1
		movlw	2 + 1
		subwf	blk_point,W		;blk_point - (2 + 1)
		btfsc	STATUS,C		;blk_point < (2 + 1) か？
		clrf	blk_point		;No. blk_point = 0 に設定

slrig01		btfsc	PORTB,_swRIG		;RIGHT スイッチ = ON か？
		goto	slrig03			;No

		btfsc	PORTB,_swLEF		;LEFT スイッチ = ON か？
		goto	slrig01			;No

		bsf	stat2_flg,7	;;	;処理終了フラグ = 1 (中断終了)

slrig02		comf	PORTB,W			;全ビットを反転
		andlw	h'c0'
		btfss	STATUS,Z		;RIGHT スイッチ and LEFT スイッチ = OFF か？
		goto	slrig02			;No

slrig03		call	xwait_15ms		;チャッタリング吸収

slrig04		return

;--------------------------------------------------------------------------
;	 DOWN スイッチの処理 ...「スリープ移行時間の変更」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		 DOWN スイッチ ..... ブリンク位置の値を - 1

;		 DOWN スイッチ +
;		   UP スイッチ ..... すべてのデフォルト値を一括設定

slp_down_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	sldwn06			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		bsf	stat_flg,7	;;	;メモリ書き込み指示フラグ = 1

sldwn01		btfsc	PORTB,_swDWN		;DOWN スイッチ = OFF か？
		goto	sldwn02			;Yes

		btfsc	PORTB,_swUP		;UP スイッチ = ON か？
		goto	sldwn01			;No

		; デフォルト値の一括設定
		movlw	3
		movwf	menu_1			;menu_1 分カウンタのデフォルト値 = 3
		movlw	1
		movwf	menu_4			;menu_4 分カウンタのデフォルト値 = 1
	;	movlw	1
		movwf	menu_5			;menu_5 分カウンタのデフォルト値 = 1
		goto	sldwn05

		; 個別の変更設定
sldwn02		movf	blk_point,W
		btfss	STATUS,Z		;blk_point = 0 か？
		goto	sldwn03			;No

		decf	menu_1,F		;menu_1 分カウンタのデクリメント
		btfsc	STATUS,Z		;menu_1 分カウンタ = 0 か？
		incf	menu_1,F		;Yes. +1
		goto	sldwn05

sldwn03		decf	blk_point,W
		btfss	STATUS,Z		;blk_point = 1 か？
		goto	sldwn04			;No

		decf	menu_4,F		;menu_4 分カウンタのデクリメント
		btfsc	STATUS,Z		;menu_4 分カウンタ = 0 か？
		incf	menu_4,F		;Yes. +1
		goto	sldwn05

sldwn04		decf	menu_5,F		;menu_5 分カウンタのデクリメント
		btfsc	STATUS,Z		;menu_5 分カウンタ = 0 か？
		incf	menu_5,F		;Yes. +1

sldwn05		comf	PORTB,W			;全ビットを反転
		andlw	h'0c'
		btfss	STATUS,Z		;DOWN スイッチ and UP スイッチ = OFF か？
		goto	sldwn05			;No

		call	xwait_15ms		;チャッタリング吸収

sldwn06		return

;--------------------------------------------------------------------------
;	  UP スイッチの処理 ...「スリープ移行時間の変更」から CALL
;--------------------------------------------------------------------------

;	[スイッチ操作]

;		   UP スイッチ ..... ブリンク位置の値を + 1

;		   UP スイッチ +
;		 DOWN スイッチ ..... すべてのデフォルト値を一括設定

slp_up_switch

		call	xwait_15ms		;チャッタリング吸収
		btfsc	PORTB,_swUP		;再度 UP スイッチ = ON か？
		goto	slup06			;No

		bsf	stat_flg,6		;スイッチ入力有りフラグ = 1
		bsf	stat_flg,7	;;	;メモリ書き込み指示フラグ = 1

slup01		btfsc	PORTB,_swUP		;UP スイッチ = OFF か？
		goto	slup02			;Yes

		btfsc	PORTB,_swDWN		;DOWN スイッチ = ON か？
		goto	slup01			;No

		; デフォルト値の一括設定
		movlw	3
		movwf	menu_1			;menu_1 分カウンタのデフォルト値 = 3
		movlw	1
		movwf	menu_4			;menu_4 分カウンタのデフォルト値 = 1
	;	movlw	1
		movwf	menu_5			;menu_5 分カウンタのデフォルト値 = 1
		goto	slup05

		; 個別の変更設定
slup02		movf	blk_point,W
		btfss	STATUS,Z		;blk_point = 0 か？
		goto	slup03			;No

		incf	menu_1,F		;menu_1 分カウンタのインクリメント
		btfsc	menu_1,4		;menu_1 分カウンタ = 16 か？
		decf	menu_1,F		;Yes. -1
		goto	slup05

slup03		decf	blk_point,W
		btfss	STATUS,Z		;blk_point = 1 か？
		goto	slup04			;No

		incf	menu_4,F		;menu_4 分カウンタのインクリメント
		btfsc	menu_4,4		;menu_4 分カウンタ = 16 か？
		decf	menu_4,F		;Yes. -1
		goto	slup05

slup04		incf	menu_5,F		;menu_5 分カウンタのインクリメント
		btfsc	menu_5,4		;menu_5 分カウンタ = 16 か？
		decf	menu_5,F		;Yes. -1

slup05		comf	PORTB,W			;全ビットを反転
		andlw	h'0c'
		btfss	STATUS,Z		;UP スイッチ and DOWN スイッチ = OFF か？
		goto	slup05			;No

		call	xwait_15ms		;チャッタリング吸収

slup06		return

;--------------------------------------------------------------------------
;		スリープ移行時間（分）を EEPROM へ書き込み
;--------------------------------------------------------------------------

write_sleep_time

		movlw	high menu_1		;menu_1 スリープ移行時間（分）カウンタのアドレス
		movwf	FSR0H			;
		movlw	low menu_1		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	3			;書き込みバイト数
		movwf	lp_cnt1			;ループカウンタ1

		movlb	3			;バンク 3
		movlw	low eep_sleep_time
		movwf	EEADRL			;EEPROM の記録アドレスを設定
		bcf	EECON1,CFGS		;フラッシュプログラム/データ EEPROM メモリを選択
		bcf	EECON1,EEPGD		;データ EEPROM メモリにアクセス

wrslp01		movlb	3			;バンク 3
		moviw	FSR0++			;BCD カウンタデータの読み出し
		movwf	EEDATL			;書き込みデータを設定

		bsf	EECON1,WREN		;プログラム/消去サイクルを許可
	;	bcf	INTCON,GIE		;割り込みを禁止
		movlw	h'55'
		movwf	EECON2			;h'55' を EECON2 に書き込む
		movlw	h'aa'
		movwf	EECON2			;h'aa' を EECON2 に書き込む

		bsf	EECON1,WR		;書き込み開始
	;	bsf	INTCON,GIE		;割り込みを許可
		bcf	EECON1,WREN		;プログラム/消去サイクルを禁止
		btfsc	EECON1,WR		;書き込み 終了か?
		goto	$ - 1			;No

		incf	EEADRL,F		;記録アドレスの更新

		movlb	0			;バンク 0
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	wrslp01			;No

		return

;--------------------------------------------------------------------------
;		スリープ移行時間（分）を EEPROM から読み出し
;--------------------------------------------------------------------------

read_sleep_time

		movlw	high menu_1		;menu_1 スリープ移行時間（分）カウンタのアドレス
		movwf	FSR0H			;
		movlw	low menu_1		;
		movwf	FSR0L			;間接アドレスに設定

		movlw	3			;読み出しバイト数
		movwf	lp_cnt1			;ループカウンタ1

		movlb	3			;バンク 3
		movlw	low eep_sleep_time
		movwf	EEADRL			;EEPROM の記録アドレスを設定
		bcf	EECON1,CFGS		;フラッシュプログラム/データ EEPROM メモリを選択
		bcf	EECON1,EEPGD		;データ EEPROM メモリにアクセス

rdslp01		movlb	3			;バンク 3
		bsf	EECON1,RD		;読み出し制御 = ON
		movf	EEDATL,W		;データの読み出し
		movwi	FSR0++			;BCD カウンタデータへ書き込み
		incf	EEADRL,F		;記録アドレスの更新

		movlb	0			;バンク 0
		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	rdslp01			;No

		return

;==========================================================================
;		EEPROM エリア
;==========================================================================

		org	h'f000'

eeprom_start	de	"Copyright (C) 2023 by M.Yamamoto"

		de	h'ff'

		; スリープ移行時間（分）のバックアップ格納位置

eep_sleep_time
		de	3,1,1			;初期（デフォルト）値

		; インターバルタイマーの格納位置

itv_timer_memory
		de	h'00',h'00',h'00'	;初期値

		; タイマー用メモリのバックアップ格納位置

eep_timer_memory
		de	h'00'			;初期値

		; (3 * timer_capacity) バイトサイズを使用

;==========================================================================

		end				;プログラムの終了
