;***** NixieTubeClockIII.asm **********************************************
;
;	６桁ニキシー管時計 III（IN-17）
;
;	Copyright (C) 2024   by M.Yamamoto. All rights reserved.
;
;	Homepage URL: https://xyama.sakura.ne.jp/hp/NixieTubeClockIII.html
;
;     ( coding:  Ver. 0.00   2024/03/06  by M.Yamamoto )
;	coding:  Ver. 1.00   2024/03/20  基本機能の組み込み
;	update:  Ver. 1.10   2024/03/26  タイマースイッチ機能等を追加
;	update:  Ver. 1.11   2024/04/01  間隔制御,直接制御を追加
;	update:  Ver. 1.12   2024/04/15  <機能概要と使用法>を追加
;	update:  Ver. 1.13   2024/04/25  温度センサ DS18B20 に変更
;	update:  Ver. 1.14   2024/05/09  小バグ等の吸収と各種調整
;	bugfix:  Ver. 1.15   2024/05/15  bcd_yh BCDカウンタの初期設定忘れ
;	bugfix:  Ver. 1.15a  2024/05/24  signal_switch 訂正
;
;******************************************************* PicAsm 0266 ******

;	Device: PIC16F886	Clock: 8MHz (Internal OSC)

;==========================================================================

#ifdef comment

 このファイル（NixieTubeClockIII.asm）はテキストファイルであり、現在、Windows メモ帳 11.2401.26.0 によって書い
 ているが、ファイル中で使用している罫線（コメントで多用）の表示処理がうまくできず、同メモ帳では見た目がぐちゃ
 ぐちゃになる。ただし、現時点（2024/04/15）においては Microsoft Edge 123.0.2420.81 では、問題なく表示ができる
 のでドラッグ＆ドロップして同ブラウザで見るように！！

 ------------------
 <機能概要と使用法>
 ------------------

---------------------
◎ 本機の起動時の動作
---------------------

・本機に電源を投入すると、"ピポッ" と開始ブザー音を出力後に、ブルー LED の簡単な点灯デモ (1) が８秒間行われ、続
　いて９から０までの数字を１秒間ずつ降順に更新しながら、ニキシー全管（６本）の ９～０表示テストを計 10秒間行う。

・続いて、ブルー LED の簡単な点灯デモ (2) が約７秒間行われた後、プログラムのバージョン番号がニキシー管に約５秒
　間表示される。

		バージョン番号		[ _x.xx __ ]

・その後、ニキシー管、ブルー LED ともに１秒間 全桁消灯の後、RTC（リアルタイムクロック）モジュール "DS3231 For 
　PI" の状態がチェックされ、本機に初めて電源を入れたときや、バックアップ用バッテリーが異常なとき等に、次のエラ
　ーメッセージがニキシー管に表示されるとともに、"ブッブー" ブザー音が出力される。このとき、先頭の文字 "9" はエ
　ラーメッセージであることを表し、細かくブリンク表示をしてエラーであることを強調する。

		エラーメッセージ	[ 9_.32 31 ]

・ユーザはバックアップ用バッテリーの状態等を確認してその対処を行った後、全８つのスイッチの内のどれかを押して応
　答をする。

・すると、RTC（リアルタイムクロック）モジュールが初期設定され、エラーフラグがクリアされるとともに、年月日、時分
　秒がモジュールをプログラミングしたときの初期値、"2024/01/01"、"00：00：00" に設定がされて時計機能が開始される
　が、これらは現在値とは異なるため、後述のスイッチ操作による手順（SET モードの操作機能を参照）で現在の年月日、
　時分秒に設定をし直す必要がある。ちなみに "2024/01/01" は "月曜日" である。

		年月日表示　[ 24:01:01 ]	時間表示　[ 00:00:00 ]

-----------------------------
◎ 表示モードと基本機能の操作
-----------------------------

・そのスイッチ操作による手順の説明の前に、本機における表示モードと本機の基本機能を先に説明をしておくと、本機に
　は上述の時間表示の他に、年月日表示（年表示は西暦４桁の内、下２桁のみ表示）、気温表示の機能を持っている。

		表示モード 0          	  	表示モード 1          	  	表示モード 2
		時間表示　[ xx:xx:xx ]		年月日表示　[ xx.xx.xx ]	気温表示　[ __ xx.xx ]

・気温表示については、デジタル温度センサ "DS18B20" の性能そのままを使用しているため、- 55 ℃ ～ + 125 ℃ の範囲
　で測定が可能で、本機ではバイナリデータから BCD データに変換をする過程で、小数点以下２位までを表示対象として、
　３位以降は切り捨てて無視をしている。また、マイナス値の表記については、マイナスを表す記号が使用したニキシー管
　にないため、HL 桁（左から２桁目）に数字 "9" を表示することでマイナス値を表す。


・なお、上述の表示モード0 ～ 表示モード2 の他に、オートモードの表示モード3 もあって、これらは MODE / SET スイッ
　チを押すごとにモード番号が増加をし、ニキシー管に表示される内容が切り替わる。そして表示モード3 の次は 再び表示
　モード0 に戻る。

		┌─→ 時間表示 ─→ 年月日表示 ─→ 気温表示 ─→ オートモード ──┐
		│　　(モード 0)　　 (モード 1)　　 (モード 2)　　　(モード 3)　　　│
		│　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　│
		└─────────────────────────────────┘

・このとき、MODE スイッチを何度も続けて押していると、現在のモードがどれなのか分かり辛くなるときがあるため、MODE 
　スイッチを押した直後に、ニキシー管の１桁目（最左端桁）にそのときのモード種類の番号（ 0 ～ 3 の内のどれか）を、 
　約３秒間ブリンク表示をして知らせる。

・オートモード(表示モード3) を選択したときには、表示モード0 ～ 表示モード2 の個々の内容表示を、次図に示すように
　自動的に切り替えて、それぞれの表示を繰り返す。

		毎05～09秒と35～39秒の間：　年月日表示
		毎20～24秒と50～54秒の間：　気温表示
		上記以外：　　　　　　　　　時間表示

		(___: 時間表示、NNN: 年月日表示、KKK: 気温表示)

		00        10        20        30        40        50        00
		.    .    .    .    .    .    .    .    .    .    .    .    .
		_____NNNNN__________KKKKK__________NNNNN__________KKKKK_____

・なお、これらの表示モード0 ～ 表示モード3 を表示しているときの状態を、表示モードとは別に NORMAL モード という。
　そして、この NORMAL モード中のときにはニキシー管の表示だけではなく、ブルー LED を次の表示パターン（○は点灯、
　●は消灯）によってその日の曜日を表し、１秒ごとに点灯、消灯を反転させながら繰り返し表示する。

	┌───┬─────────────────┐　┌───┬─────────────────┐
	│      │         ブルー LED の桁          │　│      │         ブルー LED の桁          │
	│      ├──┬──┬──┬──┬──┬──┤　│      ├──┬──┬──┬──┬──┬──┤
	│      │ HH │ HL │ MH │ ML │ SH │ SL │　│      │ HH │ HL │ MH │ ML │ SH │ SL │
	├─┬─┼──┼──┼──┼──┼──┼──┤　├─┬─┼──┼──┼──┼──┼──┼──┤
	│  │日│ ○ │ ○ │ ○ │ ○ │ ○ │ ○ │　│  │日│ ● │ ● │ ● │ ● │ ● │ ● │
	│  ├─┼──┼──┼──┼──┼──┼──┤　│  ├─┼──┼──┼──┼──┼──┼──┤
	│  │月│ ● │ ○ │ ○ │ ○ │ ○ │ ○ │　│  │月│ ○ │ ● │ ● │ ● │ ● │ ● │
	│  ├─┼──┼──┼──┼──┼──┼──┤　│  ├─┼──┼──┼──┼──┼──┼──┤
	│  │火│ ○ │ ● │ ○ │ ○ │ ○ │ ○ │　│  │火│ ● │ ○ │ ● │ ● │ ● │ ● │
	│曜├─┼──┼──┼──┼──┼──┼──┤　│曜├─┼──┼──┼──┼──┼──┼──┤
	│  │水│ ○ │ ○ │ ● │ ○ │ ○ │ ○ │　│  │水│ ● │ ● │ ○ │ ● │ ● │ ● │
	│日├─┼──┼──┼──┼──┼──┼──┤　│日├─┼──┼──┼──┼──┼──┼──┤
	│  │木│ ○ │ ○ │ ○ │ ● │ ○ │ ○ │　│  │木│ ● │ ● │ ● │ ○ │ ● │ ● │
	│  ├─┼──┼──┼──┼──┼──┼──┤　│  ├─┼──┼──┼──┼──┼──┼──┤
	│  │金│ ○ │ ○ │ ○ │ ○ │ ● │ ○ │　│  │金│ ● │ ● │ ● │ ● │ ○ │ ● │
	│  ├─┼──┼──┼──┼──┼──┼──┤　│  ├─┼──┼──┼──┼──┼──┼──┤
	│  │土│ ○ │ ○ │ ○ │ ○ │ ○ │ ● │　│  │土│ ● │ ● │ ● │ ● │ ● │ ○ │
	└─┴─┴──┴──┴──┴──┴──┴──┘　└─┴─┴──┴──┴──┴──┴──┴──┘
		  初めの１秒間の表示パターン			   次の１秒間の表示パターン

・このブルー LED の曜日表示は四六時中行われるので、煩わしく感じられるようなときがあるかもしれない。そこで DELETE
　/ DOWN スイッチを押しながら MODE / SET スイッチを押すことによって、その表示をいつでも抑止することができる。
　このスイッチ操作はトグル動作になっていて、押す度に 表示／非表示 を繰り返す。ただし、このスイッチ操作は四六時
　中行われる曜日表示に限って有効であり、その他の一時的に行われるブルー LED 表示についてはその限りではない。

・本機では１２／２４時間の両表示機能を持ち、通常の NORMAL モード中であれば TMODE / UP スイッチを押すことによっ
　て、いつでも切り替えることができる。すなわち、時間表示(表示モード0) 中だけでなく、年月日表示(表示モード1) ～ 
　オートモード(表示モード3) 中であっても切り替えられる。ただし、時間表示(表示モード0) とオートモード(表示モード
　3) の時間表示中以外のときには、切り替わったことを目で確認することはできない。

・次に、２４時間表示と１２時間表示の両者の対応を示すが、本機では、２４時間表示では "時" の表示に "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

・１２時間表示の場合には午前と午後との区別をさせるため、左列の :（コロン）の上側 LEDで AM を、また下側 LEDで PM 
　を、１秒ごとに点滅を繰り返すことで、それぞれを表現している

					　　┌─ AM
					　　↓
		１２時間表示		[ xx：xx：xx ]
					　　↑
					　　└─ PM

・ZERO / BACK スイッチは、後述する SET モード中を除いた NORMAL モード中には、毎正時プラス・マイナス５分以内に押
　された場合に限り、00 分 00 秒に設定をするための ZERO スイッチとして機能をする。

・SIGNAL スイッチは、毎時の時報音や後述のタイマー機能時の効果音等を、押すごとに有効／無効に交互に設定をする。こ
　のときの設定状態は視覚的な表示がないため、有効になったときには "ピピピッ" 音を、無効になったときには "ブー" 
　音を、それぞれ鳴らして知らせる。なお、電源を投入した直後は有効状態に設定がされている。また、有効に設定時には、
　時間表示(表示モード0) 以外の表示モードにおいても、毎時の時報音やタイマー機能時の効果音等は有効（鳴る）なので
　注意が必要である。

・年月日カレンダー機能について、うるう年の計算は 2001年 ～ 2399年までの範囲で対応している。ただし、年の表示は下
　２桁のみになる。

・その他の機能として、周囲の明るさに応じてニキシー管の表示を減光するディマー機能を持ち、周囲が明るいときはニキ
　シー管の表示も明るく、周囲が暗くなるとニキシー管も暗く表示される。

・なお、本機での気温表示のために使用している、デジタル温度センサ "DS18B20" からのデータ読み出しは２秒ごとに行っ
　て、表示モード 2 のときにはその表示を更新させている。温度センサと通信を行うときには常に温度センサの状態がチェ
　ックされ、エラーを検出したときには次のエラーメッセージがニキシー管に表示されるとともに、"ブッブー" ブザー音が
　出力される。このとき、先頭の文字 "9" はエラーメッセージであることを表し、細かくブリンク表示をしてエラーである
　ことを強調する。

		エラーメッセージ	[ 9_.18 20 ]

・ユーザは温度センサの状態等を確認してその対処を行った後、全８つのスイッチの内のどれかを押して応答をする。例え
　ば、温度センサとの接続用のコネクタが抜けていた場合などには、接続をし直せばエラーは回復するが、それ以外の場合
　には簡単にエラーが回復することはないので、原因を追究する必要がある。

-------------------------
◎ SET モードの機能と操作
-------------------------

・さて、ここで話を戻して、年月日、時分秒の設定を変更する手順としては、現在、NORMAL モード 中であれば、時間表示
　(表示モード0) ～ オートモード(表示モード3)のどの内容が表示されている場合においても可能で、まず、表示内容（表
　示モード）を切り替えるときのように "チョン押し" ではなく、同じ MODE / SET スイッチを "長押し" することによっ
　て、年月日、時分秒を自由に変更することができる SET モード に移行をする。

・すなわち、MODE / SET スイッチを５秒以上 "長押し" をしていると、"ピッ" というブザー音とともにニキシー管は全桁
　消灯して、ブルー LED が全桁 1/4 秒点灯 1/4 秒消灯の 0.5 秒周期でブリンク表示を始め、NORMAL モードから SET モ
　ード に移行をしたことを知らせる。

・ユーザは、ブルー LED の全桁ブリンク表示を合図として MODE / SET スイッチから指を離すと、ブリンク表示をしていた
　ブルー LED は全桁消灯し、現在、RTC（リアルタイムクロック）モジュールに設定がされている、"年月日６桁" が年月日
　の表示パターンでニキシー管に表示され、かつ、先頭の "年２桁" がブリンク表示をしてこれから設定変更を行う対象項
　目であることを知らせる。

・もし変更が必要であれば、UP スイッチを押すごとに現在値より１ずつ増加し、また DOWN スイッチを押すごとに１ずつ減
　少するので、適宜希望する値に変更をする。また、このときの増減幅を大きくしたい場合には、UP スイッチ、 または 
　DOWN スイッチを押したままにしていると、１秒当たり 4 ～ 5 の増減幅で更新をするようになる。

・"年２桁" の変更が済んだら、再び MODE / SET スイッチを押すと、次には "月２桁" にブリンク表示が移り、変更の対象
　項目も移動したことを示す。同様に変更が必要であれば、UP スイッチ、または DOWN スイッチを押すことによって、適宜
　希望する値に変更をする。 

・以降同様に、SET スイッチを押すごとに "年"、"月"、"日"、"時"、"分"、"秒" と、変更の対象項目（２桁ずつのブリン
　ク表示位置（~~））が移動するので、該当の項目を選択後 UP または DOWN スイッチによって値を変更設定する。このと
　き、"日" から "時" に対象項目が移動すると、時間表示パターンに切り替わる。両者での見かけ上の違いは、各項目間の
　区切り記号表示が前者ではピリオド(.) 、後者ではコロン(:)となる。

		"年" が選択　[ xx.xx.xx ]	"月" が選択　[ xx.xx.xx ]	"日" が選択　[ xx.xx.xx ]
		　　　　　　　 ~~        	　　　　　　　    ~~        	　　　　　　　       ~~
		"時" が選択　[ xx:xx:xx ]	"分" が選択　[ xx:xx:xx ]	"秒" が選択　[ xx:xx:xx ]
		　　　　　　　 ~~        	　　　　　　　    ~~        	　　　　　　　       ~~
・なお、NORMAL モード時に１２時間表示が選択されていた場合、SET モードで "時"、"分"、"秒" を選択中には、左列の 
　:（コロン）の上側 LED点灯 + 下側 LED消灯で AM を、上側 LED消灯 + 下側 LED点灯で PM を、それぞれ表現をする。

・そして、最後の "秒２桁" 設定後にもう一度 SETスイッチを押すことによって、変更された設定値（ "年" ～ "秒" のす
　べて* ）が RTC（リアルタイムクロック）モジュールに書き込まれる。そして、年月日、時分秒の設定変更の処理が終了
　して、SET モードから抜け出して再び NORMAL モード に移行をし、必ず時間表示(表示モード0) に戻って、新たに設定し
　直した時分秒から時（とき）を刻み続ける。

　　* "年" ～ "秒" のすべて:　"年"、"月"、"日" が変更されれば "曜日" も変更するが、"曜日" についてはユーザが入
　　　　　　　　　　　　　　　力しなくても、プログラムが自動的に計算をした "曜日" 値を一緒に RTC に書き込む。

・この SET スイッチによって対象項目を選択中に、誤って希望する項目を通り過ぎてしまったような場合には、BACK スイ
　ッチを押すごとに、ひとつずつ前の項目に戻ることができる。これらの SET スイッチ、または BACK スイッチの操作と、
　各選択項目の関係を図に表すと次のようになる。

	　　　　　　　　　　　　　　　　 BACK  　BACK  　BACK  　BACK  　BACK
	　　　　　　　　　　　　　　　　 ←─ 　 ←─ 　 ←─ 　 ←─ 　 ←─
	　　　　　　　　　　　　 SET  　 SET  　 SET  　 SET  　 SET  　 SET  　 SET
	４つのどれかの表示モード ─→ 年 ─→ 月 ─→ 日 ─→ 時 ─→ 分 ─→ 秒 ─→ 時間表示モード(表示モード0) 
	　　　　　　　　　　　　　　　│　　　　　　　　　　　　　　　　　　　↑
	　　　　　　　　　　　　　BACK└───────────────────┘

・また、SET モードに移行中に何らかの理由で、設定変更の処理を中止したいような場合には、SIGNAL / CANCEL スイッチ
　を押すことによって、それまでに設定変更されてきた各項目値はすべて破棄され、RTC（リアルタイムクロック）モジュー
　ルに書き込まれることはなく、再び NORMAL モード に移行をする。

-------------------------
◎ タイマー機能関連の操作
-------------------------

・本機には、CH1 と CH2 の２個のスイッチ（リレー）が搭載してあり、それぞれのスイッチ（リレー）を次の方法で個々に
　コントロールすることができる。

　(1) タイマースイッチの設定　　　　 ..... "CH1 スイッチ（リレー）を、何曜日の何時何分にどのようにするか" を設
　　　　　　　　　　　　　　　　　　　　　 定する
　(2) 温度スイッチの設定　　　　　　 ..... "CH2 スイッチ（リレー）を、何曜日に温度が何℃になったらどのようにす
　　　　　　　　　　　　　　　　　　　　　 るか" を設定する
　(3) インターバル・タイマーの設定　 ..... "CH1 または CH2 スイッチ（リレー）を、温度には関係なく、現在の時刻
　　　　　　　　　　　　　　　　　　　　　 から何時間何分後にどのようにするか" を設定する
　(4) ダイレクト・コントロールの設定 ..... "CH1 または CH2 スイッチ（リレー）を、時間、温度には関係なく、直ち
　　　　　　　　　　　　　　　　　　　　　 にどのようにするか" を設定する

・タイマー機能関連の操作を行うためには、CH1、CH2、CH3 の３個のタクトスイッチと、上述してきた５個のタクトスイッ
　チのすべてを使用する。CH1 タクトスイッチ は上で述べた (1) タイマースイッチの設定 専用であり、CH2 タクトスイッ
　チは (2) 温度スイッチの設定専用である。また、CH3 タクトスイッチは (3) インターバル・タイマーの設定、または
　(4) ダイレクト・コントロールの設定 関連のときに使用する。
　（以降、紛らわしいので、CH1 ～ CH3 タクトスイッチを CH1 ～ CH3 スイッチといい、CH1、CH2 スイッチ（リレー）を
　CH1、CH2 リレーという。）

・また、これらのタイマースイッチ機能、温度スイッチ機能等のユーザー・インターフェースとしての操作には、あらかじ
　めそれらの情報をメモリに設定をしておくための メモリ設定機能、メモリに設定されている情報をいつでも読み出して確
　認ができるメモリ読み出し機能、不要になったメモリ情報を消去するためのメモリ消去機能がある。

　[ メモリの設定機能 ]
　--------------------

・まず、メモリの設定機能の操作は、本機が NORMAL モードのときに、CH1 ～ CH3 スイッチ のどれかを押しながら SET ス
　イッチを押すことによって始める。CH1 ～ CH3 スイッチは上述のように、CH1 または CH2 リレーに対して、(1) ～ (4) 
　の内のどの機能を設定するかを選択するものである。

・すると、選択をした CHx スイッチによって、ニキシー管には次の３種類の内のどれかが表示される。すなわち、CH1 スイ
　ッチの場合には左側の、CH2 スイッチの場合には中央の、CH3 スイッチの場合には右側の形式で表示がされ、なおかつ、
　先頭の２桁がブリンク表示をしてこれから設定をする対象項目の位置（~~）を表している。

		CH1 スイッチ　[ 00:00 00 ]	CH2 スイッチ　[ 00.00 00 ]	CH3 スイッチ　[ 00 00 10 ]
		　　　　　　　  ~~        	　　　　　　　  ~~        	　　　　　　　  ~~

・CH1、CH3 スイッチの場合には、設定をする "時"、"分" の内の "時" の位２桁であり、CH2 スイッチの場合には、設定を
　する温度値の整数部２桁（00 ～ 79 の範囲）が設定の対象項目となる。なお、すべての設定項目の初期値は "00"、また
　は "0" が表示される。ただし、CH3 スイッチの場合には、第３項目（リレー番号）には "1" が表示される。

・それぞれの値を設定するには、UP スイッチを押すごとに現在値より１ずつ増加し、また DOWN スイッチを押すごとに１ず
　つ減少するので、適宜希望値に設定をする。また、このときの増減幅を大きくしたい場合には、UP スイッチ、または DOWN 
　スイッチを押したままにしていると、１秒当たり 4 ～ 5 の増減幅で更新をするようになる。

・"時" または、温度値の整数部の設定が済んだら、SET スイッチを押すと、次には "分" の位２桁または、温度値の小数部
　２桁がブリンク表示され、設定の対象項目が次に移動したことを示す。同様に、UP スイッチ、または DOWN スイッチを押
　すことによって、適宜希望値に設定をする。

		CH1 スイッチ　[ xx:00 00 ]	CH2 スイッチ　[ xx.00 00 ]	CH3 スイッチ　[ xx 00 10 ]
		　　　　　　　     ~~     	　　　　　　　     ~~     	　　　　　　　     ~~

・ここで、まず CH2 スイッチの場合について補足をしておくと、温度値の 小数部２桁 の設定ではあるが、UP スイッチ、
　または DOWN スイッチを押しても、２桁の設定値の内の先頭１桁しか設定変更することはできず、２桁目は常に "0" とな
　る。ここで設定をする温度値の整数部、小数部は、もちろん温度スイッチ機能として使用されるものであり、本機では２
　秒ごとに温度センサからの読み出しデータが更新され、その都度、温度監視プログラムが実行されて設定値と比較される。
　このときの比較される設定値は、整数部の "00" ～ "99" までと、小数部の先頭１桁の "0" ～ "9" を対象とするためで
　ある。小数部２桁目を設定しても意味がない。（おまけの説明を参照）

・次に CH3 スイッチの場合について補足をしておくと、"時"、"分" のそれぞれ２桁を指定するときに、どちらも "00" 指
　定をすると (4) ダイレクト・コントロール機能とプログラムは解釈をし、どちらかが "00" 以外であれば (3) インター
　バル・タイマー機能と解釈をする。

・"分" または、温度値の小数部の設定が済んだら、再度 SET スイッチを押すことによって、ブリンク表示が次の設定の対
　象項目に移動する。CH1、CH2 スイッチの場合には、どちらも "曜日" を次表のように指定をし、 CH3 スイッチの場合に
　は、コントロールする CH1 または CH2 スイッチ（リレー）の番号（1 または 2）を指定する。

		CH1 スイッチ　[ xx:xx 00 ]	CH2 スイッチ　[ xx.xx 00 ]	CH3 スイッチ　[ xx xx 10 ]
		　　　　　　　        ~        	　　　　　　　        ~        	　　　　　　　        ~

・"曜日" の設定方法は CH1、CH2 スイッチ共通で、UP スイッチ、または DOWN スイッチによって、次の左の対応表のよう
　に数値によって指定をする。なお、このように温度スイッチの設定にも "曜日" の条件を加えてある。

	┌───┬──┬──┬──┬──┬──┬──┬──┬──┐　┌───┬───┬───┐
	│ 曜日 │毎日│ 日 │ 月 │ 火 │ 水 │ 木 │ 金 │ 土 │　│リレー│  CH1 │  CH2 │
	├───┼──┼──┼──┼──┼──┼──┼──┼──┤　├───┼───┼───┤
	│設定値│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │　│設定値│   1  │   2  │
	└───┴──┴──┴──┴──┴──┴──┴──┴──┘　└───┴───┴───┘
			  CH1、CH2 スイッチの場合			CH3 スイッチの場合

・同様に、再々度 SET スイッチを押すと、４つ目（最後）の設定項目の右端１桁にブリンク表示が移動する。CH1 または 
　CH2 リレーの各動作種類をどのようにコントロールするかを設定するもので、UP スイッチ、または DOWN スイッチによ
　って、次の対応表のように数値によって指定をする。

		CH1 スイッチ　[ xx:xx x0 ]	CH2 スイッチ　[ xx.xx x0 ]	CH3 スイッチ　[ xx xx x0 ]
		　　　　　　　         ~        　　　　　　　         ~        　　　　　　　         ~
	┌────┬───────────┬───────┐
	│　　　　│   CH1、CH3 スイッチ  │ CH2 スイッチ │
	├────┼───┬───┬───┼───┬───┤
	│動作種類│  OFF │  ON  │  SLP │  OFF │  ON  │
	├────┼───┼───┼───┼───┼───┤
	│ 設定値 │   0  │   1  │   3  │   0  │   1  │
	└────┴───┴───┴───┴───┴───┘

・上表のように、CH2 の温度スイッチにはスリープ（SLP）動作を設定することはできない。また、CH1、CH3 スイッチにお
　いて設定値 "2" は、プログラムの内部で使用するものでユーザが設定することはできない（ON 動作をしたリレーが１時
　間後に OFF 動作をさせるときの情報に使用）。

・また、UP スイッチ、または DOWN スイッチによって、上表３つのそれぞれの設定値以外を指定しようとしても、プログラ
　ムがそれぞれで制限をかけているのでそれはできない。

・なお、これまでの SET スイッチの操作によって対象項目を選択中に、誤って希望する項目を通り過ぎてしまったような場
　合には、BACK スイッチを押すごとに、ひとつずつ前の項目に戻ることができる。また、これらの項目を設定途中に何らか
　の理由によって中止をしたいような場合には、CANCEL スイッチを押すとそれまでに設定をしてきた項目が破棄され、メモ
　リ設定機能を終了して、NORMAL モードに戻る。

・最後のリレーの動作種類を設定後、すなわち、右端１桁がブリンク表示をしているときに、もう一度 SET スイッチを押す
　と、今まで入力をしてきたタイマースイッチ、または温度スイッチの設定情報を記憶するために、プログラムは PIC 内部
　の RAM メモリに書き込み動作を行う。

・ただし、(4) ダイレクト・コントロール機能の SLP 以外の設定では、直ちに指定されたリレーの ON、または OFF 動作を
　行い、必要がないので RAM メモリに書き込みを行うことはない。また、SLP 設定のときには直ちに指定されたリレーの
　ON 動作を行い、かつ、１時間後の OFF 動作時の時刻をプログラムが計算をして RAM メモリに書き込む。そして、これら
　の ON/OFF/SLP 動作後には NORMAL モードに戻る。また、SLP 設定のときには１時間後の OFF 動作実行後には、自動的に 
　RAM メモリから削除される。

・また、(3) インターバル・タイマー機能では、入力された "現在の時刻から何時間何分後" を、絶対的な "何時何分" の
　時刻にプログラムが変換をして RAM メモリに書き込みを行う。やがて、設定時刻がやってきて SLP 以外の設定では、指
　定されたリレーの ON、または OFF 動作を行った後は、自動的に RAM メモリから削除される。また、SLP 設定のときには
　設定時刻になると、指定されたリレーの ON 動作を行い、かつ、次の１時間後の OFF 時刻を計算して RAM メモリの書き
　替えを行うが、やがて１時間後の OFF 動作実行後にはダイレクト・コントロール時と同様に、自動的に RAM メモリから
　削除される。

・タイマースイッチ、または温度スイッチの設定情報が正常に書き込まれると、"ピピッ" ブザー音を鳴らしてユーザにそれ
　を知らせ、再び新たなメモリ設定のために、すべての設定項目を初期値の "00"、または "0" に戻して、先頭の２桁がブ
　リンク表示をするので、続けて次の設定情報の入力を行うことができる。

・ただし、この場合には CHx スイッチは前回のものが引き継がれるので、もしも他の CHx スイッチに変更をしたい場合に
　は CANCEL スイッチを押して、一旦、それまでの CHx でのメモリの設定機能を終了させて NORMAL モードに戻し、新たに
　CH1 ～ CH3 スイッチ のどれかを押しながら SET スイッチ を押して、CHx の選択をし直す必要がある。

・これらの時間（時分）や温度等の設定情報を記憶しておくためのメモリは、本機では CH1 および CH2 リレー分を共通で
　使用し、合計 20 メモリまでを可能とする。そして、プログラムが PIC 内部の RAM メモリに書き込み動作を行うときに、
　既に 20 メモリまでが書き込まれて満タン状態の場合には、"ブッブー" ブザー音が出力されるとともにエラーメッセージ
　として、ニキシー管には全桁 "9" 表示と消灯、ブルー LED は全桁消灯と点灯とが、交互に 1/4 秒間ずつ0.5 秒周期でブ 
　リンク表示を繰り返す。

		エラーメッセージ	[ 99 99 99 ]

・このニキシー管とブルー LED とのブリンク表示は、いつまでも続くので確認後に CANCEL スイッチ を押して メモリの設
　定機能を終了させると、NORMAL モードに戻る。

　[ メモリの読み出し機能 ]
　------------------------

・次に、メモリの読み出し機能の操作は、本機が NORMAL モードのときに、CH1 ～ CH3 スイッチ のどれか１つだけを押す
　ことによって始める。本機では、CHx スイッチ別にメモリ読み出しを行うようにプログラミングがされているため、メモ
　リ内容の確認を希望する CHx スイッチを押す。

・すると、直ちに RAM メモリ内が検索されて CHx の設定情報が見つかった場合は、押した CHx スイッチによって、次の３
　種類の内のどれかの形式でニキシー管に表示がされる。メモリの設定機能のときと同形式で表示がされるが、メモリ設定
　ではないためブリンク表示が行われることはない。

		CH1 スイッチ　[ xx:xx xx ]	CH2 スイッチ　[ xx.xx xx ]	CH3 スイッチ　[ xx xx xx ]

・このとき 20 メモリの内の先頭から検索が行われ、まず、最初に見つかったメモリ内容が上記の形式で表示がされる。そ
　の後、続けて CH x スイッチを押すごとに、２番目に見つかったメモリ内容、３番目に見つかったメモリ内容、・・・ の
　順にニキシー管に表示がされる。

・やがて最終の 20 メモリを過ぎると、一旦、次のように空白表示を行い、なおも CHx スイッチが押されると、また先頭か
　らの検索に戻って以上の表示が繰り返される。

		CH1 スイッチ　[ __:__ __ ]	CH2 スイッチ　[ __.__ __ ]	CH3 スイッチ　[ __ __ __ ]

・このメモリの読み出し機能では、現在検索中の CHx（例えば CH1）スイッチのときに、異なった CHx（例えば CH2）スイ
　ッチを押した場合には、検索対象が（CH2 に）変更されて、新たに 20 メモリの内の先頭から検索がされるようになる。

・なお、CH3 スイッチによってメモリ設定が行われた情報（インターバル・タイマー時の情報（ON/OFF/SLP）、および ダイ
　レクト・コントロール時の情報（SLP で OFF））については、それらが自動的に RAM メモリから削除される以前であれば、
　CH3 スイッチだけでなく CH1、または CH2 スイッチによってもメモリ読み出しが行われ、CH3 スイッチによる読み出しと、
　CH1、または CH2 スイッチによる読み出しとでは、同じメモリ内容でも表示されるときには その表示内容が異なるので注
　意が必要である。

		    　　CHx スイッチ番号  		   　　　　     　　　　    曜日番号
		    　　　　          |   		   　　　　     　　　　          |
		CH3 スイッチ　[ xx xx xx ]		CH1、または CH2 スイッチ　[ xx:xx xx ]
		    　　　　              		   　　　　     　　　　    |
		    　　　　              		   　　　　     　　　 （*注意）

　また、CH2 スイッチによる読み出しの場合でも先頭から４桁目までは時間情報であって、これらの CH1、または CH2 スイ
　ッチによる読み出しの場合には、（*注意）とある先頭桁は常に８をプラスした値（８、９、または無表示）になり、CH3 
　スイッチによってメモリ設定が行われたことを表しているので、併せて十分に注意をする必要がある。

　[ メモリの消去機能 ]
　--------------------

・このようにメモリ内容の確認中に、現在、ニキシー管に表示がされている内容が不要となった場合には、そのときに 
　DELETE スイッチを押すことによって、20 メモリの内のその情報だけを 個別に消去 することができる。

・メモリ内容が消去されると、"ピピッ" ブザー音が出力されるとともに、次の左のメッセージが約５秒間ニキシー管に表示
　され、ブルー LED がブリンク表示をする。なお、上述のように最終の 20 メモリを過ぎて空白表示がされているときに
　DELETE スイッチを押すと、"ブー" ブザー音が出力されるとともに、右のメッセージが約５間表示される。

		     CHx スイッチ番号   消去件数		     CHx スイッチ番号   消去件数
				   |     |					   |     |
		CLR メッセージ	[ _x:__ 01 ]			NOT メッセージ	[ _x:__ 00 ]

・上述の操作で、現在表示中のメモリ内容が消去されてメッセージが表示された約５秒後、消去したメモリ内容の次の順に
　記憶がされている同じ CHx の内容が読み出されて、新たにニキシー管に表示がされる。

・このようにメモリの読み出し機能では、後からの DELETE スイッチの併用によって個別のメモリ消去機能も有している。

・また、このメモリの読み出し機能を終了させるためには、前のメモリの設定機能と同様に CANCEL スイッチを押すことに
　よって、再び NORMAL モードに戻る。

・上述の例では、個別に１件ずつメモリ内容を確認しながら消去をする方法であるが、これとは別に CHx スイッチ別に一気
　に消去をしてしまう方法もある。

・本機が NORMAL モードのときに、CH1 ～ CH3 スイッチのどれかを押しながら DELETE スイッチを押すと、その指定された
　CHx スイッチによって記憶されているメモリ内容のすべてが一気に消去され、"ピピッ" ブザー音が出力されるとともに、
　次の左のメッセージが約５秒間ニキシー管に表示され、ブルー LED がブリンク表示をする。なお、このとき指定された該
　当の CHx によるメモリ内容が１つもなかった場合には、"ブー" ブザー音が出力されるとともに、右のメッセージが約５
　秒間表示される。

		     CHx スイッチ番号   消去件数		     CHx スイッチ番号   消去件数
				   |     |					   |     |
		CLR メッセージ	[ _x:__ xx ]			NOT メッセージ	[ _x:__ 00 ]

・そして、メモリの設定機能やメモリの読み出し機能とは異なって、メッセージの表示時間約 3 秒が過ぎると、再び NORMAL 
　モードに戻る（CANCEL スイッチの操作は不要）。

　[ メモリ情報の監視機能 ]
　------------------------

・上述のメモリの設定機能の (1) タイマースイッチ機能と、(2) 温度スイッチ機能でメモリに記憶設定された情報は、本機
　の電源が断になって消滅をした場合や、ユーザがメモリ消去機能で故意に消去をしない限り、いつまでも RAM メモリ内に
　存在し続けて、タイマースイッチや温度スイッチのプログラムでの監視対象となる。

・タイマースイッチの情報としては、"時"、"分"、"曜日"、リレーの動作種類、CHx リレー番号がメモリに記憶されている
　ため、本機の時計機能が毎分 "00" 秒になると、該当の情報がメモリ内に設定されていないかどうかを、監視プログラム
　が検索をする。

・また、温度スイッチの情報としては、温度値の整数部、小数部、"曜日"、リレーの動作種類、CHx リレー番号がメモリに
　記憶されていて、本機では２秒ごとに温度情報をセンサから読み出して更新をするため、その都度監視プログラムが同様
　に検索をする。ただし、この温度スイッチの場合には、現在、設定情報がメモリ内に存在しているかどうかだけを常にプ
　ログラムが把握をしていて、存在している場合に限ってメモリ検索を行う。

・このようにメモリ検索をした結果、該当の設定情報がメモリ内に存在した場合には、それぞれの CH リレーが、指定をさ
　れた動作種類（ ON/OFF/SLP ）に応じた動作をするとともに、SIGNAL スイッチによってアラーム音の出力が有効に設定さ
　れている場合には、リレーが ON 動作のときには "ピポッピポッ" ブザー音を、また OFF 動作のときには"ブーー" ブザ 
　ー音を併せて出力をする。

・なお、以上述べてきたメモリ設定、メモリ読み出し、メモリ消去、それぞれの操作時に伴う "ピピッ" ブザー音、"ブッブ
　ー" ブザー音、"ブー" ブザー音は、SIGNAL スイッチによるアラーム音の有効／無効にかかわらず出力されるので、 注意
　が必要である。

 <おまけの説明>
 --------------

　本機ではデジタル温度センサ（ DS18B20 ）を使用しており、12 ビット分解能（最高）を選択して温度値を読み出してい
　る。そのときの読み出しデータのフォーマットは "Figure 2" のように、水色部分が小数部で４ビットで構成されている。

　これらのビットはバイナリ（２進数）データであり、デシマル（10 進数）データに変換をすると、2^-1 = 0.5、2^-2 = 
　0.25、2^-3 = 0.125、2^-4 = 0.0625 となり、４ビットで構成されるバイナリデータをデシマルデータに変換をしても、
　小数部４ビットのデータが取りうる値は次のように連続値にはならない。（整数部は常に連続値になる。）

	（２進数）   （10進数）
	   .0000	.0000
	   .0001	.0625
	   .0010	.1250
	   .0011	.1875
	   .0100	.2500
	   .0101	.3125
	   .0110	.3750
	   .0111	.4375
	   .1000	.5000
	   .1001	.5625
	   .1010	.6250
	   .1011	.6875
	   .1100	.7500
	   .1101	.8125
	   .1110	.8750
	   .1111	.9375

　したがって、本機ではバイナリ - デシマル変換後のデータは、小数点以下２位までを表示対象としているが、温度スイッ
　チとしての設定値は、小数点以下１位までを設定対象とした。たとえば、小数点以下２位までを設定対象としても上表の
　ような温度値しか取らないため、上表以外の温度値を設定したような場合には、温度スイッチの監視プログラムは永遠に
　ヒットすることがなくなる。というよりも、"DS18B20" では -10 ℃ ～ +85 ℃ で ±0.5 ℃ の精度なので、小数点以下
　２位を指定してもまったくその意味がない。

#endif

;==========================================================================

;	PIC16F886 のピンと用途

;	  (1) RE3: SW8(SIGNAL) スイッチ入力	(28) RB7: ニキシー管 "HH" 桁出力
;	  (2) RA0: SW5(CH1) スイッチ入力	(27) RB6: ニキシー管 "HL" 桁出力
;	  (3) RA1: SW6(CH2) スイッチ入力　	(26) RB5: ニキシー管 "MH" 桁出力
;	  (4) RA2: 温度センサ 入出力		(25) RB4: ニキシー管 "ML" 桁出力
;	  (5) RA3: 圧電ブザー出力		(24) RB3: ニキシー管 "SH" 桁出力
;	  (6) RA4: CH1 リレー出力		(23) RB2: ニキシー管 "SL" 桁出力
;	  (7) RA5: CH2 リレー出力		(22) RB1: CC LED 出力
;	  (8) VSS: 電源 GND			(21) RB0: INT 外部割り込み入力
;	  (9) RA7: I2C SDA 入出力		(20) VDD: 電源 +5V DC
;	 (10) RA6: I2C SCL 出力			(19) VSS: 電源 GND
;	 (11) RC0: BCD A 出力 			(18) RC7: C3 LED 出力 / SW4(ZERO/BACK) スイッチ入力
;	 (12) RC1: BCD B 出力 			(17) RC6: C2 LED 出力 / SW3(TIMER/DOWN) スイッチ入力
;	 (13) RC2: BCD C 出力 			(16) RC5: C1 LED 出力 / SW2(TMODE/UP) スイッチ入力
;	 (14) RC3: BCD D 出力 			(15) RC4: C0 LED 出力 / SW1(MODE/SET) スイッチ入力

;==========================================================================

	list		p=pic16f886		;デバイス情報
	include		p16f886.inc		;インクルードファイル
	errorlevel	-302			;Eliminate bank warning

;==========================================================================
;		コンフィギュレーションワードの設定
;==========================================================================

	__config _CONFIG1, _INTOSCIO & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
	__config _CONFIG2, _WRT_OFF

;==========================================================================
;		定数の定義と変数のレジスタ割付け
;==========================================================================

		radix	dec

#define 	_PCF8574A			;スレーブアドレスの変更: PCF8574 のときはコメント行にする

ver_no		equ	h'115'			;バージョン番号: 1.15

tm0_h_val	equ	256 - 250		;ハードタイマー０カウント値（割り込み周期）(4/8Mz*256*250=32msec)
tm0_s_val1	equ	8			;ソフトタイマー０カウント値                (32msec*8=256msec)
tm0_s_val2	equ	157			;ソフトタイマー０カウント値                (32msec*157=5024msec=約５秒)
tm2_h_val	equ	250			;ハードタイマー２カウント値（割り込み周期）(4/8Mz*16*8*250=16msec)
tm2_s_val	equ	47			;ソフトタイマー２カウント値                (16msec*47=752msec)

#ifdef temp_ds3231
temp_c_val	equ	64			;64 秒ごとに読み出しをする（RTC DS3231)
#else
temp_c_val	equ	2			;2 秒ごとに読み出しをする（DS18B20 に変更)
#endif

_swMOD		equ	4			;MODE   スイッチ ;┐
_swSET		equ	4			;SET    スイッチ ;│
_swTMD		equ	5			;TMODE  スイッチ ;│
_swUP		equ	5			;UP     スイッチ ;│PORTC
_swDEL		equ	6			;DELETE スイッチ ;│
_swDWN		equ	6			;DOWN   スイッチ ;│
_swZER		equ	7			;ZERO   スイッチ ;│
_swBAK		equ	7			;BACK   スイッチ ;┘

_swCH1		equ	0			;CH1    スイッチ ;┐
_swCH2		equ	1			;CH2    スイッチ ;┘PORTA
;_swCH3		equ	2			;CH3    スイッチ ;

_swSIG		equ	3			;SIGNAL スイッチ ;┐PORTE
_swCAN		equ	3			;CANCEL スイッチ ;┘

_DQ		equ	2			;温度センサ DS18B20 入出力ポート
_BZ		equ	3			;アラーム音 出力 ;┐
SCL		equ	6			;I2C SCL	 ;│PORTA
SDA		equ	7			;I2C SDA	 ;┘

f_rah		equ	65536 - 1136		;ラ (880.00 Hz)
f_doh		equ	65536 - 1911		;ド (523.26 Hz)  at 8MHz
f_ra		equ	65536 - 2273		;ラ (440.00 Hz)
f_so		equ	65536 - 2551		;ソ (392.00 Hz)
f_mi		equ	65536 - 3034		;ミ (329.63 Hz)
f_do		equ	65536 - 3822		;ド (261.63 Hz)
f_do_		equ	65536 - 7644		;ド (130.82 Hz)
po_tim		equ	100			;音長(ms)
pi_tim		equ	100			;音長
bu_tim		equ	100			;音長
buu_tim		equ	250			;音長

#define 	bcd_yy	bcd_yl			;年(下位2桁) BCD カウンタ

		cblock	h'20'			; (( バンク 0 ))
bcd_yh						;年(上位2桁) BCD カウンタ
bcd_yl						;年(下位2桁) BCD カウンタ
bcd_nn						;月 BCD カウンタ
bcd_dd						;日 BCD カウンタ
bcd_hh						;時 BCD カウンタ
bcd_mm						;分 BCD カウンタ
bcd_ss						;秒 BCD カウンタ
bcd_ww						;曜日 BCD カウンタ
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						;ワーク
addr_high					;テーブルデータの先頭 high アドレス
addr_low					;テーブルデータの先頭 low アドレス

dspdigit					;表示桁指定フラグ
						; bit7: "HH" 桁の指定
						; bit6: "HL" 桁の指定
						; bit5: "MH" 桁の指定
						; bit4: "ML" 桁の指定
						; bit3: "SH" 桁の指定
						; bit2: "SL" 桁の指定
						; bit1: :("Colon") の指定
						; bit0: .("Period")の指定
tempfsr						;仮のFSR

int_flg						;外部(RB0/INT)割り込みフラグ
						; bit3: DS18B20 温度変換時間監視終了フラグ
						; bit2: DS18B20 温度変換時間監視中フラグ
						; bit1: RTC DS3231 (DS18B20 に変更) から温度データの読み出し要求フラグ
						; bit0: RTC DS3231 から年月日,時分秒データの読み出し要求フラグ
mode_flg					;表示モードフラグ
						; bit3-0: 0:時間, 1:年月日, 2:気温, 3:オート, 
						;	 (4:SET), (8:初期処理), (9:RTC エラー)
modex_flg					;表示モード変更フラグ
						; bit7: モード変更フラグ
						; bit6: モード変更受付フラグ
						; bit5: SET移行手続き中フラグ
						; bit4: ブリンク表示フラグ
						; bit3-0: カウンタ
time_flg					;時間表示モードフラグ
						; bit7: 1:オート/SETモードで(時間)表示のとき (nixie_display 用)
						; bit6: 1:オートモードで(時間)表示のとき     (mode_switch 用)
						; bit5: 気温表示時の"Period"制御フラグ
						; bit4: ブルー LED の曜日表示フラグ
						; bit3: ブリンク表示2フラグ (ブルー LED 点灯制御用)
						; bit2: ブリンク表示1フラグ
						; bit1: 0:24H / 1:12H
						; bit0:  0:am / 1:pm
tg_point					;変更対象の位置ポインタ
						; bit2-0: 0:年, 1:月, 2:日, 3:時, 4:分, 5:秒
alm_flg						;アラームフラグ
						; bit7: アラーム音出力許可フラグ
						; bit4: 時報正報音抑止フラグ
						; bit3: 時報正報音フラグ
						; bit2: 時報予報音フラグ
						; bit1: リレー OFF フラグ
						; bit0: リレー ON フラグ
ext_flg						;タイマー機能フラグ
						; bit7: タイマー用メモリの設定フラグ
						; bit6: タイマー用メモリの消去フラグ
						; bit5: タイマー機能中の LED 表示制御フラグ
						; bit4: ブリンク表示フラグ
						; bit3: ダイレクト・コントロールフラグ
						; bit2: CH3 フラグ
						; bit1: CH2 フラグ
						; bit0: CH1 フラグ
dsp_cnt						;タイマー用メモリの表示カウンタ
						; bit5: タイマー用メモリ検索終了フラグ
						; bit4-0: カウンタ
tmon_flg					;タイマー & 温度監視フラグ
						; bit1: 温度
						; bit0: タイマー
tmon_week					;タイマー監視中の曜日カウンタ
ch2_cnt						;CH2 メモリカウンタ
fmmwwwss					;タイマー制御バイト
del_fsr						;消去対象のタイマー用メモリのアドレス記憶
temp_cnt					;温度読み出しカウンタ
tm0_s_cnt					;ソフトタイマー０カウンタ
tm2_s_cnt					;ソフトタイマー２カウンタ

work1						;ワーク
work2						;ワーク
work3						;ワーク
lp_cnt1						;汎用ループカウンタ
lp_cnt2						;汎用ループカウンタ
lp_cnt3						;汎用ループカウンタ
buff0		;(00)				;変換文字列の格納エリア
buff1		;(01)				;
buff2		;(02)				;


const_high					;音階用分周定数 high の保存
const_low					;音階用分周定数 low の保存
wt1cnt						;ウェイト用ループカウンタ
wt2cnt						;ウェイト用ループカウンタ
wt3cnt						;ウェイト用ループカウンタ

;（PCF8574/74A で使用）
exptmp						;書き込み／読み出しデータ

; (I2C_XS_100K.sub で使用)
i2ctmp						;送受信データの一時保存
bit_cnt						;ループカウンタ

; (I2C_RTC.sub で使用)
rtc_lpcnt					;ループカウンタ
rtc_addr_high					;読み出すデータの high アドレス
rtc_addr_low					;読み出すデータの low アドレス

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_msb					;11h: MSB of Temp
temp_lsb					;12h: LSB of Temp

;（DS18B20_1-Wire.sub で使用）
temp_1w						;送受信データの一時保存
w1_lpcnt					;ループカウンタ
						;スクラッチパッド格納エリア
sp_temp_lsb					;00h: Temperature LSB
sp_temp_msb					;01h: Temperature MSB
sp_th_reg					;02h: TH Register
sp_tl_reg					;03h: TL Register
sp_conf_reg					;04h: Configuration Register
sp_resv_1					;05h: Reserved
sp_resv_2					;06h: Reserved
sp_resv_3					;07h: Reserved
sp_crc						;08h: CRC
		endc

		cblock	h'80' - 4
w_save						;W レジスタの退避用
s_save						;STATUS レジスタの退避用
f_save						;FSR レジスタの退避用
p_save						;PCLATH レジスタの退避用
		endc

		cblock  h'a0'			; (( バンク 1 ))
; (タイマー用メモリエリア)
timer_mem					;タイマー用メモリの先頭
;	     (3 * 20 = 60 byte 使用)
		endc

;==========================================================================
;		マクロ命令定義
;==========================================================================

;		Sound_M マクロ

Sound_M		macro	@scale,@time
		movlw	high @scale		;出力音階
		movwf	const_high
		movlw	low @scale
		movwf	const_low
		movlw	@time			;出力時間(ms)
		call	buzzer_control		;ブザー音出力コントロール
		endm

;		xRtc_Write_M マクロ

xRtc_Write_M	macro	@bufreg,@n
		movlw	@bufreg			;書き込みバッファのレジスタアドレス
		movwf	FSR			;間接アドレスに設定
		movlw	@n
		movwf	rtc_lpcnt		;ループカウンタ
		bsf	PCLATH,3		;ページ 1
		call	I2cRtc_Write		;RTC（DS3231）モジュールのレジスタへ書き込み
		bcf	PCLATH,3		;ページ 0
		endm

;		xRtc_Read_M マクロ

xRtc_Read_M	macro	@bufreg,@n
		movlw	@bufreg			;読み出しバッファのレジスタアドレス
		movwf	FSR			;間接アドレスに設定
		movlw	@n
		movwf	rtc_lpcnt		;ループカウンタ
		bsf	PCLATH,3		;ページ 1
		call	I2cRtc_Read		;RTC（DS3231）モジュールのレジスタから読み出し
		bcf	PCLATH,3		;ページ 0
		endm

;==========================================================================
;		プログラム開始
;==========================================================================

		org	h'0000'			;リセットベクタ

		bsf	PCLATH,3		;ページ 1
		goto	initialize

;==========================================================================
;		割り込み処理
;==========================================================================

		org	h'0004'			;割り込みベクタ

interrupt
		; レジスタの保存

		movwf	w_save			;W レジスタの保存
		swapf	STATUS,W
		clrf	STATUS
		movwf	s_save			;STATUS レジスタの保存
		movf	PCLATH,W
		movwf	p_save			;PCLATH レジスタの保存
		clrf	PCLATH
		movf	FSR,W
		movwf	f_save			;FSR レジスタの保存

		; 割り込み処理の振り分け

		bcf	STATUS,RP0		;バンク 0
		btfsc	INTCON,INTF		;外部(RB0/INT)割り込み か？
		goto	rb0_int			;Yes

		btfsc	INTCON,T0IF		;タイマー０割り込み か？
		goto	t0_int			;Yes

		btfsc	PIR1,TMR2IF	;*2	;タイマー２割り込み か？
		goto	t2_int			;Yes

		btfsc	PIR1,TMR1IF	;*1	;タイマー１割り込み か？
		goto	t1_int			;Yes
		goto	int_end			;(Illegal interrupt)

		;; (注)． 振り分けを *2 より *1 を先に優先させると、
		;;  2 秒ごとにブザーから "コツッ" という雑音が出る

;---------------- 外部(RB0/INT)割り込み処理 -------------------------------

rb0_int		bcf	INTCON,INTF		;外部(RB0/INT)割り込みフラグをクリア
		bsf	int_flg,0		;RTC DS3231 から年月日,時分秒データの読み出し要求フラグ = 1

		btfss	time_flg,1		;時間表示モードフラグ (bit1=0:24H/1:12H) = 0:24H か？
		bcf	time_flg,2		;Yes. bit2:ブリンク表示1フラグ = 0
		movlw	b'00000100'
		btfsc	time_flg,1		;時間表示モードフラグ (bit1=0:24H/1:12H) = 1:12H か？
		xorwf	time_flg,F		;Yes. bit2:ブリンク表示1フラグ = 反転

		movlw	b'00001000'		;ブリンク表示フラグ (ブルー LED 点灯制御用)
		xorwf	time_flg,F		;     bit3:ブリンク表示2フラグ = 反転

		decfsz	temp_cnt,F		;温度読み出しカウンタ - 1 = 0 か？
		goto	int_end			;No

		bsf	int_flg,1		;温度データの読み出し要求フラグ = 1
		movlw	temp_c_val		;2 秒ごとに読み出しをする（DS18B20 に変更)
		movwf	temp_cnt		;温度読み出しカウンタに設定
		goto	int_end

;---------------- タイマー０割り込み処理 ----------------------------------
						;（タイマー０を許可したときのみ: 割り込み周期 = 4/8Mz*256*250=32msec）

t0_int		bcf	INTCON,TMR0IF		;タイマー０割り込みフラグをクリア
		movlw	tm0_h_val		;ハードタイマー０カウント値 = (256 - 250) を
		movwf	TMR0			;TMR0 に設定

		decfsz	tm0_s_cnt,F		;ソフトタイマー０カウンタ - 1 = 0 か？
		goto	int_end			;No

		movlw	9
		subwf	mode_flg,W		;
		btfsc	STATUS,Z		;表示モードフラグ = 9:RTC エラー か？
		goto	t0int01			;Yes

		btfsc	ext_flg,5		;タイマー用メモリの設定フラグ = 1 か？
		goto	t0int01			;Yes

		movlw	4
		subwf	mode_flg,W		;
		btfsc	STATUS,Z		;表示モードフラグ = 4:SET モード か？
		goto	t0int01			;Yes

		btfsc	modex_flg,5		;SET移行手続き中フラグ = 1 か？
		goto	t0int02			;Yes

		btfss	modex_flg,6		;表示モード変更受付フラグ = 1 か？
		goto	t0int03			;No

		incf	modex_flg,F		;カウンタ（下位 4 ビット）の +1 更新
		movlw	h'0f'
		andwf	modex_flg,W		;カウンタを取り出し
		sublw	4 * 3			;(32ms x 8) x (4 x 3) = 3,072ms ≒ ３秒間
		btfsc	STATUS,Z		;ブリンク終了 か？
		goto	t0int02			;Yes

t0int01		movlw	b'00010000'
		xorwf	modex_flg,F		;ブリンク表示フラグを反転
		xorwf	ext_flg,F		;ブリンク表示フラグを反転（タイマー用メモリの設定用）
		movlw	tm0_s_val1		;ソフトタイマー０カウント値 = 8 を
		movwf	tm0_s_cnt		;ソフトタイマー０カウンタに設定
		goto	int_end

t0int02		clrf	modex_flg		;表示モード変更フラグをクリア

t0int03		bcf	INTCON,T0IE		;T0IE: タイマー０割り込みを禁止
		goto	int_end

;---------------- タイマー１割り込み処理 ----------------------------------

t1_int		bcf	PIR1,TMR1IF		;タイマー１割込みフラグをクリア

		movf	const_high,W		;音階用分周定数 high を
		movwf	TMR1H			;TMR1H に設定
		movf	const_low,W		;音階用分周定数 low を
		movwf	TMR1L			;TMR1L に設定

		movlw	1 << _BZ		;対象ビットをセット
		xorwf	PORTA,F			;出力をビット反転
		goto	int_end

;---------------- タイマー２割り込み処理 ----------------------------------
						;割り込み周期 = 4/8Mz*16*8*250=16msec）

t2_int		bcf	PIR1,TMR2IF		;タイマー２割込みフラグをクリア

		decfsz	tm2_s_cnt,F		;ソフトタイマー２カウンタ - 1 = 0 か？
		goto	int_end			;No
						;16ms x 47 = 752ms
		bcf	T2CON,TMR2ON		;タイマー２ ON/OFF 制御 = OFF
		bcf	int_flg,2		;温度変換時間監視中フラグ = 0
		bsf	int_flg,3		;温度変換時間監視終了フラグ = 1
;		goto	int_end

		; 割り込み処理の終了

int_end		movf	f_save,W
		movwf	FSR			;FSR レジスタの復帰
		movf	p_save,W
		movwf	PCLATH			;PCLATH レジスタの復帰
		swapf	s_save,W
		movwf	STATUS			;STATUS レジスタの復帰
		swapf	w_save,F
		swapf	w_save,W		;W レジスタの復帰

		retfie				;割り込みからの復帰	

;==========================================================================

		; バッファからカウンタへコピー

buffer_to_counter

		movf	seconds,W		;Seconds
		movwf	bcd_ss			;秒 BCD カウンタ
		btfsc	STATUS,Z		;bcd_ss = h'00' か？
		bsf	tmon_flg,0		;Yes. タイマー監視フラグ = 1

		movf	minutes,W		;Minutes
		movwf	bcd_mm			;分 BCD カウンタ
		movf	hours,W			;Hours
		movwf	bcd_hh			;時 BCD カウンタ

		movf	day,W			;Day
		movwf	bcd_ww			;曜日 BCD カウンタ

		movf	date,W			;Date
		movwf	bcd_dd			;日 BCD カウンタ
		movlw	h'1f'			;
		andwf	month,W			;Month
		movwf	bcd_nn			;月 BCD カウンタ
		movf	year,W			;Year
		movwf	bcd_yy			;年 BCD カウンタ
		return

		; カウンタからバッファへコピー

counter_to_buffer

		movf	bcd_ss,W		;秒 BCD カウンタ
		movwf	seconds			;Seconds
		movf	bcd_mm,W		;分 BCD カウンタ
		movwf	minutes			;Minutes
		movf	bcd_hh,W		;時 BCD カウンタ
		movwf	hours			;Hours

		movf	bcd_ww,W		;曜日 BCD カウンタ
		movwf	day			;Day

		movf	bcd_dd,W		;日 BCD カウンタ
		movwf	date			;Date
		movf	bcd_nn,W		;月 BCD カウンタ
		movwf	month			;Month
		movf	bcd_yy,W		;年 BCD カウンタ
		movwf	year			;Year
		return

;==========================================================================
;		メイン・ルーチン
;==========================================================================

;	mode_flg: 表示モードフラグ:   0:時間, 1:年月日, 2:温度, 3:オート,
;				     (4:SET), (8:初期処理), (9:RTC エラー)

main
		; RTC DS3231 から年月日,時分秒,温度データの読み出し、
		; 及び タイマー & 温度の監視と時報音出力コントロール

		call	xtime_monitor		;タイマー & 温度の監視と時報音出力コントロール

;-------------- ニキシー管の(時間)表示

		bcf	time_flg,6		;(bit6=1:オートモードで(時間)表示 (mode_switch 用)) = 0
		movf	mode_flg,W
		btfss	STATUS,Z		;表示モードフラグ = 0(時間)表示 か？
		goto	main03			;No

main01		movlw	bcd_hh			;時 BCD カウンタの番地
		btfss	time_flg,1		;時間表示モードフラグ (bit1=0:24H/1:12H) = 1:12H か？
		goto	main02			;No

		movf	bcd_hh,W		;時 BCD カウンタ
		movwf	temp_hh			;仮の時 BCD カウンタ
		movf	bcd_mm,W		;分 BCD カウンタ
		movwf	temp_mm
		movf	bcd_ss,W		;秒 BCD カウンタ
		movwf	temp_ss
		call	cnv_24to12		;24時間表示を12時間表示に変換
		movlw	temp_hh			;仮の時 BCD カウンタの番地

main02		movwf	tempfsr			;間接アドレスの先頭番地に設定
		movlw	h'fe'			;時間(xx:xx:xx)表示指定
		movwf	dspdigit		;表示桁指定フラグの設定
		goto	main10			;ニキシー管の表示へ

;-------------- ニキシー管の(年月日)表示

main03		movlw	1
		subwf	mode_flg,W
		btfss	STATUS,Z		;表示モードフラグ = 1(年月日)表示 か？
		goto	main05			;No

main04		movlw	bcd_yy			;年 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地の設定
		movlw	h'fd'			;年月日(xx.xx.xx)表示指定
		movwf	dspdigit		;表示桁指定フラグの設定
		goto	main10			;ニキシー管の表示へ

;-------------- ニキシー管の(温度)表示

main05		movlw	2
		subwf	mode_flg,W
		btfss	STATUS,Z		;表示モードフラグ = 2(温度)表示 か？
		goto	main08			;No

main06		movlw	buff0			;仮の時 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地の設定
		movlw	h'3d'			;温度(__ xx.xx)表示指定
		movwf	dspdigit		;表示桁指定フラグの設定
		bsf	time_flg,5		;気温表示時の"Period"制御フラグ = 1

		movf	buff0,W	    ;temp_hh	;
		btfsc	STATUS,Z		;buff0 = 0 か？
		goto	main07			;Yes

		bsf	dspdigit,6		;"HL"桁追加(_x xx.xx) dspdigit = h'7d'
		xorlw	h'09'			;
		btfss	STATUS,Z		;    "HL"桁 = 9 (マイナス(-)値) か？
		goto	main10			;No. "HL"桁 = 1 (+100 ℃以上のとき)

main07		movlw	h'f0'
		andwf	buff1,W	    ;temp_mm
		btfsc	STATUS,Z		;temp_mm 上位４ビット = 0 か？
		bcf	dspdigit,5		;Yes. ゼロサプレス "MH"桁を非表示(__ _x.xx) dspdigit = h'1d' or  h'5d'
		goto	main10			;ニキシー管の表示へ

;-------------- オートモードの処理

;		(NNN: 毎05～09秒と35～39秒の間: 年月日表示)
;		(OOO: 毎20～24秒と50～54秒の間: 温度表示)
;		(___: 上記以外:                 時間表示)
;
;		 00        10        20        30        40        50        00
;		 .    .    .    .    .    .    .    .    .    .    .    .    .
;		 _____NNNNN__________OOOOO__________NNNNN__________OOOOO_____

main08		movlw	h'00' - h'05'
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'05' か？
		goto	main09			;No. (時間)表示へ

		movlw	h'00' - (h'09' + 1)
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'10' か？
		goto	main04			;No. (年月日)表示へ

		movlw	h'00' - h'20'
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'20' か？
		goto	main09			;No. (時間)表示へ

		movlw	h'00' - (h'24' + 1)
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'25' か？
		goto	main06			;No. (温度)表示へ

		movlw	h'00' - h'35'
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'35' か？
		goto	main09			;No. (時間)表示へ

		movlw	h'00' - (h'39' + 1)
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'40' か？
		goto	main04			;No. (年月日)表示へ

		movlw	h'00' - h'50'
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'50' か？
		goto	main09			;No. (時間)表示へ

		movlw	h'00' - (h'54' + 1)
		addwf	bcd_ss,W
		btfss	STATUS,C		;bcd_ss > h'55' か？
		goto	main06			;No. (温度)表示へ

main09		bsf	time_flg,7		;(bit7=1:オートモードで(時間)表示 (nixie_display 用)) = 1
		bsf	time_flg,6		;(bit6=1:オートモードで(時間)表示 (mode_switch 用)) = 1
		goto	main01			;(時間)表示へ

;-------------- ニキシー管の表示コントロール

main10		call	nixie_display		;ニキシー管の表示
		bcf	time_flg,5		;気温表示時の"Period"制御フラグ = 0

;-------------- ブルー LED の（曜日）表示コントロール

;	入力:	bcd_ww = ( 1:日, 2:月, 3:火, 4:水, 5:木, 6:金, 7:土 )
;	出力:	曜日位置   なし, "HH", "HL", "MH", "ML", "SH", "SL"

		movlw	h'ff'			;ブルー LED 消灯
		btfsc	time_flg,4		;ブルー LED 曜日表示フラグ = 1 か？
		goto	main14			;Yes. 0: 表示, 1: 非表示

		decf	bcd_ww,W		;
		movwf	lp_cnt2			;ループカウンタ

;		movlw	h'00'			;1:日の場合
		btfsc	STATUS,Z		;曜日 BCD カウンタ - 1 = 0 か？
		goto	main13			;Yes

		movlw	b'00100000'		;h'20'
		movwf	work1			;曜日位置の初期値

main11		decf	lp_cnt2,F
		btfsc	STATUS,Z		;lp_cnt2 - 1 = 0 か？
		goto	main12			;Yes

		bcf	STATUS,C
		rrf	work1,F			;曜日位置を右に 1 ビットシフト
		goto	main11

main12		movf	work1,W			;曜日位置

main13		btfsc	time_flg,3		;ブリンク表示フラグ (ブルー LED 点灯制御用) = 1 か？
		xorlw	h'3f'			;Yes. ビット反転
		iorlw	h'c0'			;書き込みデータに上位 2 ビットを追加

main14		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み

;-------------- 各スイッチの ON／OFF 状態のチェック

		btfsc	modex_flg,6		;表示モード変更受付フラグ = 1 か？
		goto	main16			;Yes

		movlw	h'ff'			;;時間表示時、入力ポートに切り替える前に 'H' を出しておく
		movwf	PORTC			;;これを行わないと切り替えたとたんに、出力時の :("Colon")
						;;指定が引き継がれて、４つの SW が ON ('L') になってしまう

		bsf	STATUS,RP0		;バンク 1
		movlw	b'11110000'		;RC7-4: 入力, RC3-0: 出力
		movwf	TRISC
		bcf	STATUS,RP0		;バンク 0

		btfss	PORTC,_swTMD		;TIME MODE / UP スイッチ = ON か？
		call	tmode_switch		;Yes

		btfss	PORTC,_swZER		;ZERO / BACK スイッチ = ON か？
		call	zero_switch		;Yes

		btfss	PORTC,_swMOD		;MODE / SET スイッチ = ON か？
		call	mode_switch		;Yes

		comf	PORTA,W			;全ビットを反転
		andlw	h'03'			;スイッチ入力だけ取り出す
		btfss	STATUS,Z		;どれか（CH1～CH2）のスイッチ = ON か？
		goto	main15			;Yes

		call	xExpPCF8574_Read	;（PCF8574/74A）のポートからデータを読み出し
		btfss	exptmp,7		;CH3（SW7）スイッチ = ON か？

main15		call	timer_switch		;Yes

		btfss	PORTE,_swSIG		;SIGNAL スイッチ = ON か？
		call	signal_switch		;Yes

		bsf	STATUS,RP0		;バンク 1
		movlw	b'00000000'		;RC7-0: 出力
		movwf	TRISC
		bcf	STATUS,RP0		;バンク 0

		btfss	modex_flg,7		;表示モード変更フラグ = 1 か？
		goto	main16			;No

		; 表示モード変更時のモード番号のブリンク表示手続き
		; (4/8Mz*256*250=32msec) * 8 * 12 = 256 * 12 = 3,072 ms = 約３秒間

		; modex_flg:			;表示モード変更フラグ
						; bit7: モード変更フラグ
						; bit6: モード変更受付フラグ
						; bit5: SET移行手続き中フラグ
						; bit4: ブリンク表示フラグ
						; bit3-0: カウンタ

		bsf	modex_flg,6		;表示モード変更受付フラグ = 1
		movlw	tm0_h_val		;ハードタイマー０カウント値 = (256 - 250) を
		movwf	TMR0			;TMR0 に設定
		movlw	tm0_s_val1		;ソフトタイマー０カウント値 = 8 を
		movwf	tm0_s_cnt		;ソフトタイマー０カウンタに設定
		bsf	INTCON,T0IE		;T0IE: タイマー０割り込みを許可

main16		goto	main

;--------------------------------------------------------------------------
;		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

;--------------------------------------------------------------------------
;    各種データ読み出しと タイマー & 温度の監視と時報音出力コントロール
;--------------------------------------------------------------------------

xtime_monitor
		btfss	int_flg,0		;RTC DS3231 からデータ読み出し要求フラグ = 1（１秒周期） か？
		goto	xtime01  ;03			;No

		xRtc_Read_M  seconds,7		;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter
		bcf	int_flg,0		;RTC DS3231 からデータ読み出し要求フラグ = 0

		call	time_signal		;時報音出力コントロール

		btfss	tmon_flg,0		;タイマー監視フラグ = 1 か？
		goto	xtime01			;No

		bsf	PCLATH,3		;ページ 1
		call	time_monitor		;タイマー & 温度の監視とその処理
		bcf	PCLATH,3		;ページ 0

xtime01		btfss	int_flg,1		;DS18B20 から温度データの読み出し要求フラグ = 1（2 秒周期） か？
		goto	xtime02			;No

#ifdef temp_ds3231
		xRtc_Read_M  temp_msb,2		;RTC DS3231 から温度データ 11h,12h を読み出し
		call	temp_cnv		;温度データの BCD 変換
		bcf	int_flg,1		;温度データの読み出し要求フラグ = 0
#else
		bsf	PCLATH,3		;ページ 1
		call	read_temperature	;DS18B20 から温度データの読み出し
		btfsc	int_flg,3		;温度変換時間監視終了フラグ = 1 か？
		call	temp_cnv2		;Yes. 温度データの BCD 変換
		bcf	PCLATH,3		;ページ 0

		movlw	h'01'
		btfsc	int_flg,3		;温度変換時間監視終了フラグ = 1 か？
		andwf	int_flg,F		;Yes. 温度関連フラグ = 0
#endif
		movf	ch2_cnt,W		;
		btfsc	STATUS,Z		;CH2 メモリカウンタ = 0 か？
		goto	xtime02			;Yes

		bsf	tmon_flg,1		;温度監視フラグ = 1
		bsf	PCLATH,3		;ページ 1
		call	time_monitor		;タイマー & 温度の監視とその処理
		bcf	PCLATH,3		;ページ 0

xtime02		call	alarm_sound		;アラームフラグの監視とアラーム音出力

xtime03		return

#ifdef temp_ds3231
;--------------------------------------------------------------------------

;		11h: temp_msb 	bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
;				Sign  Data  Data  Data  Data  Data  Data  Data
;
;		12h: temp_lsb 	bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
;				Data  Data    0     0     0     0     0     0

		; 温度データの BCD 変換
temp_cnv
		movf	temp_msb,W		;11h: MSB of Temp: (整数部分)
		movwf	work1
		movlw	h'02'
		btfsc	temp_msb,7		;マイナス(-)値 か？
		addwf	work1,F			;Yes. 正値に変換

		call	bin8bcd3_cnv		;8 ビット数値を 10進数 3桁の BCD 数値に変換
		swapf	buff1,W	    ;	
		addwf	buff2,W	    ;
		movwf	buff1	    ;temp_mm	;仮の分 BCD カウンタ

		clrf	buff2	    ;temp_ss	;仮の秒 BCD カウンタの初期設定
		movlw	h'50'
		btfsc	temp_lsb,7		;12h: LSB of Temp: (小数部分) bit7 = 1 か？
		addwf	buff2,F	    ;temp_ss	;Yes
		movlw	h'25'
		btfsc	temp_lsb,6		;12h: LSB of Temp: (小数部分) bit6 = 1 か？
		addwf	buff2,F	    ;temp_ss	;Yes

		movlw	h'09'			;
		btfsc	temp_msb,7		;マイナス(-)値 か？
		movwf	buff0	    ;temp_hh	;Yes. 仮の時 BCD カウンタ

		return
#endif

;==========================================================================
;	   ニキシー管の表示と :("Colon") / .("Period") の LED 表示
;==========================================================================

;		mode_flg:  表示モードフラグ	0:時間, 1:年月日, 2:気温, 3:オート,
;						(4:SET), (8:初期処理), (9:RTC エラー)

;		modex_flg: 表示モード変更フラグ
;						bit7: モード変更フラグ
;						bit6: モード変更受付フラグ
;						bit5: SET移行手続き中フラグ
;						bit4: ブリンク表示フラグ
;						bit3-0: カウンタ

;		time_flg:  時間表示モードフラグ
;						bit7: 1:オート/SETモードで(時間)表示のとき (nixie_display 用)
;						bit6: 1:オートモードで(時間)表示のとき     (mode_switch 用)
;						bit5: 気温表示時の"Period"制御フラグ
;						bit4: ブルー LED の曜日表示フラグ
;						bit3: ブリンク表示2フラグ (ブルー LED 点灯制御用)
;						bit2: ブリンク表示1フラグ
;						bit1: 0:24H / 1:12H
;						bit0: 0:am / 1:pm

;		ext_flg:   タイマー機能フラグ
;						bit7: タイマー用メモリの設定フラグ
;						bit6: タイマー用メモリの消去フラグ
;						bit5: タイマー機能中の LED 表示制御フラグ
;						bit4: ブリンク表示フラグ
;						bit3: ダイレクト・コントロールフラグ
;						bit2: CH3 フラグ
;						bit1: CH2 フラグ
;						bit0: CH1 フラグ

;		tempfsr:   表示文字列の先頭番地

;		dspdigit:  表示桁指定フラグ	bit7: "HH" 桁の指定
;						bit6: "HL" 桁の指定
;						bit5: "MH" 桁の指定
;						bit4: "ML" 桁の指定
;						bit3: "SH" 桁の指定
;						bit2: "SL" 桁の指定
;						bit1: :("Colon") の指定
;						bit0: .("Period")の指定

nixie_display

		; ニキシー管（６桁分）の表示制御
		; ------------------------------

		movlw	8
		subwf	mode_flg,W
		btfss	STATUS,Z		;表示モードフラグ = 8(初期処理)表示 か？
		goto	nxdsp01			;No

		movlw	75			;(2.2 mS * 6 + 0.2) * 75 = 1,005 mS
		movwf	lp_cnt3			;１秒経過カウンタの初期設定

		; "HH" 桁の表示

nxdsp01		movf	tempfsr,W		;間接アドレスの先頭番地
		movwf	FSR
		btfss	modex_flg,6		;表示モード変更受付フラグ = 1 か？
		goto	nxdsp02			;No

		bsf	dspdigit,7
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		bcf	dspdigit,7		;Yes

nxdsp02		movlw	h'0f'			;非表示 (0～9の範囲外)
		btfss	dspdigit,7		;表示桁指定フラグ 7 ("HH") = 1 か？
		goto	nxdsp06			;No

		btfss	modex_flg,6		;表示モード変更受付フラグ = 1 か？
		goto	nxdsp03			;No

		movf	mode_flg,W		;"HH" 桁にモード番号を表示
		goto	nxdsp06

nxdsp03		swapf	INDF,W			;上位4ビット
;		andlw	h'0f'
		movwf	work3			;退避

		movf	mode_flg,W
		btfsc	STATUS,Z		;表示モードフラグ = 0(時間)表示 か？
		goto	nxdsp04			;Yes

		btfss	time_flg,7		;時間表示モードフラグ (bit7=1:オート/SETモードで(時間)表示) = 1 か？
		goto	nxdsp05			;No

		bcf	time_flg,7		;時間表示モードフラグ (bit7=1:オート/SETモードで(時間)表示) = 0

nxdsp04		btfss	time_flg,1		;時間表示モードフラグ (bit1=0:24H/1:12H) = 1:12H か？
		goto	nxdsp05			;No

		movlw	h'f0'			;上位4ビット
		andwf	INDF,W			;"HH" 桁

		movlw	h'0f'			;非表示 (0～9の範囲外)
		btfsc	STATUS,Z		;"HH" 桁 = 0 か？
		goto	nxdsp06			;Yes. ゼロサプレス

nxdsp05		movf	work3,W			;復帰

nxdsp06		iorlw	h'f0'			;(LED off)
		movwf	PORTC
		movlw	h'80'			;"HH" 桁
		call	bright_cntrl		;輝度コントロール

		; "HL" 桁の表示

		movf	INDF,W			;下位4ビット
;		andlw	h'0f'
		btfss	dspdigit,6		;表示桁指定フラグ 6 ("HL") = 1 か？
		movlw	h'0f'			;No, 非表示 (0～9の範囲外)

		iorlw	h'f0'			;(LED off)
		movwf	PORTC
		movlw	h'40'			;"HL" 桁
		call	bright_cntrl		;輝度コントロール

		; "MH" 桁の表示

		incf	FSR,F			;間接アドレス +1 更新
		swapf	INDF,W			;上位4ビット
;		andlw	h'0f'
		btfss	dspdigit,5		;表示桁指定フラグ 5 ("MH") = 1 か？
		movlw	h'0f'			;No, 非表示 (0～9の範囲外)

		iorlw	h'f0'			;(LED off)
		movwf	PORTC
		movlw	h'20'			;"MH" 桁
		call	bright_cntrl		;輝度コントロール

		; "ML" 桁の表示

		movf	INDF,W			;下位4ビット
;		andlw	h'0f'
		btfss	dspdigit,4		;表示桁指定フラグ 4 ("ML") = 1 か？
		movlw	h'0f'			;No, 非表示 (0～9の範囲外)

		iorlw	h'f0'			;(LED off)
		movwf	PORTC
		movlw	h'10'			;"ML" 桁
		call	bright_cntrl		;輝度コントロール

		; "SH" 桁の表示

		incf	FSR,F			;間接アドレス +1 更新
		swapf	INDF,W			;上位4ビット
;		andlw	h'0f'
		btfss	dspdigit,3		;表示桁指定フラグ 3 ("SH") = 1 か？
		movlw	h'0f'			;No, 非表示 (0～9の範囲外)

		iorlw	h'f0'			;(LED off)
		movwf	PORTC
		movlw	h'08'			;"SH" 桁
		call	bright_cntrl		;輝度コントロール

		; "SL" 桁の表示

		movf	INDF,W			;下位4ビット
;		andlw	h'0f'
		btfss	dspdigit,2		;表示桁指定フラグ 2 ("SL") = 1 か？
		movlw	h'0f'			;No, 非表示 (0～9の範囲外)

		iorlw	h'f0'			;(LED off)
		movwf	PORTC
		movlw	h'04'			;"SL" 桁
		call	bright_cntrl		;輝度コントロール

		; :("Colon") / .("Period") の LED 表示制御
		; ----------------------------------------

		btfss	dspdigit,1		;表示桁指定フラグ 1 ("Colon") = 1 か？
		goto	nxdsp08			;No

		; :("Colon") の 指定

		movlw	h'c0'			;左列上下:("Colon")指定
		btfsc	ext_flg,5		;タイマー機能中の LED 表示制御フラグ = 1 か？
		goto	nxdsp12			;Yes

		movlw	h'f0'			;:("Colon")指定
		btfss	time_flg,1		;12時間表示 か？
		goto	nxdsp12			;No

		movlw	4
		subwf	mode_flg,W
		btfss	STATUS,Z		;MODEフラグ = 4(SET) か？
		goto	nxdsp07			;No

		movlw	h'b0'			;am指定, :("Colon")右列上下 + 左列上側 LED点灯
		btfsc	time_flg,0		;pm表示 か？
		movlw	h'70'			;pm指定, :("Colon")右列上下 + 左列下側 LED点灯
		goto	nxdsp12

		; 12時間表示時の AM/PM 表示点滅タイミング
nxdsp07		btfss	time_flg,2		;ブリンク表示フラグ = 1 か？
		goto	nxdsp12			;No

		movlw	h'70'			;am指定, :("Colon")左列上側 LED滅灯
		btfsc	time_flg,0		;pm表示 か？
		movlw	h'b0'			;pm指定, :("Colon")左列下側 LED滅灯
		goto	nxdsp12

		; .("Period") の 指定

nxdsp08		movlw	h'00'			;無表示指定
		btfss	dspdigit,0		;表示桁指定フラグ 0 ("Period") = 1 か？
		goto	nxdsp12			;No. 無表示

		btfsc	ext_flg,5		;タイマー機能中の LED 表示制御フラグ = 1 か？
		goto	nxdsp09			;Yes

		movlw	8
		subwf	mode_flg,W
		btfss	STATUS,C		;MODEフラグ >= 8 か？
		goto	nxdsp10			;No

nxdsp09		movlw	h'40'			;左. ("Period")指定
		goto	nxdsp12			;Ver(_x.xx __) / Error(x_.xx xx)

nxdsp10		movlw	4
		subwf	mode_flg,W
		btfsc	STATUS,Z		;MODEフラグ = 4(SET モード) か？
		goto	nxdsp11			;Yes

		movlw	h'10'			;右 .("Period")指定
		btfsc	time_flg,5		;気温表示時の"Period"制御フラグ = 1 か？
		goto	nxdsp12			;Yes.  温度(_x xx.xx)

nxdsp11		movlw	h'50'			;両..("Period")指定 ... 年月日(xx.xx.xx)

nxdsp12		xorlw	h'ff'			;ビット反転
		movwf	PORTC			;

		movlw	h'00'
		movwf	PORTB			;LEDの点灯
		call	wait_100us		;100u 秒 ウェイト
	;	call	wait_100us		;要調整（使用するLEDによる）
		movlw	h'02'			;
		movwf	PORTB			;LEDの消灯
		call	wait_100us		;要調整

		; 初期処理のときだけ１秒経過の監視

		movlw	8
		subwf	mode_flg,W
		btfss	STATUS,Z		;表示モードフラグ = 8(初期処理)表示 か？
		goto	nxdsp13			;No

		decfsz	lp_cnt3,F		;１秒経過カウンタ - 1 = 0 か？
		goto	nxdsp01			;No

nxdsp13		return

;--------------------------------------------------------------------------

;		ニキシー管の輝度コントロール（要調整）

bright_cntrl
		movwf	PORTB		;ニキシー管の点灯
		call	wait_1ms	;
		call	wait_1ms	;

		movlw	h'02'		;LED も消灯
		movwf	PORTB		;ニキシー管の消灯
		call	wait_100us	;
		call	wait_100us	;
		return		

;--------------------------------------------------------------------------
;		SET モード / タイマー機能中のニキシー管の表示制御
;--------------------------------------------------------------------------

set_ext_nixie_display

		bsf	STATUS,RP0		;バンク 1
		movlw	b'00000000'		;RC7-0: 出力
		movwf	TRISC
		bcf	STATUS,RP0		;バンク 0

		call	nixie_display		;ニキシー管の表示

		movlw	h'ff'			;;時間表示時、入力ポートに切り替える前に 'H' を出しておく
		movwf	PORTC			;;これを行わないと切り替えたとたんに、出力時の :("Colon")
						;;指定が引き継がれて、４つの SW が ON ('L') になってしまう
		bsf	STATUS,RP0		;バンク 1
		movlw	b'11110000'		;RC7-4: 入力, RC3-0: 出力
		movwf	TRISC
		bcf	STATUS,RP0		;バンク 0
		return

;==========================================================================
;		拡張機能（タイマー & 温度 スイッチ機能等）
;==========================================================================

;--------------------------------------------------------------------------
;	  CH1 ～ CH3 スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

;		ext_flg:  タイマー機能フラグ
;						bit7: タイマー用メモリの設定フラグ
;						bit6: タイマー用メモリの消去フラグ
;						bit5: タイマー機能中の LED 表示制御フラグ
;						bit4: ブリンク表示フラグ
;						bit3: ダイレクト・コントロールフラグ
;						bit2: CH3 フラグ
;						bit1: CH2 フラグ
;						bit0: CH1 フラグ

timer_switch
		call	wait_15ms		;チャッタリング吸収
		clrf	ext_flg			;タイマー設定フラグの初期設定

timer01		comf	PORTA,W			;全ビットを反転
		andlw	h'03'			;スイッチ入力だけ取り出す
		btfss	STATUS,Z		;どれか（CH1～CH2）のスイッチ = ON か？
		goto	timer02			;Yes

		call	xExpPCF8574_Read	;（PCF8574/74A）のポートからデータを読み出し
		btfsc	exptmp,7		;CH3（SW7）スイッチ = ON か？
		goto	timer03			;No

		movlw	h'04'			;bit2: CH3 フラグ

timer02		movwf	work1			;退避
		movlw	h'f8'
		andwf	ext_flg,F		;クリア
		movf	work1,W			;復帰
		iorwf	ext_flg,F		;CH1 ～ CH3 スイッチの記憶

		btfss	PORTC,_swSET		;MODE / SET スイッチ = ON か？
		bsf	ext_flg,7		;Yes. タイマー用メモリの設定フラグ = 1

		btfss	PORTC,_swDEL		;DELETE / DOWN スイッチ = ON か？
		bsf	ext_flg,6		;Yes. タイマー用メモリの消去フラグ = 1

		call	wait_15ms		;チャッタリング吸収
		goto	timer01

timer03		call	wait_15ms		;チャッタリング吸収

		movf	ext_flg,W
		btfsc	STATUS,Z		;どれか（CH1～CH3）のスイッチ = ON か？
		goto	timerx3			;No. 終了

		movlw	h'ff'			;ブルー LED 消灯
		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み

		bsf	ext_flg,5		;タイマー機能中の LED 表示制御フラグ = 1

		movlw	tm0_h_val		;ハードタイマー０カウント値を
		movwf	TMR0			;TMR0 に設定
		movlw	tm0_s_val1		;ソフトタイマー０カウント値 = 8 を
		movwf	tm0_s_cnt		;ソフトタイマー０カウンタに設定
		bsf	INTCON,T0IE		;bit5(T0IE)=1: タイマー０割り込み許可

;--------------------------------------------------------------------------

		btfss	ext_flg,7		;タイマー用メモリの設定フラグ = 1 か？
		goto	timer30			;No

		; CH1～CH3 + SET スイッチ（タイマー用メモリの設定）
		; ------------------------------------------------

timer10		clrf	temp_hh			;初期設定
		clrf	temp_mm			;
		clrf	temp_ss			;
		btfsc	ext_flg,2		;CH = 3 か？
		bsf	temp_ss,4		;Yes. h'10'
		clrf	tg_point		;対象の位置ポインタ = 0

		; メモリ設定データの表示

timer11		btfsc	ext_flg,4		;ブリンク表示フラグ = 1 (非表示) か？
		goto	timer12			;Yes

;		btfsc	ext_flg,0		;CH = 1 か？
		movlw	h'fe'			;(xx:xx xx)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'fd'			;(xx.xx xx)表示
		btfsc	ext_flg,2		;CH = 3 か？
		movlw	h'fc'			;(xx xx xx)表示
		goto	timer16

timer12		movf	tg_point,F
		btfss	STATUS,Z		;tg_point = 0 か？
		goto	timer13			;No

		movlw	h'3e'			;(__:xx xx)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'3d'			;(__.xx xx)表示
		btfsc	ext_flg,2		;CH = 3 か？
		movlw	h'3c'			;(__ xx xx)表示
		goto	timer16

timer13		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 1 か？
		goto	timer14			;No

		movlw	h'ce'			;(xx:__ xx)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'cd'			;(xx.__ xx)表示
		btfsc	ext_flg,2		;CH = 3 か？
		movlw	h'cc'			;(xx __ xx)表示
		goto	timer16

timer14		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 2 か？
		goto	timer15			;No

		movlw	h'f6'			;(xx:xx _x)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'f5'			;(xx.xx _x)表示
		btfsc	ext_flg,2		;CH = 3 か？
		movlw	h'f4'			;(xx xx _x)表示
		goto	timer16

timer15		movlw	h'fa'			;(xx:xx x_)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'f9'			;(xx.xx x_)表示
		btfsc	ext_flg,2		;CH = 3 か？
		movlw	h'f8'			;(xx xx x_)表示

timer16		movwf	dspdigit		;表示桁指定フラグの設定
		movlw	temp_hh			;仮の時 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地に設定

		call	set_ext_nixie_display	;ニキシー管の表示
		call	xtime_monitor		;タイマー & 温度の監視と時報音出力コントロール

		; 各スイッチの入力処理

timer17		btfss	PORTC,_swSET		;SET スイッチ = ON か？
		call	set2_switch		;Yes

		btfss	PORTC,_swUP		;UP スイッチ = ON か？
		call	up2_switch		;Yes

		btfss	PORTC,_swDWN		;DOWN スイッチ = ON か？
		call	down2_switch		;Yes

		btfss	PORTC,_swBAK		;BACK スイッチ = ON か？
		call	back2_switch		;Yes

		movlw	4
		subwf	tg_point,W
		btfsc	STATUS,Z		;tg_point = 4 か？
		goto	timer18			;Yes

		btfsc	PORTE,_swCAN		;CANCEL スイッチ = ON か？
		goto	timer11			;No
		goto	timerx1			;Yes. 終了

timer18		btfss	ext_flg,2		;CH = 3 か？
		goto	timer20			;No

		; CH = 3 のときの動作

		movf	temp_hh,W		;
		iorwf	temp_mm,W		;
		btfss	STATUS,Z		;temp_hh = temp_mm = 0 か？
		goto	timer20			;No. インターバル・タイマー（間隔制御）

		; ダイレクト・コントロール（直接制御）
		bsf	ext_flg,3		;ダイレクト・コントロールフラグ = 1
		;	temp_ss			;0www.00mm
		movlw	b'00010000'		;    CH1 = RA4
		btfss	temp_ss,4		;CH1 か？
		movlw	b'00100000'		;No. CH2 = RA5

		btfsc	temp_ss,0		;mm bit = x1: ON 出力 か？
		iorwf	PORTA,F			;Yes. リレーを ON
		xorlw	h'ff'
		btfss	temp_ss,0		;mm bit = x0: OFF 出力 か？
		andwf	PORTA,F			;Yes. リレーを OFF

		; アラームフラグの設定
		btfss	alm_flg,7		;アラーム音出力許可フラグ = 1 か？
		goto	timer19			;No

		btfsc	temp_ss,0		;mm bit = x1: ON 出力 か？
		bsf	alm_flg,0		;Yes. リレー ON フラグ = 1
		btfss	temp_ss,0		;mm bit = x0: OFF 出力 か？
		bsf	alm_flg,1		;Yes. リレー OFF フラグ = 1

timer19		btfss	temp_ss,1		;mm bit = 1x: SLP 出力 か？
		goto	timerx2			;No. 終了

		movlw	h'01'
		movwf	temp_hh			;1 時間後
		movlw	h'72'
		andwf	temp_ss,F		;SLP & OFF

		; タイマー用メモリへの書き込み
						;           C
		;	temp_ss			;0www.00mm  x
timer20		clrf	fmmwwwss		;0000.0000  x
		bcf	STATUS,C		;           0
		rrf	temp_ss,F		;00ww.w00m  m
		rrf	fmmwwwss,F		;m000.0000  0
		rrf	temp_ss,W		;000w.ww00  m
		rrf	fmmwwwss,F		;mm00.0000  0
		rrf	fmmwwwss,F		;0mm0.0000  0
		iorwf	fmmwwwss,F		;0mmw.ww00  x

		btfss	ext_flg,2		;CH = 3 か？
		goto	timer21			;No

		; CH = 3 のとき
		rlf	temp_ss,F		;0www.00mx  0
		swapf	temp_ss,W		;00mx.0www  0、www bit には ss bit が入っている
		andlw	h'03'
		iorwf	fmmwwwss,F		;ss bit をセット
						;www bit は interval_time でクリア後再セット
		call	interval_time           ;インターバル時間の計算
		bsf	temp_hh,7		;C bit（メモリ自動消去フラグ）をセット
		goto	timer22

		; CH = 1,2 のとき
timer21		movlw	h'03'
		andwf	ext_flg,W		;ss bit を取り出す
		iorwf	fmmwwwss,F		;0mmw.wwss
						;f bit は write_memory 内でセット
		; CH = 1,2,3 のとき
timer22		bsf	PCLATH,3		;ページ 1
		call	write_memory		;タイマー用メモリへの書き込み
		bcf	PCLATH,3		;ページ 0

		btfsc	STATUS,C		;書き込み済み OK か？
		goto	timer23			;No. C フラグ = 1 = メモリオーバーエラー

		btfsc	ext_flg,1		;CH2 フラグ = 1 か？
		incf	ch2_cnt,F		;Yes. CH2 メモリカウンタ +1 更新

		btfsc	ext_flg,3		;ダイレクト・コントロールフラグ = 1 か？
		goto	timerx2			;Yes. 終了

		call	buzzer_pipi		;No. "ピピッ" ブザー音
		goto	timer10

		; 書き込み（メモリオーバー）エラーのとき

timer23		call	buzzer_bubuu		;"ブッブー" ブザー音出力

		movlw	h'99'			;ERROR'999999'
		movwf	temp_hh
		movwf	temp_mm
		movwf	temp_ss
;		movlw	temp_hh			;仮の時 BCD カウンタの番地
;		movwf	tempfsr			;間接アドレスの先頭番地に設定

timer24		movlw	h'fc'			;(xx xx xx)表示
		btfsc	ext_flg,4		;ブリンク表示フラグ = 1 (非表示) か？
		movlw	h'00'			;(__ __ __)表示
		movwf	dspdigit		;表示桁指定フラグの設定

		call	set_ext_nixie_display	;ニキシー管の表示

		movlw	h'ff'			;ブルー LED 全消灯
		btfsc	ext_flg,4		;ブリンク表示フラグ = 1 か？
		xorlw	h'3f'			;ブルー LED 全点灯, 上位 2 ビット = h'c0'
		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み

		btfsc	PORTE,_swCAN		;CANCEL スイッチ = ON か？
		goto	timer24			;No
		goto	timerx1			;Yes. 終了

;--------------------------------------------------------------------------

timer30		btfss	ext_flg,6		;タイマー用メモリの消去フラグ = 1 か？
		goto	timer40			;No

		; CH1～CH3 + DELETE スイッチ（タイマー用メモリの消去）
		; ---------------------------------------------------

		bsf	PCLATH,3		;ページ 1
		call	clear_memory		;CH 別タイマー用メモリの消去
		bcf	PCLATH,3		;ページ 0

		btfsc	ext_flg,1		;CH = 2 か？
		clrf	ch2_cnt			;Yes. CH2 メモリカウンタ = 0 クリア

		movlw	h'03'
		andwf	ext_flg,W		;CHx フラグ
		btfsc	STATUS,Z		;下 2 bit = '00' か？
		movlw	h'03'			;Yes. '100' = CH3 → '11', 
		movwf	temp_hh			;    ('001' = CH1 → '01', '010' = CH2 → '10' )

		movf	temp_ss,W		;
		btfss	STATUS,Z		;消去件数 > 0 か？
		call	buzzer_pipi		;Yes. "ピピッ" ブザー音
		movf	temp_ss,W		;
		btfsc	STATUS,Z		;消去件数 > 0 か？
		call	buzzer_buu		;No. "ブー" ブザー音

		call	delete_report		;タイマー用メモリの消去数報告
		goto	timerx2			;終了

;--------------------------------------------------------------------------

;	dsp_cnt: タイマー用メモリの表示カウンタ
;						bit5: タイマー用メモリ検索終了フラグ
;						bit4-0: カウンタ

		; CH1～CH3 スイッチ（タイマーメモリ内容の表示）
		; --------------------------------------------

timer40		clrf	dsp_cnt			;表示カウンタの初期設定

timer41		bsf	PCLATH,3		;ページ 1
		call	read_memory		;タイマー用メモリの読み出し
		bcf	PCLATH,3		;ページ 0

timer42		btfss	dsp_cnt,5		;タイマー用メモリ検索終了フラグ = 1 か？
		goto	timer43			;No

		movlw	h'02'			;(__:__ __)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'01'			;Yes. (__.__ __)表示
		btfsc	ext_flg,2		;CH = 3 か？
		movlw	h'00'			;Yes. (__ __ __)表示
		goto	timer45

timer43		movf	fmmwwwss,W		;fmmwwwss を壊さないためにワークへ
		movwf	work1			;fmmw.wwss  x
		rrf	work1,F			;xfmm.wwws  s
		swapf	work1,F			;wwws.xfmm  s
		movlw	h'03'
		andwf	work1,W			;mm bit を取り出す
		movwf	temp_ss			;0000.00mm

		btfsc	ext_flg,2		;CH = 3 か？
		goto	timer44			;Yes

		rrf	work1,W			;swww.sxfm  m
		andlw	h'70'			;www bit を取り出す
		iorwf	temp_ss,F		;0www.00mm

		movlw	h'fe'			;(xx:xx xx)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'fd'			;Yes. (xx.xx xx)表示
		goto	timer45

timer44		swapf	fmmwwwss,W		;wwss.fmmw
		andlw	h'30'			;ss bit を取り出す
		iorwf	temp_ss,F		;00ss.00mm

		movlw	h'fc'			;(xx xx xx)表示

timer45		movwf	dspdigit		;表示桁指定フラグの設定
		movlw	temp_hh			;仮の時 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地に設定

timer46		call	set_ext_nixie_display	;ニキシー管の表示
		call	xtime_monitor		;タイマー & 温度の監視と時報音出力コントロール

		; 各スイッチの入力処理

		btfss	PORTC,_swDEL		;DELETE / DOWN スイッチ = ON か？
		goto	timer52			;Yes

		btfss	PORTE,_swCAN		;CANCEL スイッチ = ON か？
		goto	timerx1			;Yes. 終了

		comf	PORTA,W			;全ビットを反転
		andlw	h'03'			;スイッチ入力だけ取り出す
		btfsc	STATUS,Z		;どれか（CH1～CH2）のスイッチ = ON か？
		goto	timer48			;No

		movwf	work1			;退避
		call	wait_15ms		;チャッタリング吸収

timer47		comf	PORTA,W			;全ビットを反転
		andlw	h'03'			;スイッチ入力だけ取り出す
		btfss	STATUS,Z		;全スイッチ（CH1～CH2）= OFF か？
		goto	timer47			;No
		goto	timer50			;Yes

timer48		call	xExpPCF8574_Read	;（PCF8574/74A）のポートからデータを読み出し
		btfsc	exptmp,7		;CH3（SW7）スイッチ = ON か？
		goto	timer46			;No

		movlw	h'04'			;bit2: CH3 フラグ
		movwf	work1			;退避
		call	wait_15ms		;チャッタリング吸収

timer49		call	xExpPCF8574_Read	;（PCF8574/74A）のポートからデータを読み出し
		btfss	exptmp,7		;CH3（SW7）スイッチ = OFF か？
		goto	timer49			;No

timer50		call	wait_15ms		;チャッタリング吸収

		movf	work1,W			;復帰
		xorwf	ext_flg,W		;比較する
		andlw	h'07'			;
		btfss	STATUS,Z		;スイッチ入力は前回と等しい か？
		goto	timer51			;No

		btfss	dsp_cnt,5		;タイマー用メモリ検索終了フラグ = 1 か？
		goto	timer41			;No
		goto	timer40			;Yes

timer51		movlw	h'f8'			;
		andwf	ext_flg,W		;旧スイッチ入力だけクリアして
		iorwf	work1,W
		movwf	ext_flg			;新スイッチと入れ替える
		goto	timer40

		; DELETE スイッチ（タイマーメモリ内容の個別消去）
		; --------------------------------------------

timer52		call	wait_15ms		;チャッタリング吸収
		btfss	PORTC,_swDEL		;DELETE / DOWN スイッチ = OFF か？
		goto	$ - 1			;No

		movlw	h'03'			;
		andwf	ext_flg,W		;CHx 番号の取り出し
		btfsc	STATUS,Z		;CHx 番号 = 00 か？
		movlw	h'03'			;Yes
		movwf	temp_hh
		clrf	temp_ss			;消去件数 = 0

		btfsc	dsp_cnt,5		;タイマー用メモリ検索終了フラグ = 1 か？
		goto	timer53			;Yes

		bsf	PCLATH,3		;ページ 1
		call	delete_memory		;タイマー用メモリの個別消去
		bcf	PCLATH,3		;ページ 0

		incf	temp_ss,F		;消去件数 +1 = 1
		decf	dsp_cnt,F		;表示カウンタの更新
		btfsc	ext_flg,1		;CH2 フラグ = 1 か？
		decf	ch2_cnt,F		;Yes. CH2 メモリカウンタ -1 更新

timer53		btfss	dsp_cnt,5		;タイマー用メモリ検索終了フラグ = 1 か？
		call	buzzer_pipi		;No. "ピピッ" ブザー音
		btfsc	dsp_cnt,5		;タイマー用メモリ検索終了フラグ = 1 か？
		call	buzzer_buu		;Yes. "ブー" ブザー音

		call	delete_report		;タイマー用メモリの消去数報告
		goto	timer41

;--------------------------------------------------------------------------

		; タイマー機能の終了

timerx1		call	wait_15ms		;チャッタリング吸収
		btfss	PORTE,_swCAN		;CANCEL スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

timerx2		bcf	INTCON,T0IE		;タイマー０割り込みを禁止
		bcf	INTCON,T0IF		;タイマー０割込みフラグをクリア
		clrf	ext_flg			;タイマー設定フラグをクリア

timerx3		return

;--------------------------------------------------------------------------

		; タイマー用メモリの消去数報告

delete_report					;            CH   件数
		movlw	h'4c'			;     CH3 = (_x __ xx)表示
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'4d'			;Yes. CH2 = (_x.__ xx)表示
		btfsc	ext_flg,0		;CH = 1 か？
		movlw	h'4e'			;Yes. CH1 = (_x:__ xx)表示
		movwf	dspdigit		;表示桁指定フラグの設定

		movlw	temp_hh
		movwf	tempfsr			;間接アドレスの先頭番地の設定

		movlw	2			;2,505.8 mS x 2 = 5,011.6 mS = 5 秒間
		movwf	lp_cnt1			;ループカウンタ1

drep01		movlw	187			;(2.2 mS x 6 + 0.2) mS x 187= 2,505.8 mS
		movwf	lp_cnt2			;ループカウンタ2

drep02		call	set_ext_nixie_display	;ニキシー管の表示

		movlw	h'2c'			;     ブルー LED (_x __ xx) 点灯
		btfsc	ext_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'3f'			;Yes. ブルー LED (__ __ __) 消灯

		iorlw	h'c0'			;書き込みデータに上位 2 ビットを追加
		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み

		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	drep02			;No

		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	drep01			;No

		movlw	h'ff'			;ブルー LED (__ __ __) 消灯
		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み
		return

;--------------------------------------------------------------------------
;		インターバル時間の計算（24時間表示に変換）
;--------------------------------------------------------------------------

interval_time
		; 本日の曜日（www bit）

		movlw	h'e3'
		andwf	fmmwwwss,F	;www bit をクリア
		movf	bcd_ww,W	;曜日 BCD カウンタ
		movwf	work1		;ワーク
		rlf	work1,F
		rlf	work1,W		;左に 2 ビットシフト
		andlw	h'1c'
		iorwf	fmmwwwss,F	;www 位置に加える

		; 分の計算

		movf	bcd_mm,W
		addwf	temp_mm,F	;仮の 分_BCD カウンタ
		movf	temp_mm,W
		andlw	h'0f'		;下位4ビット
		sublw	h'09'		;9 - W
		movlw	h'06'
		btfss	STATUS,C	;下位4ビット > 9 か？
		addwf	temp_mm,F	;Yes. 下位4ビット = +6, (上位4ビット = +1)

		movf	temp_mm,W
		sublw	h'59'		;h'59' - W
		btfsc	STATUS,C	;仮の 分_BCD カウンタ > h'59' か？
		goto	itval01		;No. OK

		movlw	h'60'
		subwf	temp_mm,F	;仮の 分_BCD カウンタ - h'60'
		incf	temp_hh,F	;仮の 時_BCD カウンタ +1

		; 時の計算

itval01		movf	bcd_hh,W
		addwf	temp_hh,F	;仮の 時_BCD カウンタ
		movf	temp_hh,W
		andlw	h'0f'		;下位4ビット
		sublw	h'09'		;9 - W
		movlw	h'06'
		btfss	STATUS,C	;下位4ビット > 9 か？
		addwf	temp_hh,F	;Yes. 下位4ビット = +6, (上位4ビット = +1)

		movf	temp_hh,W
		sublw	h'23'		;h'23' - W
		btfsc	STATUS,C	;仮の 時_BCD カウンタ > h'23' か？
		goto	itval03		;No. OK

		movlw	h'24'
		subwf	temp_hh,F	;仮の 時_BCD カウンタ - h'24'

		; 曜日の更新

		movf	fmmwwwss,W
		andlw	h'1c'		;www bit
		addlw	h'04'		;www bit + 1
		andlw	h'1c'		;www bit
		btfsc	STATUS,Z	;www bit = 8 か？
		goto	itval02		;Yes

		movlw	h'04'
		addwf	fmmwwwss,F	;www bit + 1
		goto	itval03

itval02		movlw	h'e3'
		andwf	fmmwwwss,F	;www bit をクリア
		bsf	fmmwwwss,2	;www bit = 1

itval03		return

;==========================================================================
;		各種スイッチの処理
;==========================================================================

;--------------------------------------------------------------------------
;	  TIME MODE / UP スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

tmode_switch
		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swTMD		;再度 TMODE スイッチ = ON か？
		goto	tmodsw01		;No

		movlw	b'00000010'
		xorwf	time_flg,F		;時間表示モードフラグ (bit1=0:24H/1:12H) 反転

		btfss	PORTC,_swTMD		;TMODE スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

tmodsw01	return

;--------------------------------------------------------------------------
;	   ZERO / BACK スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

zero_switch
		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swZER		;再度 ZERO スイッチ = ON か？
		goto	zersw05			;No

		movf	mode_flg,W
		btfss	STATUS,Z		;表示モードフラグ = 0(時間)表示 か？
		goto	zersw04			;No. 無視

		movlw	h'05'
		subwf	bcd_mm,W
		btfsc	STATUS,C		;分 BCD カウンタ < h'05' か？
		goto	zersw01			;No

		bcf	INTCON,INTE		;外部(RB0/INT)割り込み許可 = 0:禁止
		goto	zersw03

zersw01		movlw	h'55'
		subwf	bcd_mm,W
		btfss	STATUS,C		;分 BCD カウンタ >= h'55' か？
		goto	zersw04			;No. 無視

		bcf	INTCON,INTE		;外部(RB0/INT)割り込み許可 = 0:禁止
		call	bcd_hh_inc		;時 BCD カウンタのインクリメント
		movf	bcd_hh,W
		btfss	STATUS,Z		;時 BCD カウンタ = h'00' か？
		goto	zersw03			;No

		call	bcd_dd_inc		;日 BCD カウンタのインクリメント
		movlw	h'01'
		subwf	bcd_dd,W
		btfss	STATUS,Z		;日 BCD カウンタ = h'01' か？
		goto	zersw02			;No

		call	bcd_nn_inc		;月 BCD カウンタのインクリメント
		movlw	h'01'
		subwf	bcd_nn,W
		btfsc	STATUS,Z		;月 BCD カウンタ = h'01' か？
		call	bcd_yl_inc		;Yes. 年(下位2桁) BCD カウンタのインクリメント

zersw02		call	day_week		;該当日の曜日を取得
		movwf	bcd_ww			;曜日 BCD カウンタ

zersw03		btfss	PORTC,_swZER		;ZERO スイッチ = OFF か？
		goto	$ - 1			;No

		clrf	bcd_mm			;分 BCD カウンタのクリア
		clrf	bcd_ss			;秒 BCD カウンタのクリア
		call	counter_to_buffer
		xRtc_Write_M  seconds,7		;RTC DS3231 へ年月日、時分秒を書き込み

		bsf	INTCON,INTE		;外部(RB0/INT)割り込み許可 = 1:禁止解除

zersw04		call	wait_15ms		;チャッタリング吸収

zersw05		return

;--------------------------------------------------------------------------
;	    SIGNAL スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

;出力:		alm_flg: 時報音出力フラグ ( bit0:予報音, bit1:正報音, bit7:出力許可 )

signal_switch
		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTE,_swSIG		;再度 SIGNAL スイッチ = ON か？
		goto	sigsw01			;No

		movlw	b'10000000'
		xorwf	alm_flg,W		;時報音出力許可フラグの更新
		movwf	work1			;退避

		bsf	alm_flg,7		;
		btfsc	work1,7			;時報音出力許可フラグ = 1 か？
		call	buzzer_pipipi		;Yes. "ピピピッ" ブザー音出力
		btfss	work1,7			;時報音出力許可フラグ = 0 か？
		call	buzzer_buu		;Yes. "ブー" ブザー音出力

		movf	work1,W
		movwf	alm_flg			;復帰

		btfss	PORTE,_swSIG		;SIGNAL スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

sigsw01		return

;--------------------------------------------------------------------------
;	  MODE / SET スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

mode_switch
		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swMOD		;再度 MODE スイッチ = ON か？
		goto	modsw14			;No

		; ブルー LED の曜日表示の設定

		btfsc	PORTC,_swDEL		;DELETE スイッチ = ON か？
		goto	modsw02			;No

modsw01		call	wait_15ms		;チャッタリング吸収

		btfss	PORTC,_swDEL		;DELETE スイッチ = OFF か？
		goto	modsw01			;No

		call	wait_15ms		;チャッタリング吸収
		movlw	b'00010000'		;
		xorwf	time_flg,F		;ブルー LED 曜日表示フラグ 反転
		goto	modsw14			;No

		; (4/8Mz*256*250=32msec) * 157 = 5,024 ms = 約５秒間長押しの監視

modsw02		movlw	tm0_h_val		;ハードタイマー０カウント値 = (256 - 250) を
		movwf	TMR0			;TMR0 に設定
		movlw	tm0_s_val2		;ソフトタイマー０カウント値 = 157 を
		movwf	tm0_s_cnt		;ソフトタイマー０カウンタに設定
		bsf	INTCON,T0IE		;T0IE: タイマー０割り込みを許可
		bsf	modex_flg,5		;SET移行手続き中フラグ = 1

modsw03		movf	tm0_s_cnt,F
		btfsc	STATUS,Z		;ソフトタイマー０カウンタ = 0 か？
		goto	modsw09			;Yes. SETモードに移行

		btfsc	PORTC,_swMOD		;MODEスイッチ = OFF か？
		goto	modsw08			;Yes. SETモード移行手続き中断

		btfss	int_flg,0		;年月日,時分秒データの読み出し要求フラグ = 1 か？
		goto	modsw04			;No

		xRtc_Read_M  seconds,7		;RTC DS3231 から年月日,時分秒データを読み出し
		call	buffer_to_counter
		bcf	int_flg,0		;年月日,時分秒データの読み出し要求フラグ = 0

modsw04		movf	mode_flg,W
		btfsc	STATUS,Z		;表示モードフラグ = 0(時間)表示 か？
		goto	modsw05			;Yes

		btfss	time_flg,6		;(bit6=1:オートモードで(時間)表示 (mode_switch 用)) = 1 か？
		goto	modsw07			;No

modsw05		movlw	bcd_hh			;時 BCD カウンタの番地
		btfss	time_flg,1		;時間表示モードフラグ (bit1=0:24H/1:12H) = 1:12H か？
		goto	modsw06			;No

		bsf	time_flg,7		;(bit7=1:オートモードで(時間)表示 (nixie_display 用)) = 1
		movf	bcd_hh,W		;時 BCD カウンタ
		movwf	temp_hh			;仮の時 BCD カウンタ
		movf	bcd_mm,W		;分 BCD カウンタ
		movwf	temp_mm
		movf	bcd_ss,W		;秒 BCD カウンタ
		movwf	temp_ss
		call	cnv_24to12		;24時間表示を12時間表示に変換
		movlw	temp_hh			;仮の時 BCD カウンタの番地

modsw06		movwf	tempfsr			;間接アドレスの先頭番地に設定
		movlw	h'fe'			;時間(xx:xx:xx)表示指定
		movwf	dspdigit		;表示桁指定フラグの設定

modsw07		call	set_ext_nixie_display	;ニキシー管の表示
		goto	modsw03

		; 表示モードフラグの更新

modsw08		bcf	INTCON,T0IE		;T0IE: タイマー０割り込みを禁止

		incf	mode_flg,F		;表示モードフラグの更新
		movlw	4
		subwf	mode_flg,W
		btfsc	STATUS,Z		;表示モードカウンタ = 4 か？
		clrf	mode_flg		;Yes. mode_flg = 0 にクリア
		bcf	modex_flg,5		;SET移行手続き中フラグ = 0
		bsf	modex_flg,7		;表示モード変更フラグ = 1
		goto	modsw14

;--------------------------------------------------------------------------

		; SET モードに移行

modsw09		call	buzzer_pi		;"ピッ" ブザー音

	;;	bcf	INTCON,T0IE		;T0IE: タイマー０割り込みを禁止（割り込み処理内でクリア済み）
		bcf	INTCON,INTE		;INTE: 外部(RB0/INT)割り込みを禁止
		bcf	time_flg,7		;(bit7=1:オートモードで(時間)表示 (nixie_display 用)) = 0
		clrf	modex_flg		;表示モード変更フラグの初期設定（念のため）
		movlw	4
		movwf	mode_flg		;表示モードフラグ = 4(SET)表示に設定

		; SET モード移行メッセージの表示

;		movlw	h'ff'			;"__"
;		movwf	temp_hh
;		movwf	temp_mm
;		movwf	temp_ss
;		movlw	temp_hh
;		movwf	tempfsr			;間接アドレスの先頭番地の設定
;		movlw	h'01'			;(__.__.__)表示
;		movwf	dspdigit		;表示桁指定フラグの設定

;		call	set_ext_nixie_display	;ニキシー管の表示（消灯）

modsw10		movlw	h'c0'			;ブルー LED 全点灯
		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み
		call	wait_250ms

		movlw	h'ff'			;ブルー LED 全消灯
		call	xExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み
		call	wait_250ms

		btfss	PORTC,_swSET		;MODE/SET スイッチ = OFF か？
		goto	modsw10			;No

		call	wait_15ms		;チャッタリング吸収
		clrf	tg_point		;対象の位置ポインタ = 0

		movlw	tm0_h_val		;ハードタイマー０カウント値を
		movwf	TMR0			;TMR0 に設定
		movlw	tm0_s_val1		;ソフトタイマー０カウント値 = 8 を
		movwf	tm0_s_cnt		;ソフトタイマー０カウンタに設定
		bsf	INTCON,T0IE		;bit5(T0IE)=1: タイマー０割り込み許可

		; SET モード中のデータ表示

modsw11		call	set_mode_pattern	;SET モード中の表示パターン制御
		call	set_ext_nixie_display	;ニキシー管の表示

		; SET モード中の各スイッチの入力処理

		btfss	PORTC,_swSET		;SET スイッチ = ON か？
		call	set_switch		;Yes

		btfss	PORTC,_swUP		;UP スイッチ = ON か？
		call	up_switch		;Yes

		btfss	PORTC,_swDWN		;DOWN スイッチ = ON か？
		call	down_switch		;Yes

		btfss	PORTC,_swBAK		;BACK スイッチ = ON か？
		call	back_switch		;Yes

		movlw	6
		subwf	tg_point,W
		btfsc	STATUS,Z		;tg_point = 6 か？
		goto	modsw12			;Yes. 終了

		btfsc	PORTE,_swCAN		;CANCEL スイッチ = ON か？
		goto	modsw11			;No

		; SET モードの終了

		call	wait_15ms		;チャッタリング吸収
		btfss	PORTE,_swCAN		;CANCEL スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収
		goto	modsw13			;中断

modsw12		call	counter_to_buffer
		xRtc_Write_M  seconds,7		;RTC DS3231 へ年月日、時分秒を書き込み

modsw13		clrf	mode_flg		;表示モードフラグの初期設定  0:時間
		clrf	modex_flg		;表示モード変更フラグの初期設定
		bcf	INTCON,T0IE		;T0IE: タイマー０割り込みを禁止
		bsf	INTCON,INTE		;INTE: 外部(RB0/INT)割り込みを禁止解除

modsw14		btfss	PORTC,_swMOD		;MODE スイッチ = OFF か？
		goto	$ - 1			;No

		return

;--------------------------------------------------------------------------

;		SET モード中のニキシー管の表示パターン制御

set_mode_pattern

		movlw	bcd_yy			;年 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地の設定
		bcf	time_flg,7		;時間表示モードフラグ (bit7=1: SETモードで(時間)表示) = 0

		movf	tg_point,W
		btfss	STATUS,Z		;対象の位置ポインタ = 0 か？
		goto	smptn01			;No

		movlw	h'fd'			;年月日(xx.xx.xx)表示指定
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'3d'			;年月日(__.xx.xx)表示指定
		goto	smptn07

smptn01		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z		;対象の位置ポインタ = 1 か？
		goto	smptn02			;No

		movlw	h'fd'			;年月日(xx.xx.xx)表示指定
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'cd'			;年月日(xx.__.xx)表示指定
		goto	smptn07

smptn02		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z		;対象の位置ポインタ = 2 か？
		goto	smptn03			;No

		movlw	h'fd'			;年月日(xx.xx.xx)表示指定
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'f1'			;年月日(xx.xx.__)表示指定
		goto	smptn07

smptn03		movlw	bcd_hh			;時 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地の設定

		movlw	3
		subwf	tg_point,W
		btfss	STATUS,Z		;対象の位置ポインタ = 3 か？
		goto	smptn05			;No

		btfss	time_flg,1		;時間表示モードフラグ (bit1=0:24H/1:12H) = 1:12H か？
		goto	smptn04			;No

		movf	bcd_hh,W		;時 BCD カウンタ
		movwf	temp_hh			;仮の時 BCD カウンタ
		call	cnv_24to12		;Yes. 24時間表示を12時間表示に変換
		movlw	temp_hh			;仮の時 BCD カウンタの番地
		movwf	tempfsr			;間接アドレスの先頭番地に設定

smptn04		bsf	time_flg,7		;時間表示モードフラグ (bit7=1: SETモードで(時間)表示) = 1
		movlw	h'fe'			;年月日(xx:xx:xx)表示指定
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'3e'			;時分秒(__:xx:xx)表示指定
		goto	smptn07

smptn05		movlw	4
		subwf	tg_point,W
		btfss	STATUS,Z		;対象の位置ポインタ = 4 か？
		goto	smptn06			;No

		movlw	h'fe'			;年月日(xx:xx:xx)表示指定
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'ce'			;時分秒(xx:__:xx)表示指定
		goto	smptn07

smptn06	;	movlw	5
	;	subwf	tg_point,W
	;	btfss	STATUS,Z		;対象の位置ポインタ = 5 か？
	;	goto	smptn07			;No

		movlw	h'fe'			;年月日(xx:xx:xx)表示指定
		btfsc	modex_flg,4		;ブリンク表示フラグ = 1 か？
		movlw	h'f2'			;時分秒(xx:xx:__)表示指定

smptn07		movwf	dspdigit		;表示桁指定フラグの設定
		return

;--------------------------------------------------------------------------
;	   SET スイッチの処理 ... SET モード / TIMER 機能から CALL
;--------------------------------------------------------------------------

set_switch	;; SET モード
set2_switch	;; TIMER 機能

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swSET		;再度 SET スイッチ = ON か？
		goto	setsw01			;No

		incf	tg_point,F		;対象の位置ポインタ + 1

		btfss	PORTC,_swSET		;SET スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

setsw01		return

;--------------------------------------------------------------------------
;	   UP スイッチの処理 ... SET モード / TIMER 機能から CALL
;--------------------------------------------------------------------------

up_switch	;; SET モード

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swUP		;再度 UP スイッチ = ON か？
		goto	upsw08			;No

		movf	tg_point,W
		btfss	STATUS,Z		;tg_point = 0 か？
		goto	upsw01			;No

		call	bcd_yl_inc		;年 BCD カウンタのインクリメント
		goto	upsw03

upsw01		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 1 か？
		goto	upsw02			;No

		call	bcd_nn_inc		;月 BCD カウンタのインクリメント
		goto	upsw03

upsw02		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 2 か？
		goto	upsw04			;No

		call	bcd_dd_inc		;日 BCD カウンタのインクリメント

upsw03		call	day_week		;該当日の曜日を取得
		movwf	bcd_ww			;曜日 BCD カウンタ
		goto	upsw07

upsw04		movlw	3
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 3 か？
		goto	upsw05			;No

		call	bcd_hh_inc		;時 BCD カウンタのインクリメント
		goto	upsw07

upsw05		movlw	4
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 4 か？
		goto	upsw06			;No

		call	bcd_mm_inc		;分 BCD カウンタのインクリメント
		goto	upsw07

upsw06	;	movlw	5
	;	subwf	tg_point,W
	;	btfss	STATUS,Z		;tg_point = 5 か？
	;	goto	upsw07			;No

		call	bcd_ss_inc		;秒 BCD カウンタのインクリメント

upsw07	;	btfss	PORTC,_swUP		;UP スイッチ = OFF か？
	;	goto	$ - 1			;No

		call	wait_200ms		;早送りの速度調整

upsw08		return

;--------------------------------------------------------------------------

up2_switch	;; TIMER 機能

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swUP		;再度 UP スイッチ = ON か？
		goto	upsw26			;No

		movf	tg_point,W
		btfss	STATUS,Z		;tg_point = 0 か？
		goto	upsw21			;No

		btfsc	ext_flg,0		;CH = 1 か？
		call	bcd_hh_inc2		;Yes. 時 BCD カウンタのインクリメント
		btfsc	ext_flg,1		;CH = 2 か？
		call	temp_int_inc		;Yes. 温度(整数) BCD カウンタのインクリメント
		btfsc	ext_flg,2		;CH = 3 か？
		call	bcd_hh_inc2		;Yes. 時 BCD カウンタのインクリメント
		goto	upsw26

upsw21		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 1 か？
		goto	upsw22			;No

		btfsc	ext_flg,0		;CH = 1 か？
		call	bcd_mm_inc2		;Yes. 分 BCD カウンタのインクリメント
		btfsc	ext_flg,1		;CH = 2 か？
		call	temp_dec_inc		;Yes. 温度(小数) BCD カウンタのインクリメント
		btfsc	ext_flg,2		;CH = 3 か？
		call	bcd_mm_inc2		;Yes. 分 BCD カウンタのインクリメント
		goto	upsw26

upsw22		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 2 か？
		goto	upsw24			;No

		btfsc	ext_flg,2		;CH = 3 か？
		goto	upsw23			;Yes

		movlw	h'10'
		addwf	temp_ss,F		;曜日 BCD カウンタのインクリメント
		movlw	h'80'
		subwf	temp_ss,W
		btfss	STATUS,C		;temp_ss < h'80' か？
		goto	upsw26			;Yes

		movlw	h'0f'
		andwf	temp_ss,F		;上位4ビット = 0
		goto	upsw26

upsw23		movlw	h'30'
		xorwf	temp_ss,F		;01 → 10 → 01
		goto	upsw26

		; CH1,CH3: 00:OFF → 01:ON → 11:SLP → 00
		;     CH2: 00:OFF → 01:ON → 00
upsw24		incf	temp_ss,F		;MODE(OFF,ON,SLP) のインクリメント
		movf	temp_ss,W
		andlw	h'0f'
		movwf	work1			;下位4ビットを取り出す

		movlw	h'02'			;
		subwf	work1,W
		btfss	STATUS,C		;work1 < h'02' か？
		goto	upsw26			;Yes. 01:ON

		btfsc	ext_flg,1		;CH = 2 か？
		goto	upsw25			;Yes

		incf	temp_ss,F	
		btfss	temp_ss,2		;下位4ビット >= 4 か？
		goto	upsw26			;No. 11:SLP

upsw25		movlw	h'f0'
		andwf	temp_ss,F		;MODE(OFF,ON,SLP) = 00:OFF

upsw26	;	btfss	PORTC,_swUP		;UP スイッチ = OFF か？
	;	goto	$ - 1			;No

		call	wait_200ms		;早送りの速度調整
		return

;--------------------------------------------------------------------------

		; 温度(整数) BCD カウンタのインクリメント
temp_int_inc
		movlw	temp_hh			;温度(整数) BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
#ifdef temp_ds3231
		movlw	h'80'
#else
	;;	movlw	h'a0'
		movlw	h'80'			;同値に変更した
#endif
		subwf	temp_hh,W
		btfsc	STATUS,Z		;温度(整数) BCD カウンタ = h'80' or h'a0' か？
		clrf	temp_hh			;Yes. 温度(整数) BCD カウンタのクリア
		return

		; 温度(小数) BCD カウンタのインクリメント
temp_dec_inc

#ifdef temp_ds3231
		; 00 → 25 → 50 → 75 → 00
		;            (4A)        (9A)
		movlw	h'25'
		addwf	temp_mm,F		;temp_mm + h'25' 更新

;		movlw	h'0f'
;		andwf	temp_mm,W	
;		xorlw	h'0a'
;		btfss	STATUS,Z		;下位 4 ビット = h'0a' か？
;		goto	tdinc01			;No

		btfss	temp_mm,3		;bit3 = 1 か？
		goto	tdinc01			;No

		movlw	h'06'
		btfsc	temp_mm,7		;bit7 = 1 か？（h'75' + h'25' をしたとき）
		movlw	h'66'			;Yes
		addwf	temp_mm,F		;temp_mm + (h'06' or h'66') 補正

tdinc01		return
#else
		movlw	h'10'
		addwf	temp_mm,F		;temp_mm + h'10' 更新

		movlw	h'a0'
		subwf	temp_mm,W		;
		btfsc	STATUS,Z		;温度(整数) BCD カウンタ = h'a0' か？
		clrf	temp_mm			;Yes. 温度(小数) BCD カウンタのクリア
		return
#endif

;--------------------------------------------------------------------------
;	  DOWN スイッチの処理 ... SET モード / TIMER 機能から CALL
;--------------------------------------------------------------------------

down_switch	;; SET モード

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	dwnsw08			;No

		movf	tg_point,W
		btfss	STATUS,Z		;tg_point = 0 か？
		goto	dwnsw01			;No

		call	bcd_yl_dec		;年 BCD カウンタのデクリメント
		goto	dwnsw03

dwnsw01		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 1 か？
		goto	dwnsw02			;No

		call	bcd_nn_dec		;月 BCD カウンタのデクリメント
		goto	dwnsw03

dwnsw02		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 2 か？
		goto	dwnsw04			;No

		call	bcd_dd_dec		;日 BCD カウンタのデクリメント

dwnsw03		call	day_week		;該当日の曜日を取得
		movwf	bcd_ww			;曜日 BCD カウンタ
		goto	dwnsw07

dwnsw04		movlw	3
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 3 か？
		goto	dwnsw05			;No

		call	bcd_hh_dec		;時 BCD カウンタのデクリメント
		goto	dwnsw07

dwnsw05		movlw	4
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 4 か？
		goto	dwnsw06			;No

		call	bcd_mm_dec		;分 BCD カウンタのデクリメント
		goto	dwnsw07

dwnsw06	;	movlw	5
	;	subwf	tg_point,W
	;	btfss	STATUS,Z		;tg_point = 5 か？
	;	goto	dwnsw07			;No

		call	bcd_ss_dec		;秒 BCD カウンタのデクリメント

dwnsw07	;	btfss	PORTC,_swDWN		;DWN スイッチ = OFF か？
	;	goto	$ - 1			;No

		call	wait_200ms		;早送りの速度調整

dwnsw08		return

;--------------------------------------------------------------------------

down2_switch	;; TIMER 機能

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swDWN		;再度 DOWN スイッチ = ON か？
		goto	dwnsw26			;No

		movf	tg_point,W
		btfss	STATUS,Z		;tg_point = 0 か？
		goto	dwnsw21			;No

		btfsc	ext_flg,0		;CH = 1 か？
		call	bcd_hh_dec2		;Yes. 時 BCD カウンタのデクリメント
		btfsc	ext_flg,1		;CH = 2 か？
		call	temp_int_dec		;Yes. 温度(整数) BCD カウンタのデクリメント
		btfsc	ext_flg,2		;CH = 3 か？
		call	bcd_hh_dec2		;Yes. 時 BCD カウンタのデクリメント
		goto	dwnsw26

dwnsw21		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 1 か？
		goto	dwnsw22			;No

		btfsc	ext_flg,0		;CH = 1 か？
		call	bcd_mm_dec2		;Yes. 分 BCD カウンタのデクリメント
		btfsc	ext_flg,1		;CH = 2 か？
		call	temp_dec_dec		;Yes. 温度(小数) BCD カウンタのデクリメント
		btfsc	ext_flg,2		;CH = 3 か？
		call	bcd_mm_dec2		;Yes. 分 BCD カウンタのデクリメント
		goto	dwnsw26

dwnsw22		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z		;tg_point = 2 か？
		goto	dwnsw24			;No

		btfsc	ext_flg,2		;CH = 3 か？
		goto	dwnsw23			;Yes

		movlw	h'10'
		subwf	temp_ss,F		;曜日 BCD カウンタのデクリメント
		btfsc	STATUS,C		;temp_ss < h'10' か？
		goto	dwnsw26			;No

		movlw	h'80'
		addwf	temp_ss,F		;曜日 BCD カウンタ = 7
		goto	dwnsw26

dwnsw23		movlw	h'30'
		xorwf	temp_ss,F		;01 → 10 → 01
		goto	dwnsw26

		; CH1,CH3: 11:SLP → 01:ON → 00:OFF → 11
		;     CH2:           01:ON → 00:OFF → 01
dwnsw24		movf	temp_ss,W		;現在の値
		andlw	h'0f'
		btfsc	STATUS,Z		;下位4ビット = 0 か？
		goto	dwnsw25			;Yes

		decf	temp_ss,F		;MODE(OFF,ON,SLP) のデクリメント
		movf	temp_ss,W
		andlw	h'0f'			;下位4ビットを取り出す
		sublw	h'02'
		btfsc	STATUS,Z		;下位4ビット = 0010:-- か？
		decf	temp_ss,F		;Yes. 01:ON
		goto	dwnsw26

dwnsw25		movlw	h'03'			;00:OFF, 01:ON, 10:--, 11:SLP
		btfsc	ext_flg,1		;CH = 2 か？
		movlw	h'01'			;Yes. 00:OFF, 01:ON
		iorwf	temp_ss,F		;MODE(OFF,ON,SLP) = 最大値

dwnsw26	;	btfss	PORTC,_swDWN		;DWN スイッチ = OFF か？
	;	goto	$ - 1			;No

		call	wait_200ms		;早送りの速度調整
		return

;--------------------------------------------------------------------------

		; 温度(整数) BCD カウンタのデクリメント
temp_int_dec
		decf	temp_hh,F		;温度(整数) BCD カウンタ -1 更新
		incf	temp_hh,W
		btfss	STATUS,Z		;温度(整数) BCD カウンタ = h'ff' か？
		goto	tidec01			;No

#ifdef temp_ds3231
		movlw	h'79'
#else
	;;	movlw	h'99'
		movlw	h'79'			;同値に変更した
#endif
		movwf	temp_hh			;温度(整数) BCD カウンタ 更新
		goto	tidec02

tidec01		movf	temp_hh,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0f'
		btfss	STATUS,Z		;下位4ビット = h'0f' か？
		goto	tidec02			;No

		movlw	h'06'
		subwf	temp_hh,F		;温度(整数) BCD カウンタ 更新

tidec02		return	

		; 温度(小数) BCD カウンタのデクリメント
temp_dec_dec

#ifdef temp_ds3231
		; 00 → 75 → 50 → 25 → 00
		;      (DB)        (2B)
		movlw	h'25'
		subwf	temp_mm,F		;temp_mm - h'25' 更新

;		movlw	h'0f'
;		andwf	temp_mm,W	
;		btfsc	STATUS,Z		;下位 4 ビット = h'00' か？
;		goto	tddec01			;Yes

		btfss	temp_mm,3		;bit3 = 1 か？
		goto	tddec01			;No

		movlw	h'06'
		btfsc	temp_mm,7		;bit7 = 1 か？（h'00' - h'25' をしたとき）
		movlw	h'66'			;Yes
		subwf	temp_mm,F		;temp_mm - (h'06' or h'66') 補正

tddec01		return
#else
		movlw	h'10'
		subwf	temp_mm,F		;temp_mm - h'10' 更新

		movlw	h'f0'
		subwf	temp_mm,W		;
		movlw	h'90'
		btfsc	STATUS,Z		;温度(整数) BCD カウンタ = h'f0' か？
		movwf	temp_mm			;Yes. 温度(小数) BCD カウンタ 更新
		return
#endif

;--------------------------------------------------------------------------
;	  BACK スイッチの処理 ... SET モード / TIMER 機能から CALL
;--------------------------------------------------------------------------

back_switch	;; SET モード
back2_switch	;; TIMER 機能

		call	wait_15ms		;チャッタリング吸収
		btfsc	PORTC,_swBAK		;再度 BACK スイッチ = ON か？
		goto	baksw02			;No

		decf	tg_point,F		;対象の位置ポインタ + 1
		incf	tg_point,W
		btfss	STATUS,Z		;対象の位置ポインタ = 0 か？
		goto	baksw01			;No

		movlw	5			;(SET モード)
		movf	ext_flg,F
		btfss	STATUS,Z		;ext_flg = h'00' か？
		movlw	3			;No. (TIMER 機能)
		movwf	tg_point		;最大値 tg_point = 5 or 3 に設定

baksw01		btfss	PORTC,_swBAK		;BACK スイッチ = OFF か？
		goto	$ - 1			;No

		call	wait_15ms		;チャッタリング吸収

baksw02		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	bcd_dd			;日 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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
		bcf	STATUS,C
		rlf	work1,F			;2倍
		rlf	work1,F			;4倍
		addwf	work1,F			;5倍
		rlf	work1,F			;10倍

		movf	work2,W			;下位4ビット(単位)
		andlw	h'0f'
		addwf	work1,W			;10位 + 単位 = W レジスタ
		return

;--------------------------------------------------------------------------
;		月 BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_nn_inc
		movlw	bcd_nn			;月 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	bcd_yl			;年(下位2桁) BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	bcd_yh			;年(上位2桁) BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	bcd_ss			;秒 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	bcd_mm			;分 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'60'
		subwf	bcd_mm,W
		btfsc	STATUS,C		;分 BCD カウンタ < h'60' か？
		clrf	bcd_mm			;No. 分 BCD カウンタのクリア
		return

bcd_mm_inc2
		movlw	temp_mm			;分 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'60'
		subwf	temp_mm,W
		btfsc	STATUS,C		;分 BCD カウンタ < h'60' か？
		clrf	temp_mm			;No. 分 BCD カウンタのクリア
		return

;--------------------------------------------------------------------------
;		時 BCD カウンタのインクリメント
;--------------------------------------------------------------------------

bcd_hh_inc
		movlw	bcd_hh			;時 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'24'
		subwf	bcd_hh,W
		btfsc	STATUS,C		;時 BCD カウンタ < h'24' か？
		clrf	bcd_hh			;No. 時 BCD カウンタのクリア
		return

bcd_hh_inc2
		movlw	temp_hh			;時 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	inc_bcd			;BCDインクリメント
		movlw	h'24'
		subwf	temp_hh,W
		btfsc	STATUS,C		;時 BCD カウンタ < h'24' か？
		clrf	temp_hh			;No. 時 BCD カウンタのクリア
		return

;--------------------------------------------------------------------------
;		秒 BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_ss_dec
		movlw	bcd_ss			;秒 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	bcd_mm			;分 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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_mm_dec2
		movlw	temp_mm			;分 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	dec_bcd			;BCDデクリメント
		movlw	h'f9'			;h'00' - h'01' - h'06'
		subwf	temp_mm,W
		btfss	STATUS,Z		;分 BCD カウンタ = h'f9' か？
		goto	mdec201			;No

		movlw	h'59'
		movwf	temp_mm			;分 BCD カウンタ = h'59' 設定

mdec201		return

;--------------------------------------------------------------------------
;		時 BCD カウンタのデクリメント
;--------------------------------------------------------------------------

bcd_hh_dec
		movlw	bcd_hh			;時 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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_hh_dec2
		movlw	temp_hh			;時 BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		call	dec_bcd			;BCDデクリメント
		movlw	h'f9'			;h'00' - h'01' - h'06'
		subwf	temp_hh,W
		btfss	STATUS,Z		;時 BCD カウンタ = h'f9' か？
		goto	hdec201			;No

		movlw	h'23'
		movwf	temp_hh			;時 BCD カウンタ = h'23' 設定

hdec201		return

;--------------------------------------------------------------------------

;		BCD インクリメント

inc_bcd
		incf	INDF,F			;BCD カウンタ +1 更新
		movf	INDF,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0a'
		btfss	STATUS,Z		;下位4ビット = d'10' か？
		return				;No

		movlw	h'06'
		addwf	INDF,F			;下位4ビット = 0, 上位4ビット = +1
		return

;--------------------------------------------------------------------------

;		BCD デクリメント

dec_bcd
		movf	INDF,W
		andlw	h'0f'			;下位4ビット
		btfsc	STATUS,Z		;下位4ビット <> h'00' か？
		goto	dec01			;No

		decf	INDF,F			;-1 更新
		return

dec01		decf	INDF,F			;-1 更新
		movlw	h'06'
		subwf	INDF,F			;下位4ビット = 9
		return

;--------------------------------------------------------------------------
;		8 ビット数値を 10進数 3桁の BCD 数値に変換
;--------------------------------------------------------------------------

		;	work1: 変換する 8 ビット数値
		;	work2: ワーク
		;	buff0,buff1,buff2: BCD 数値

bin8bcd3_cnv
		movlw	buff0 + 2 + 1		;変換文字列の格納エリア
		movwf	FSR			;間接アドレスの設定
		call	bb8c			;(02) 最下位変換
		call	bb8c			;(01)
		call	bb8c			;(00) 最上位変換
		return

		; ÷10（10で除算）
bb8c
		movlw	8			;8ビット繰り返し
		movwf	lp_cnt1			;シフトカウンタに設定
		clrf	work2			;一時余り格納場所のクリア

bb8c01		bcf	STATUS,C		;キャリーフラグのクリア
		rlf	work1,F
		rlf	work2,F

		movlw	-10			;-10 = h'f6'
		addwf	work2,W
		btfsc	STATUS,C		;C = 0 か？
		movwf	work2			;No
		btfsc	STATUS,C		;C = 0 か？
		incf	work1,F			;No
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	bb8c01			;No

		decf	FSR,F			;間接アドレスの更新
		movf	work2,W			;余りを
		movwf	INDF			;格納
		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	cur_yl			;年(下位2桁)(変) BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	cur_yh			;年(上位2桁)(変) BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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	cur_nn			;月(変) BCD カウンタの番地
		movwf	FSR			;間接アドレスに設定
		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

;--------------------------------------------------------------------------

#ifdef comment
month_day2
		decf	work2,W
		addwf	PCL,F			;プログラム・カウンタに加算

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  (使用しない)
#endif

month_day2
		decf	work2,W
		movwf	addr_low
		movlw	high day_table
		movwf	addr_high		;読み出しデータの high アドレス
		movlw	low day_table
		addwf	addr_low,F		;読み出しデータの low アドレス
		btfsc	STATUS,C		;オーバーフローした場合は
		incf	addr_high,F		;high アドレスの更新

		movf	addr_high,W		;読み出しデータの high アドレス
		movwf	PCLATH
		movf	addr_low,W		;読み出しデータの low アドレス
		movwf	PCL

day_table	dt	31 % 7			; 1:  31 % 7 = 3
		dt	28 % 7			; 2:  28 % 7 = 0
		dt	31 % 7			; 3:  31 % 7 = 3
		dt	30 % 7			; 4:  30 % 7 = 2
		dt	31 % 7			; 5:  31 % 7 = 3
		dt	30 % 7			; 6:  30 % 7 = 2
		dt	31 % 7			; 7:  31 % 7 = 3
		dt	31 % 7			; 8:  31 % 7 = 3
		dt	30 % 7			; 9:  30 % 7 = 2
		dt	31 % 7			;10:  31 % 7 = 3
		dt	30 % 7			;11:  30 % 7 = 2
;		dt	31 % 7			;12:  31 % 7 = 3  (使用しない)

;==========================================================================
;		時報音出力コントロール
;==========================================================================

;  NHKの時報は、1000ミリ秒以上の無音、予報音3回、正報音1回、1000ミリ秒以上の無音という構成になっている。 
;  予報音は、一定音量の440Hzの正弦波を100ミリ秒発振させ、その後900ミリ秒の無音を置く。
;  これを1セットとして、正時の3秒前から3回繰り返している。
;  正報音は、880Hzの正弦波を発振させ、1000ミリ秒間一定の音量に保ち、次の2000ミリ秒で減衰させている。
;  出典: フリー百科事典『ウィキペディア（Wikipedia）』 ( http://ja.wikipedia.org/wiki/%E6%99%82%E5%A0%B1 )

;		時報音出力コントロール	

time_signal
		btfss	alm_flg,7		;時報音出力許可フラグ = 1 か？
		goto	ts102			;No

		movlw	h'59'
		subwf	bcd_mm,W		;分 BCD カウンタ
		btfss	STATUS,Z		;bcd_mm = h'59' か？
		goto	ts101			;No

		movlw	h'57'
		subwf	bcd_ss,W		;秒 BCD カウンタ
		btfss	STATUS,C		;bcd_ss >= h'57' か？
		goto	ts101			;No

		; "プッ"			;予報音 (440Hz)
;		call	buzzer_pu		;"プッ"
		bsf	alm_flg,2		;予報音フラグのセット
		goto	ts102

ts101		movf	bcd_ss,W
		iorwf	bcd_mm,W
		btfss	STATUS,Z		;bcd_ss = bcd_mm = h'00' か？
		goto	ts102			;No

		; "ポッ～～ン"			;正報音 (880Hz)
;		call	buzzer_poon		;"ポッ～～ン"
		bsf	alm_flg,3		;No. 正報音フラグのセット

ts102		return

;--------------------------------------------------------------------------

;		アラームフラグの監視とアラーム音出力

; alm_flg: アラームフラグ

;		┌───────────  signal_switch で設定
;		│　　　　 ┌────── time_signal で設定	
;		│　　　　 │　┌──── time_monitor で設定
;		│　　　　┌┐┌┐
;		ｘ００ｘ．ｘｘｘｘ
;		│　　│　││││
;		│　　│　│││└─── リレー ON フラグ	;"ピポッピポッ"
;		│　　│　││└──── リレー OFF フラグ	;"ブーー"
;		│　　│　│└───── 時報予報音フラグ	;"プッ"
;		│　　│　└────── 時報正報音フラグ	;"ポッ～～ン"
;		│　　└──────── 時報正報音抑止フラグ（起動時の出力を抑止）
;		└─────────── アラーム音出力許可フラグ

alarm_sound
;		btfss	alm_flg,7		;アラーム音出力許可フラグ = 1 か？
;		goto	alarm05			;（このフラグ = OFF のときは、
						;４つのフラグ = ON になることはない）
		movlw	h'6f'
		andwf	alm_flg,W
		btfsc	STATUS,Z		;どれかアラームフラグ = 1 か？
		goto	alarm05			;No

		btfss	alm_flg,0		;リレー ON フラグ = 1 か？
		goto	alarm01			;No

		call	buzzer_pipo2		;"ピポッピポッ" ブザー音出力 (490 mS)
		goto	alarm04

alarm01		btfss	alm_flg,1		;リレー OFF フラグ = 1 か？
		goto	alarm02			;No

		call	buzzer_buu		;"ブー" ブザー音出力 (250 mS)
		call	buzzer_buu		;"ブー" ブザー音出力 (250 mS)
		goto	alarm04

alarm02		btfss	alm_flg,2		;時報予報音フラグ = 1 か？
		goto	alarm03			;No

		call	buzzer_pu		;"プッ" ブザー音出力 (100 mS)
		goto	alarm04

alarm03		btfsc	alm_flg,4		;時報正報音抑止フラグ = 1 か？
		goto	alarm04			;Yes

		call	buzzer_poon		;"ポッ～～ン" ブザー音出力 (1000 mS)
		bcf	PORTB,_BZ		;ブザー出力ビットを "L" にしておく
	;	goto	alarm04

alarm04		movlw	h'80'
		andwf	alm_flg,F		;アラームフラグをクリア

alarm05		return

;==========================================================================
;		アラーム（ブザー）音出力ルーチン
;==========================================================================

		; 時報予報音 "プッ" ブザー音出力 (100 mS)
buzzer_pu
		Sound_M		f_ra, 100
		return

		; 時報正報音 "ポッ～～ン" ブザー音出力 (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
		return

		;"ピピピッ" ブザー音 (360 mS)
buzzer_pipipi
		call	buzzer_pi		;"ピッ" ブザー音出力
		call	wait_30ms

		;"ピピッ" ブザー音 (230 mS)
buzzer_pipi
		call	buzzer_pi		;"ピッ" ブザー音出力
		call	wait_30ms

		; "ピッ" ブザー音出力
buzzer_pi
		Sound_M		f_so, pi_tim
		return

		; "ピポッピポッ" ブザー音出力 (490 mS)
buzzer_pipo2
		call	buzzer_pipo		;"ピポッ" ブザー音出力
		call	wait_30ms

		; "ピポッ" ブザー音出力 (230 mS)
buzzer_pipo
		call	buzzer_pi		;"ピッ" ブザー音出力
		call	wait_30ms

		; "ポッ" ブザー音出力
buzzer_po
		Sound_M		f_doh, po_tim
		return

		; "ブッ" ブザー音出力
buzzer_bu
		Sound_M		f_do, bu_tim
		return

		; "ブー" ブザー音出力
buzzer_buu
		Sound_M		f_do, buu_tim
		return

		; "ブッブー" ブザー音出力 (450 mS)
buzzer_bubuu
		call	buzzer_bu		;"ブッ" ブザー音出力
		call	wait_100ms
		call	buzzer_buu		;"ブー" ブザー音出力
		return

		; ブザー音出力コントロール
buzzer_control
		bsf	STATUS,RP0		;バンク 1
		bsf	PIE1,TMR1IE		;タイマー１割り込みを許可
		bcf	STATUS,RP0		;バンク 0

		call	wait_xxms		;入力 W: 音長（ループカウンタ）

		bsf	STATUS,RP0		;バンク 1
		bcf	PIE1,TMR1IE		;タイマー１割り込みを禁止
		bcf	STATUS,RP0		;バンク 0
		return

;==========================================================================
;		ウェイト・ルーチン (8 MHz)
;==========================================================================

		; 100μ秒 ウェイトルーチン
wait_100us
		movlw	39			;1
		movwf	wt1cnt			;1
wu02		goto	$+1			;2
		decfsz	wt1cnt,F		;1,2
		goto	wu02			;2,0	1+1+(2+1+2)*38+(2+2+0)=196
		goto	$+1			;2
		return				;2	196+2+2=200
						;Total	200/8MHz*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

		; 250m 秒 ウェイトルーチン
wait_250ms
		movlw	250
		goto	wait_xxms

		; 1m 秒 ウェイトルーチン
wait_1ms
		movlw	1

		; xx m 秒（ 1m 秒 x W ）ウェイトルーチン
wait_xxms
		movwf	wt2cnt			;1

w1m01		movlw	221			;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)*220+(2+2+2+2+0)=1988

		nop				;1
		goto	$ + 1			;2
		goto	$ + 1			;2
		decfsz	wt2cnt,F		;1,2
		goto	w1m01			;2,0	(1+1+1988+1+2+2+1+2)*(W-1)+(1+1+1988+1+2+2+2+0)=1998*W-1

		return				;2	1+(1998*W-1)+2=1998*W+2
						;Total	(1998*W+2)/8MHz*4 = (999*W + 1) μ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

;--------------------------------------------------------------------------

xExpPCF8574_Write
		bsf	PCLATH,3		;ページ 1
		call	ExpPCF8574_Write
		bcf	PCLATH,3		;ページ 0
		return

xExpPCF8574_Read
		bsf	PCLATH,3		;ページ 1
		call	ExpPCF8574_Read
		bcf	PCLATH,3		;ページ 0
		return


;=============================================================================================================
 		org	h'800'			;(ページ 1)
;=============================================================================================================

;==========================================================================
;		サブルーチンファイルのインクルード
;==========================================================================

#define 	TRISX	TRISA			;PORTA で I2C を行う場合、
#define 	PORTX	PORTA			;

;				ドライブ、パス名は、各自の開発環境に合わせるように !!

		include		C:\Data\Project\PIC\_sub\I2C_XS.sub
		include		C:\Data\Project\PIC\_sub\I2C_RTCII.sub

		include		C:\Data\Project\PIC\_sub\DS18B20_1W.sub

;==========================================================================
;	I/O エキスパンダ IC（PCF8574/74A）のポートとのデータ入出力
;==========================================================================

#ifdef _PCF8574A
ExpAddr		equ	h'38'			; I/O エキスパンダ IC（PCF8574A）のスレーブアドレス
#else
ExpAddr		equ	h'20'			; I/O エキスパンダ IC（PCF8574） のスレーブアドレス
#endif

;<使用外部ルーチン>

;(i2c_start, i2c_stop, i2c_byte_send, i2c_byte_reciv, i2c_nack)

;<使用レジスタ>

;exptmp						;書き込み／読み出しデータ

;--------------------------------------------------------------------------
;		（PCF8574/74A）のポートへデータを書き込み
;--------------------------------------------------------------------------

ExpPCF8574_Write
		movwf	exptmp			;書き込みデータ退避
		call	i2c_start		;スタートコンディション
		movlw	ExpAddr	<< 1		;スレーブアドレス
		call	i2c_byte_send		;1 バイト送信

		movf	exptmp,W		;書き込みデータ復帰
		call	i2c_byte_send		;1 バイト送信
		call	i2c_stop		;ストップコンディション
		return

;--------------------------------------------------------------------------
;		（PCF8574/74A）のポートからデータを読み出し
;--------------------------------------------------------------------------

ExpPCF8574_Read
		call	i2c_start		;スタートコンディション
		movlw	(ExpAddr << 1) + 1	;スレーブアドレス
		call	i2c_byte_send		;1 バイト送信

		call	i2c_byte_reciv		;1 バイト受信
		movwf	exptmp			;読み出しデータ
		call	i2c_nack		;NACK
		call	i2c_stop		;ストップコンディション
		return

;==========================================================================
;		DS18B20 から温度データの読み出し
;==========================================================================

read_temperature
		btfsc	int_flg,2		;温度変換時間監視中フラグ = 1 か？
		goto	rdtemp04		;Yes

		btfsc	int_flg,3		;温度変換時間監視終了フラグ = 1 か？
		goto	rdtemp01		;Yes

		call	Init_1_Wire		;1-Wire バスの初期設定
		btfsc	STATUS,C		;Error か？
		goto	rdtemp03		;Yes

		movlw	h'cc'			;
		call	Write_1_Wire		;[SKIP ROM] コマンドの送信
		movlw	h'44'			;
		call	Write_1_Wire		;[CONVERT T] コマンドの送信

	;;	bcf	PCLATH,3		;ページ 0
	;;	call	wait_250ms		;750 ms 間（変換時間）待つ
	;;	call	wait_500ms		;分解能 = 12 ビット（デフォルト）
	;;	bsf	PCLATH,3		;ページ 1

		bsf	int_flg,2		;温度変換時間監視中フラグ = 1
		movlw	tm2_s_val		;=47,  16ms x 47 = 752ms
		movwf	tm2_s_cnt		;ソフトタイマー２カウンタに設定
		bsf	T2CON,TMR2ON		;タイマー２ ON/OFF 制御 = ON
		goto	rdtemp04

rdtemp01 	call	Init_1_Wire		;1-Wire バスの初期設定
		btfsc	STATUS,C		;Error か？
		goto	rdtemp03		;Yes

		movlw	h'cc'			;
		call	Write_1_Wire		;[SKIP ROM] コマンドの送信
		movlw	h'be'			;
		call	Write_1_Wire		;[READ SCRATCHPAD] コマンドの送信

		movlw	low sp_temp_lsb		;スクラッチパッド格納エリア (9 byte 使用)
		movwf	FSR
		movlw	9
		movwf	lp_cnt1			;ループカウンタ

rdtemp02	call	Read_1_Wire		;データの受信
		movwf	INDF			;格納エリアに移動
		incf	FSR,F			;間接アドレス +1 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	rdtemp02		;No

	;;	call	crc8			;受信データ 9バイトの CRC8 計算チェック
	;;	btfsc	STATUS,C		;Error か？
	;;	goto	rdtemp0x		;Yes

		goto	rdtemp04		;

rdtemp03	movlw	h'ff'			;ブルー LED 消灯
		call	ExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み

;		[ 9_.18 20 ]			;DS18B20 エラーメッセージ
		movlw	h'9f'			;"9f" = "Error"
		movwf	temp_hh
		movlw	h'18'			;"18"
		movwf	temp_mm
		movlw	h'20'			;"20"
		movwf	temp_ss
		call	error_disp		;DS18B20 異常時のエラー表示

		bcf	PCLATH,3		;ページ 0
		call	wait_1sec		;1 秒間のウエイト
		bsf	PCLATH,3		;ページ 1
		goto	read_temperature

rdtemp04	return

;--------------------------------------------------------------------------

;		00h: sp_temp_lsb    bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
;				    2^3   2^2   2^1   2^0   2^-1  2^-2  2^-3  2^-4
;
;		01h: sp_temp_msb    bit7  bit6  bit5  bit4  bit3  bit2  bit1  bit0
;				     S     S     S     S     S    2^6   2^5   2^4 

		; 温度データの BCD 変換
temp_cnv2
		btfss	sp_temp_msb,7		;マイナス(-)値 か？
		goto	tcv201			;No

		comf	sp_temp_lsb,F		;正値に変換
		comf	sp_temp_msb,F		;
		movlw	1			;
		addwf	sp_temp_lsb,F		;
		btfsc	STATUS,C		;C = 1 か？
		addwf	sp_temp_msb,F		;Yes

		bsf	sp_temp_msb,7	;;	;マイナスサインを残しておく

		;(整数部分)
tcv201		swapf	sp_temp_lsb,W		;00h: Temperature LSB
		andlw	h'0f'
		movwf	work1
		swapf	sp_temp_msb,W		;01h: Temperature MSB
		andlw	h'f0'
		iorwf	work1,F			;(整数部分) 0, 2^6, 2^5, 2^4, 2^3, 2^2, 2^1, 2^0

		bcf	PCLATH,3		;ページ 0
		call	bin8bcd3_cnv		;8 ビット数値を 10進数 3桁の BCD 数値に変換
		bsf	PCLATH,3		;ページ 1

		swapf	buff1,W	
		addwf	buff2,W
		movwf	buff1	  ;temp_mm	;仮の分 BCD カウンタ

		;(小数部分)
		clrf	buff2	    		;仮の秒 BCD カウンタの初期設定

		movlw	high h'5000'		;上位
		btfsc	sp_temp_lsb,3		;00h: Temperature LSB.bit3 = 1 か？
		movwf	buff2			;Yes

		movlw	high h'2500'		;上位
		btfsc	sp_temp_lsb,2		;00h: Temperature LSB.bit2 = 1 か？
		addwf	buff2,F			;Yes

		movlw	high h'1250' ;+ 1	;上位
		btfsc	sp_temp_lsb,1		;00h: Temperature LSB.bit1 = 1 か？
		addwf	buff2,F			;Yes

		movlw	high h'0625'		;上位
		btfsc	sp_temp_lsb,0		;00h: Temperature LSB.bit0 = 1 か？
		addwf	buff2,F			;Yes

		movlw	h'0f'
		andwf	buff2,W			;下位４ビット
		sublw	h'09'
		movlw	h'06'
		btfss	STATUS,C		;C = 0 (W > 9) か？
		addwf	buff2,F	  ;temp_ss	;Yes.  buff2 + 6

		movlw	h'09'			;
		btfsc	sp_temp_msb,7		;マイナスサイン = 1 か？
		movwf	buff0	  ;temp_hh	;Yes. 仮の時 BCD カウンタ
		return

;--------------------------------------------------------------------------

;　例．		(msb)      (lsb)

;		1111 1111  1111 1000	-0.5
;		0000 0000  0000 0111
;		                  +1
;		0000 0000  0000 1000

;		1111 1111  0101 1110	-10.125
;		0000 0000  1010 0001
;		                  +1
;		0000 0000  1010 0010

;		1111 1110  0110 1111	-25.0625
;		0000 0001  1001 0000
;		                  +1
;		0000 0001  1001 0001

;		1111 1100  1001 0000	-55
;		0000 0011  0110 1111
;		                  +1
;		0000 0011  0111 0000

;		2^-1	50 00
;		2^-2	25 00
;		2^-3	12 50
;		2^-4	06 25

;==========================================================================
;		初期化処理
;==========================================================================

initialize
		bcf	STATUS,RP1
		bcf	STATUS,RP0		;バンク 0
		clrf	PORTA
;		clrf	PORTB
		movlw	h'02'			;起動直後に LED が瞬間点灯するのを防ぐ
		movwf	PORTB			;LED off
		clrf	PORTC

		; PORTA,PORTB をデジタルI/O に設定

		clrf	ADCON0			;ADCON0 の設定, A/D 未使用

		bsf	STATUS,RP0		;バンク 1
		bsf	STATUS,RP1		;バンク 3
		clrf	ANSEL			;すべてデジタルポート指定
		clrf	ANSELH			;

		; PORTA,PORTB,PORTC,PORTE の入出力設定

		bcf	STATUS,RP1		;バンク 1
		movlw	b'00000111'		;RA7-3: 出力, RA2-0: 入力
		movwf	TRISA
		movlw	b'00000001'		;RB7-1: 出力, RB0: 入力
		movwf	TRISB
		clrf	TRISC			;RC7-0: 出力
		movlw	b'00001000'		;RE3: 入力
		movwf	TRISE

		; 内部クロックを 8 MHzに設定

		movlw	b'01110101'		;IRCF=111: 内部クロック周波数選択=8MHz
						;OSTS=0: 内部クロック
						;HTS=1: HFINTOSCステータスビット
						;SCS=1: システムクロック選択=内部クロック
		movwf	OSCCON

		; OPTION_REG の設定

		movlw	b'10000111'		;bit7(PBPU)=1: プルアップ無効
						;bit6(INTEDG)=0: INTピンの立ち下がりエッジで割り込み
						;bit5(T0CS)=0: タイマー０クロックソース選択 = 内部クロック（FOSC / 4）
						;bit4(T0SE)=0: タイマー０エッジ選択 = low-to-high
						;bit3(PSA)=0:  タイマー０でプリスケーラを使用
						;bit2-0(PS2-PS0)=111: プリスケーラのスケール値 = 1:256
		movwf	OPTION_REG

		; 割り込みの設定

		bcf	PIE1,TMR1IE		;TMR1IE: タイマー１割り込みを禁止
		bsf	PIE1,TMR2IE		;TMR2IE: タイマー２割り込みを許可
		movlw	tm2_h_val
		movwf	PR2			;PR2 に設定

		bcf	STATUS,RP0		;バンク 0
		movlw	h'00'			;bit7(GIE)=0:  全割り込み禁止,
						;bit5(T0IE)=0: タイマー０割り込み禁止,
						;bit4(INTE)=0: 外部割り込み(RB0/INT)禁止
		movwf	INTCON

		movlw	b'00000001'		;bit7-6: 未使用
						;bit5-4=00: プリスケーラのスケール値 1:1
						;bit3=0: 専用の発振器を使う場合に指定
						;bit2=0: 外部入力クロック指定時に有効
						;bit1=0: 内部クロックを使う
						;bit0=1: タイマー１を動作
		movwf	T1CON			;T1CON に設定

		movlw	b'00111010'		;bit7:        未使用
						;bit6-3=0111: ポストスケーラのスケール値 1:8
						;bit2(TMR2ON)=0:
						;bit1-0=10:   プリスケーラのスケール値 1:16
		movwf	T2CON			;T2CON に設定

;		bcf	INTCON,T0IE		;T0IE: タイマー０割り込みを禁止
;		bcf	INTCON,INTE		;INTE: 外部(RB0/INT)割り込みを禁止
		bsf	INTCON,PEIE		;PEIE: 周辺機器割り込みを許可
		bsf	INTCON,GIE		;GIE:  グローバル割り込みを許可

		bsf	PORTA,SDA		;SDA="H"
		bsf	PORTA,SCL		;SCL="H"

		movlw	h'ff'
		call	ExpPCF8574_Write	;（PCF8574/74A）の拡張ポートを初期設定

		bcf	PCLATH,3		;ページ 0
		call	buzzer_pipo		;"ピポッ" ブザー音出力
		bsf	PCLATH,3		;ページ 1

		; ニキシー全管の９～０表示テスト

nixie_init
		call	blue_led_demo1		;ブルー LED の点灯デモ (1)

		movlw	8			;8(初期処理)
		movwf	mode_flg		;表示モードフラグを設定
		clrf	modex_flg		;表示モード変更フラグの初期設定
		clrf	time_flg		;時間表示モードフラグの初期設定

		movlw	h'99'			;表示テストデータの初期値
		movwf	temp_hh
		movwf	temp_mm
		movwf	temp_ss

		movlw	h'fc'			;(xx xx xx)表示
		movwf	dspdigit		;表示桁指定フラグの設定
		movlw	temp_hh
		movwf	tempfsr			;間接アドレスの先頭番地の設定

init01		bcf	PCLATH,3		;ページ 0
		call	nixie_display		;ニキシー管の表示
		bsf	PCLATH,3		;ページ 1

		movf	temp_hh,W
		btfsc	STATUS,Z		;全管の９～０表示テスト終了か？
		goto	init02			;Yes

		movlw	h'11'			;全管の表示データを－１
		subwf	temp_hh,F
		subwf	temp_mm,F
		subwf	temp_ss,F
		goto	init01			;全管の９～０表示テストの繰り返し

		; バージョン番号の表示

init02		call	blue_led_demo2		;ブルー LED の点灯デモ (2)
		movlw	h'ff'			;ブルー LED 消灯
		call	ExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み

		movlw	high ver_no		;バージョン番号
		movwf	temp_hh
		movlw	low ver_no		;
		movwf	temp_mm

		movlw	h'71'			;(_x.xx __)表示
		movwf	dspdigit		;表示桁指定フラグの設定
		movlw	temp_hh
		movwf	tempfsr			;間接アドレスの先頭番地の設定

		movlw	5
		movwf	lp_cnt2			;5 秒経過カウンタ

init03		bcf	PCLATH,3		;ページ 0
		call	nixie_display		;ニキシー管の表示
		bsf	PCLATH,3		;ページ 1

		decfsz	lp_cnt2,F		;5 秒経過カウンタ - 1 = 0 か？
		goto	init03			;No

		movlw	h'ff'			;ブルー LED 消灯
		call	ExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み
		bcf	PCLATH,3		;ページ 0
		call	wait_1sec		;1 秒間のウエイト
		bsf	PCLATH,3		;ページ 1

;--------------------------------------------------------------------------

		; I2C RTC（DS3231）モジュールのチェック

rtcinit01	Rtc_Read_M  cont_stat,1		;0Fh: Control/Status 読み出し

		btfss	cont_stat,7		;OSF = 1 か？
		goto	init04			;No

;		[ 9_.32 31 ]			;DS3231 RTC エラーメッセージ
		movlw	h'9f'			;"9f" = "Error"
		movwf	temp_hh
		movlw	h'32'			;"32"
		movwf	temp_mm
		movlw	h'31'			;"31"
		movwf	temp_ss
		call	error_disp		;I2C RTC（DS3231）モジュールのエラー表示

		; I2C RTC（DS3231）モジュールの初期設定

		call	I2cRtc_Init		;I2C RTC（DS3231）モジュールの初期設定

		bcf	PCLATH,3		;ページ 0
		call	wait_1sec		;1 秒間のウエイト
		bsf	PCLATH,3		;ページ 1
		goto	rtcinit01

;--------------------------------------------------------------------------

		; 各変数の初期設定

init04		movlw	h'20'
		movwf	bcd_yh			;年(上位2桁) BCD カウンタの初期設定
		clrf	int_flg			;RTC DS3231 からデータの読み出し要求フラグの初期設定
		clrf	mode_flg		;表示モードフラグの初期設定  0:時間
		clrf	modex_flg		;表示モード変更フラグの初期設定
		clrf	time_flg		;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		clrf	ext_flg			;タイマー機能フラグの初期設定
		clrf	tmon_flg		;タイマー & 温度監視フラグの初期設定
		clrf	ch2_cnt			;CH2 メモリカウンタの初期設定
		clrf	alm_flg
		bsf	alm_flg,4		;時報正報音抑止フラグ = 1（起動時の出力を抑止）
		bsf	alm_flg,7		;時報音出力許可フラグ = 1
		movlw	temp_c_val		;2 秒ごとに読み出しをする（DS18B20 に変更)
		movwf	temp_cnt		;温度読み出しカウンタの初期設定
;
		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movlw	low timer_mem		;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	3 * 20
		movwf	lp_cnt1			;ループカウンタ

init05		clrf	INDF			;タイマー用メモリの初期設定
		incf	FSR,F			;間接アドレス +1 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	init05			;No

		Rtc_Read_M  seconds,7		;RTC DS3231 から年月日,時分秒データを読み出し
		bcf	PCLATH,3		;ページ 0
		call	buffer_to_counter
		bsf	PCLATH,3		;ページ 1
;;		Rtc_Read_M  temp_msb,2		;RTC DS3231 から温度データ 11h,12h を読み出し

		bsf	INTCON,INTE		;INTE: 外部(RB0/INT)割り込みを禁止解除

		bcf	PCLATH,3		;ページ 0
		goto	main

;==========================================================================

;		デバイス ( DS3231 / DS18B20 ) 異常時のエラー表示

error_disp
		bcf	PCLATH,3		;ページ 0
		call	buzzer_bubuu		;"ブッブー" アラーム音出力
		bsf	PCLATH,3		;ページ 1

		movf	mode_flg,W		;
		movwf	work2			;退避
		movlw	9
		movwf	mode_flg		;表示モードフラグ = 9 を設定

		bsf	modex_flg,6		;表示モード変更受付フラグ = 1
		movlw	tm0_h_val		;ハードタイマー０カウント値 = (256 - 250) を
		movwf	TMR0			;TMR0 に設定
		movlw	tm0_s_val1		;ソフトタイマー０カウント値 = 8 を
		movwf	tm0_s_cnt		;ソフトタイマー０カウンタに設定
		bsf	INTCON,T0IE		;T0IE: タイマー０割り込みを許可

		movlw	h'bd'			;(x_.xx xx)表示
		movwf	dspdigit		;表示桁指定フラグの設定
		movlw	temp_hh
		movwf	tempfsr			;間接アドレスの先頭番地の設定

erdsp01		bcf	PCLATH,3		;ページ 0
		call	nixie_display		;ニキシー管の表示
		bsf	PCLATH,3		;ページ 1

		movlw	h'ff'			;;時間表示時、入力ポートに切り替える前に 'H' を出しておく
		movwf	PORTC			;;これを行わないと切り替えたとたんに、出力時の :("Colon")
						;;指定が引き継がれて、４つの SW が ON ('L') になってしまう
		; スイッチ入力チェック

		bsf	STATUS,RP0		;バンク 1
		movlw	b'11110000'		;RC7-4: 入力, RC3-0: 出力
		movwf	TRISC
		bcf	STATUS,RP0		;バンク 0

		movf	PORTC,W			;一度に各スイッチ入力を読み込み
		andlw	h'f0'			;スイッチ入力だけの
		xorlw	h'f0'			;反転値を取り出して
		movwf	work1			;保存する

		bsf	STATUS,RP0		;バンク 1
		movlw	b'00000000'		;RC7-0: 出力
		movwf	TRISC
		bcf	STATUS,RP0		;バンク 0

		movf	work1,W			;
		btfss	STATUS,Z		;どれか（SW1～SW4）のスイッチ = ON か？
		goto	erdsp02			;Yes

		comf	PORTA,W			;全ビットを反転
		andlw	h'03'			;スイッチ入力だけ取り出す
		btfss	STATUS,Z		;どれか（SW5～SW6）のスイッチ = ON か？
		goto	erdsp02			;Yes

		call	ExpPCF8574_Read		;（PCF8574/74A）のポートからデータを読み出し
		btfss	exptmp,7		;CH3（SW7）スイッチ = ON か？
		goto	erdsp02			;Yes

		btfsc	PORTE,3			;SIGNAL（SW8）スイッチ = ON か？
		goto	erdsp01			;No

erdsp02		movf	work2,W			;
		movwf	mode_flg		;復帰

		bcf	INTCON,T0IE		;T0IE: タイマー０割り込みを禁止
		clrf	modex_flg		;表示モード変更フラグの初期設定
		return

;==========================================================================

		; ブルー LED の点灯デモ (1)

blue_led_demo1
		movlw	2
		movwf	lp_cnt1			;ループカウンタ1

bled01		call	blue_right_left		;2 秒間
		call	blue_left_right		;2 秒間

		decfsz	lp_cnt1,F		;ループカウンタ1 - 1 = 0 か？
		goto	bled01			;No

;--------------------------------------------------------------------------

blue_right_left
		movlw	8
		movwf	lp_cnt2			;ループカウンタ2
		clrf	work1			;初期値
		clrf	work2			;
		bsf	work2,0			;

bled02		movf	work1,W
		iorwf	work2,W
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		bcf	STATUS,C		;
		movf	work1,W			;
		btfsc	STATUS,Z		;ループ = 1回目 か？
		bsf	STATUS,C		;Yes

		rlf	work1,F
		rlf	work2,F
		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	bled02			;No

		return

;--------------------------------------------------------------------------

blue_left_right
		movlw	8
		movwf	lp_cnt2			;ループカウンタ2
		clrf	work1			;初期値
		clrf	work2			;
		bsf	work2,5			;

bled03		movf	work1,W
		iorwf	work2,W
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		bcf	STATUS,C		;
		movf	work1,W			;
		btfsc	STATUS,Z		;ループ = 1回目 か？
		bsf	work1,6			;Yes

		rrf	work1,F
		rrf	work2,F
		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	bled03			;No

		return

;--------------------------------------------------------------------------

		; ブルー LED の点灯デモ (2)

blue_led_demo2
		movlw	5
		movwf	lp_cnt2			;ループカウンタ2

bled04		movlw	h'21'
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		movlw	h'12'
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		movlw	h'0c'
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		movlw	h'12'
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		movlw	h'21'
		xorlw	h'3f'			;ビット反転
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		decf	lp_cnt2,W		;ループカウンタ2
		btfsc	STATUS,Z		;ループカウンタ2 = 1 か？
		goto	bled05			;Yes

		movlw	h'3f'			;消灯
		call	ExpWrite_wait		;（PCF8574/74A）のポートへデータを書き込み

		decfsz	lp_cnt2,F		;ループカウンタ2 - 1 = 0 か？
		goto	bled04			;No

bled05		return

;--------------------------------------------------------------------------

ExpWrite_wait
		iorlw	h'c0'			;書き込みデータに上位 2 ビットを追加
		call	ExpPCF8574_Write	;（PCF8574/74A）のポートへデータを書き込み
		bcf	PCLATH,3		;ページ 0
		call	wait_250ms
		bsf	PCLATH,3		;ページ 1
		return

;==========================================================================
;		タイマー用メモリの構成
;==========================================================================

; １メモリ単位 ... (タイマー制御バイト)、(時_BCD カウンタバイト)、(分_BCD カウンタバイト)

; (タイマー制御バイト) ／ fmmwwwss
; --------------------

;  (CH1,CH2)	fmmw.wwss	fmmw.wwss	fmmw.wwss	fmmw.wwss
;  (CH3)	:		 ::		   : ::		       ::
;		0  メモリ無効	 00  OFF	   0 00  EDAY	       01  SW1
;		1  メモリ有効	 01  ON		   0 01  SUN	       10  SW2
;				 10  SLP OFF	   0 10  MON
;				 11  SLP ON	   0 11  TUE
;						   1 00  WED
;						   1 01  THU
;						   1 10  FRI
;						   1 11  SAT

; (時_BCD カウンタバイト)
; -----------------------

;  (CH1,CH3)	chhh.hhhh		chhh.hhhh	chhh.hhhh
;		:			 :::		     ::::
;		1 メモリ自動消去有効	 十時(0～2)	     時(0～9)
;		(c=1: CH3のときのみ)
;  (CH2)				iiii.iiii	iiii.iiii
;					::::		     ::::
;		DS3231	    温度値の整数十位(0～7)	     一位(0～9)
;		DS18B20	    温度値の整数十位(0～7)	     一位(0～9)

; (分_BCD カウンタバイト)
; -----------------------

;  (CH1,CH3)				mmmm.mmmm	mmmm.mmmm
;					::::		     ::::
;					十分(0～5)	     分(0～9)

;  (CH2)				dddd.dddd	dddd.dddd
;					::::		     ::::
;		DS3231	    温度値の小数一位(0,2,5,7)	     小数二位(0,5)
;		DS18B20	    温度値の小数一位(0～9)	     小数二位(0)

;--------------------------------------------------------------------------
;		タイマー用メモリの CH(SW)別消去
;--------------------------------------------------------------------------

;	  汎用変数:	temp_ss, lp_cnt1

clear_memory
		clrf	temp_ss			;ワーク, BCD カウンタ(消去件数) = 0 クリア
		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movlw	low timer_mem		;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1			;ループカウンタ

clmem01		btfss	INDF,7			;(タイマー制御バイト) の f bit = 1 (有効) か？
		goto	clmem04			;No

		btfss	ext_flg,2		;CH = 3 か？
		goto	clmem02			;No

		incf	FSR,F			;間接アドレス +1 更新
		movf	INDF,W			;時_BCD カウンタバイト
		decf	FSR,F			;間接アドレス -1 更新, 元に戻す
		andlw	h'80'			;C bit
		btfss	STATUS,Z		;C bit: メモリ自動消去フラグ = 1 か？
		goto	clmem03			;Yes
		goto	clmem04			;No

clmem02		movlw	h'03'
		andwf	ext_flg,W		;ss bit = 01 or 10
		xorwf	INDF,W			;比較する
		andlw	h'03'			;ss bit を取り出し
		btfss	STATUS,Z		;ss bit は等しい か？
		goto	clmem04			;No

clmem03		clrf	INDF			;Yes. 消去

		incf	temp_ss,F		;BCD カウンタ +1 更新
		movf	temp_ss,W
		andlw	h'0f'			;下位4ビット
		sublw	h'0a'
		movlw	h'06'
		btfsc	STATUS,Z		;下位4ビット = h'0a' か？
		addwf	temp_ss,F		;Yes. 下位4ビット = 0, 上位4ビット = +1

clmem04		movlw	3
		addwf	FSR,F			;間接アドレス +3 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	clmem01			;No

		return

;--------------------------------------------------------------------------
;		タイマー用メモリの個別消去
;--------------------------------------------------------------------------

delete_memory
		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movf	del_fsr,W		;消去対象のタイマー用メモリのアドレス
		movwf	FSR			;
		clrf	INDF			;タイマー制御バイトを消去
		return

#ifdef comment		; (参考)
delete_memory
		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movlw	low timer_mem		;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1			;ループカウンタ

demem01		movf	INDF,W			;タイマー制御バイト
		subwf	fmmwwwss,W		;
		btfss	STATUS,Z		;(タイマー制御バイト)は等しい か？
		goto	demem02			;No

		incf	FSR,F			;間接アドレス +1 更新
		movf	INDF,W			;時_BCD カウンタ
		andlw	h'7f'			;メモリ自動消去フラグ = 0
		subwf	temp_hh,W		;
		btfss	STATUS,Z		;(時_BCD カウンタバイト)は等しい か？
		goto	demem03			;No

		incf	FSR,F			;間接アドレス +1 更新
		movf	INDF,W			;分_BCD カウンタ
		subwf	temp_mm,W		;
		btfss	STATUS,Z		;(分_BCD カウンタバイト)は等しい か？
		goto	demem04			;No

		decf	FSR,F			;
		decf	FSR,F			;
		clrf	INDF			;タイマー制御バイトを消去
	;	bcf	STATUS,C		;C フラグ = 0、消去済み
		goto	demem05

demem02		incf	FSR,F			;(時_BCD カウンタバイト)

demem03		incf	FSR,F			;(分_BCD カウンタバイト)

demem04		incf	FSR,F			;(次の タイマー制御バイト)
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	demem01			;No

	;	bsf	STATUS,C		;C フラグ = 1、未消去

demem05		return
#endif

;--------------------------------------------------------------------------
;		タイマー用メモリの読み出し
;--------------------------------------------------------------------------

;	  汎用変数:	work1, lp_cnt1

read_memory
		; タイマー用メモリの検索

		movf	dsp_cnt,W		;表示カウンタ
		movwf	work1

		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movlw	low timer_mem		;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1			;ループカウンタ

rdmem01		btfss	INDF,7			;fmmwwwss の f bit = 1 (有効) か？
		goto	rdmem04			;No

		btfss	ext_flg,2		;CH = 3 か？
		goto	rdmem02			;No

		incf	FSR,F			;間接アドレス +1 更新
		movf	INDF,W			;時_BCD カウンタバイト
		decf	FSR,F			;間接アドレス -1 更新, 元に戻す
		andlw	h'80'			;C bit
		btfss	STATUS,Z		;C bit: メモリ自動消去フラグ = 1 か？
		goto	rdmem03			;Yes
		goto	rdmem04			;No

rdmem02		movlw	h'03'
		andwf	ext_flg,W		;ss bit = 01 or 10
		xorwf	INDF,W			;比較する
		andlw	h'03'			;ss bit を取り出し
		btfss	STATUS,Z		;ss bit は等しい か？
		goto	rdmem04			;No

rdmem03		movf	work1,W
		btfsc	STATUS,Z		;表示カウンタ = 0 か？
		goto	rdmem05			;Yes

		decf	work1,F			;表示カウンタ - 1

rdmem04		movlw	3
		addwf	FSR,F			;間接アドレス +3 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	rdmem01			;No

		bsf	dsp_cnt,5		;タイマー用メモリ検索終了フラグ = 1
		goto	rdmem06

		; タイマー用メモリの読み出し

rdmem05		movf	FSR,W
		movwf	del_fsr			;消去対象（となるかもしれない）タイマー用メモリアドレスを記憶
		movf	INDF,W			;
		movwf	fmmwwwss		;タイマー制御バイト

		incf	FSR,F			;間接アドレス +1 更新
		movf	INDF,W			;
		btfsc	ext_flg,2		;CH = 3 か？
		andlw	h'7f'			;Yes. C bit: メモリ自動消去フラグ = 0
		movwf	temp_hh			;時_BCD カウンタ

		incf	FSR,F			;間接アドレス +1 更新
		movf	INDF,W			;
		movwf	temp_mm			;分_BCD カウンタ
		incf	dsp_cnt,F		;表示カウンタの更新

rdmem06		return

;--------------------------------------------------------------------------
;		タイマー用メモリへの書き込み
;--------------------------------------------------------------------------

;	  汎用変数:	lp_cnt1

write_memory
		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movlw	low timer_mem		;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1			;ループカウンタ

wrmem01		btfss	INDF,7			;fmmwwwss の f bit = 1 (有効) か？
		goto	wrmem02			;No. 空き

		movlw	3
		addwf	FSR,F			;間接アドレス +3 更新
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	wrmem01			;No

		bsf	STATUS,C		;C フラグ = 1、メモリオーバーエラー表示
		goto	wrmem03			;ERROR'999999'

wrmem02		bsf	fmmwwwss,7		;f bit = 1 (有効) にする
		movf	fmmwwwss,W
		movwf	INDF			;(タイマー制御バイト) へ書き込み
		incf	FSR,F			;間接アドレス +1 更新

		movf	temp_hh,W
		movwf	INDF			;(時_BCD カウンタバイト) へ書き込み
		incf	FSR,F			;間接アドレス +1 更新

		movf	temp_mm,W
		movwf	INDF			;(分_BCD カウンタバイト) へ書き込み

		bcf	STATUS,C		;C フラグ = 0、書き込み済み

wrmem03		return

;==========================================================================
;		タイマー & 温度の監視とその処理
;==========================================================================

;	  汎用変数:	work1, lp_cnt1

;		tmon_flg: タイマー & 温度監視フラグ、 bit1: 温度,  bit0: タイマー

time_monitor
		movlw	h'03'
		andwf	tmon_flg,W		;
		btfsc	STATUS,Z		;タイマー & 温度監視フラグ = 1 か？
		goto	tmon15			;No

		movf	bcd_ww,W		;曜日 BCD カウンタ
		movwf	tmon_week		;タイマー監視中の曜日カウンタ
		bcf	STATUS,C
		rlf	tmon_week,F		;WEEK カウンタ
		rlf	tmon_week,F		;左に 2 ビットシフト

		bcf	STATUS,IRP		;バンク 0,1（間接アドレス指定用）
		movlw	low timer_mem		;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1			;ループカウンタ

tmon01		btfss	INDF,7			;fmmwwwss の f bit = 1 (メモリ有効) か？
		goto	tmon12			;No

		movf	INDF,W			;(タイマー制御バイト)
		movwf	fmmwwwss		;fmmwwwss に退避
		andlw	h'1c'			;www bit を取り出す
		btfsc	STATUS,Z		;www bit = 0: EDAY か？
		goto	tmon02			;Yes

		xorwf	tmon_week,W
		btfss	STATUS,Z		;WEEK カウンタは等しいか？
		goto	tmon12			;No

tmon02		incf	FSR,F			;間接アドレス +1 更新、(時_BCD カウンタバイト)
		btfss	tmon_flg,1		;温度監視フラグ = 1 か？
		goto	tmon03			;No

		; CH2 検索の場合

		movlw	h'03'
		andwf	fmmwwwss,W		;ss bit を取り出す
		xorlw	h'02'
		btfss	STATUS,Z		;ss bit = 2 か？
		goto	tmon13			;No

		movf	INDF,W
		subwf	buff1,W	    ;temp_mm
		btfss	STATUS,Z		;温度(整数)は等しいか？
		goto	tmon13			;No

		incf	FSR,F			;間接アドレス +1 更新、(分_BCD カウンタバイト)
		movf	INDF,W
		subwf	buff2,W	    ;temp_ss
		andlw	h'f0'			;DS18B20 のとき（上位４ビット（小数一位）のみ有効）
		btfsc	STATUS,Z		;温度(小数)は等しいか？
		goto	tmon04			;Yes
		goto	tmon14			;No

		; CH1,CH3 検索の場合

tmon03		movf	INDF,W
		andlw	h'7f'			;メモリ自動消去フラグを削除
		subwf	bcd_hh,W
		btfss	STATUS,Z		;時_BCD カウンタは等しいか？
		goto	tmon13			;No

		incf	FSR,F			;間接アドレス +1 更新、(分_BCD カウンタバイト)
		movf	INDF,W
		subwf	bcd_mm,W
		btfss	STATUS,Z		;分_BCD カウンタは等しいか？
		goto	tmon14			;No

		; WEEK, 時, 分, または 温度(整数), (小数) が等しいときの出力（リレー）制御

tmon04		movf	PORTA,W			;
		movwf	work1			;変更前の出力ポートのリレー制御データ

		movlw	b'00010000'		;    CH1 = RA4
		btfss	fmmwwwss,0		;CH1 か？
		movlw	b'00100000'		;No. CH2 = RA5

		btfsc	fmmwwwss,5		;mm bit = x1: ON 出力 か？
		iorwf	PORTA,F			;Yes. リレーを ON
		xorlw	h'ff'
		btfss	fmmwwwss,5		;mm bit = x0: OFF 出力 か？
		andwf	PORTA,F			;Yes. リレーを OFF

		; アラームフラグの設定
		btfss	alm_flg,7		;アラーム音出力許可フラグ = 1 か？
		goto	tmon06			;No

		btfsc	tmon_flg,0		;タイマー監視フラグ = 1 か？
		goto	tmon05			;Yes

		movf	work1,W			;変更前のリレー制御データを
		xorwf	PORTA,W			;変更後のリレー制御データと比較
		andlw	h'20'			;CH2
		btfsc	STATUS,Z		;等しい か？
		goto	tmon14			;Yes

tmon05		btfsc	fmmwwwss,5		;mm bit = x1: ON 出力 か？
		bsf	alm_flg,0		;Yes. リレー ON フラグ = 1
		btfss	fmmwwwss,5		;mm bit = x0: OFF 出力 か？
		bsf	alm_flg,1		;Yes. リレー OFF フラグ = 1

tmon06		btfsc	tmon_flg,1		;温度監視フラグ = 1 か？
		goto	tmon14			;Yes

		; メモリの自動消去

		decf	FSR,F			;間接アドレス -1 更新、(時_BCD カウンタバイト)
		btfss	INDF,7			;メモリ自動消去フラグ = 1 か？
		goto	tmon08			;No

		btfss	fmmwwwss,6		;mm bit = 1x: SLP か？
		goto	tmon07			;No

		btfsc	fmmwwwss,5		;mm bit = 10: OFF か？
		goto	tmon09			;No

tmon07		decf	FSR,F			;間接アドレス -1 更新、(タイマー制御バイト)
	;	bcf	INDF,7			;f bit = 0
		clrf	INDF			;メモリの消去
		goto	tmon12			;No

tmon08		btfss	fmmwwwss,6		;mm bit = 1x: SLP か？
		goto	tmon13			;No

		; SLP のときのメモリ内容変更

tmon09		decf	FSR,F			;間接アドレス -1 更新、(タイマー制御バイト)
		movlw	h'20'
		xorwf	INDF,F			;ON/OFF ビットを反転

		incf	FSR,F			;間接アドレス +1 更新、(時_BCD カウンタバイト)
		btfsc	fmmwwwss,5		;変更前の mm bit = 10: OFF 出力 か？
		goto	tmon10			;No. ON 出力

		; ON 出力時間に変更（メモリ自動消去フラグ = 1 のものはない）
		bcf	PCLATH,3		;ページ 0
		call	dec_bcd			;時_BCD カウンタバイト - 1
		bsf	PCLATH,3		;ページ 1

		movlw	h'f9'			;h'00' - h'01' - h'06'
		subwf	INDF,W
		btfss	STATUS,Z		;時_BCD カウンタ = h'f9' か？
		goto	tmon13			;No

		movlw	h'23'
		movwf	INDF			;時_BCD カウンタ = h'23' 設定

		movlw	h'1c'
		andwf	fmmwwwss,F
		btfsc	STATUS,Z		;www bit = 0: EDAY か？
		goto	tmon13			;Yes

		movlw	h'04'
		subwf	fmmwwwss,F		;www bit を - 1
		btfss	STATUS,Z		;www bit = 0 か？
		goto	tmon11			;No

		movlw	h'1c'
		movwf	fmmwwwss		;www bit = 7 にする
		goto	tmon11

		; OFF 出力時間に変更
tmon10		movf	INDF,W
		movwf	work1			;時_BCD カウンタバイトを一旦退避
		bcf	INDF,7			;メモリ自動消去フラグ = 0

		bcf	PCLATH,3		;ページ 0
		call	inc_bcd			;時_BCD カウンタバイト + 1
		bsf	PCLATH,3		;ページ 1

		movlw	h'24'
		subwf	INDF,W
		btfsc	STATUS,C		;時_BCD カウンタ < h'24' か？
		clrf	INDF			;No. 時_BCD カウンタのクリア
		btfsc	work1,7			;メモリ自動消去フラグ = 1 か？
		bsf	INDF,7			;Yes. メモリ自動消去フラグ = 1
		movlw	h'7f'
		andwf	INDF,W
		btfss	STATUS,Z		;時_BCD カウンタ = 0 か？
		goto	tmon13			;No

		movlw	h'1c'
		andwf	fmmwwwss,F
		btfsc	STATUS,Z		;www bit = 0: EDAY か？
		goto	tmon13			;Yes

		movlw	h'04'
		addwf	fmmwwwss,F		;www bit を + 1
		btfss	fmmwwwss,5		;www bit = 8 か？
		goto	tmon11			;No

		movlw	h'04'
		movwf	fmmwwwss		;www bit = 1 にする

		; WEEK を変更
tmon11		decf	FSR,F			;間接アドレス -1 更新、(タイマー制御バイト)
		movlw	h'e3'
		andwf	INDF,F			;www bit をクリア
		movf	fmmwwwss,W		;www bit
		iorwf	INDF,F			;新しい www bit に更新

tmon12		incf	FSR,F			;(時_BCD カウンタバイト)

tmon13		incf	FSR,F			;(分_BCD カウンタバイト)

tmon14		incf	FSR,F			;(次の タイマー制御バイト)
		decfsz	lp_cnt1,F		;ループカウンタ - 1 = 0 か？
		goto	tmon01			;No

		clrf	tmon_flg		;タイマー & 温度監視フラグをクリア

tmon15		return

;==========================================================================
;		EEPROM エリア
;==========================================================================

		org	h'2100'

eep_st		de	"Copyright (C) 2024 by M.Yamamoto"

;==========================================================================

		end				;プログラムの終了