;***** Matrix88LED_ClockII.asm ********************************************
;
;	ドットマトリクス 8 x 8 LED 表示時計 II （ MAX7219 版）
;
;	Copyright (C) 2021-2022   by M.Yamamoto. All rights reserved.
;
;	Homepage URL: http://xyama.sakura.ne.jp/hp/Matrix88LED_ClockII.html
;
;     ( coding:  Ver. 0.00   2021/02/15 by M.Yamamoto )
;	coding:  Ver. 1.00   2021/03/09  初期バージョン
;	update:  Ver. 1.01   2021/03/10  include ファイル名を変更
;	update:  Ver. 1.10   2021/05/16  タイマースイッチ機能等を追加
;	bugfix:  Ver. 1.11   2021/10/07  month_day2 サブルーチンを修正
;	bugfix:  Ver. 1.12   2021/10/08  コロン(:)表示の異常を仮修正
;	update:  Ver. 1.13   2021/12/06  輝度調節機能の追加、その他改善
;	bugfix:  Ver. 1.14   2022/04/30  割り込みルーチンの改善
;
;******************************************************* PicAsm 0255 ******

;	Device: PIC16F690	Clock: 8MHz (Internal OSC)

;==========================================================================

#ifdef comment

 <機能と使用法>

・本機の電源を投入すると、"ピポッ" と開始ブザー音を出力後、ドットマトリクス LED の点灯チェックを兼ねたデモ
　表示が数秒間行われ、続いて 1 秒間の空白をおいた後、0.5秒間ずつ９から０までの数字をカウントダウンしながら、
　ドットマトリクス LED 全６桁分の表示テストを計５秒間行う。

・次に 1 秒間の空白をおいた後、プログラムのバージョン番号がマトリクス LED に約３秒間表示される。

	バージョン番号			[ Ver. x.xx ]

・その後１秒間の空白をおいた後、RTC（リアルタイムクロック）モジュールの状態がチェックされ、初めて電源を入れ
　たときや、バックアップ用バッテリーが異常なとき等に、次のエラーメッセージがマトリクス LED に表示されるとと
　もに、"ブッブー" ブザー音が出力される。

	エラーメッセージ		[ Err. DS3231 ]

・ユーザはバックアップ用バッテリーの状態等を確認してその対処を行った後、SIGNAL スイッチを除いた４つのスイッ
　チの内のどれかを押して応答をする。

・すると、RTC（リアルタイムクロック）モジュールが初期設定され、エラーフラグがクリアされるとともに、年月日、
　時分秒が本機をプログラミングしたときの初期値、"2021/01/01"、"00：00：00" に設定がされて時計機能が開始され
　る。この状態を NORMAL モード という。 しかし、これらは現在値とは異なるため、スイッチ操作による手順で現在
　の年月日、時分秒に設定をし直す必要がある。

	時間表示			[ xx:xx:xx ]

・その手順の説明の前に、本機における表示モードを先に説明をしておく。（このときのモードの意味は上述の NORMAL 
　モードと対比するものではなく、単に表示する内容の種類を表している）。本機には上述の時間表示の他に、年月日
　(曜日)表示、温度表示、湿度表示の機能を持っている。

	モード 0          	モード 1          	　モード 2          	　 モード 3 
	時間表示　[ xx:xx:xx ]	年月日表示　[ xx.xx.xx ]　温度表示　[ _- xx.x℃ ]　湿度表示　[ _x xx.x％ ]	

・なお、上述のモード 0 ～ モード 3 の他にモード 4 もあって、これらは MODE / SET スイッチ を押すごとにモード
　番号が増加をし、マトリクス LED に表示される内容が切り替わる。そして モード 4 の次は再び モード 0 に戻る。 

	┌→ 時間表示 → 年月日表示 → 温度表示 → 湿度表示 → オートモード ─┐
	│　(モード 0)　 (モード 1)　 (モード 2)　(モード 3)　　(モード 4)　　│
	│　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　│
	└──────────────────────────────────┘

・オートモード(モード 4) を選択したときには、モード 0 ～ モード 3 の個々の内容表示を、次図に示すように自動的
　に 10 秒ごとに内容を切り替えて、１分ごとにすべての表示を繰り返す。 

      		毎 05 ～ 14 秒の間：	年月日表示
      		毎 25 ～ 34 秒の間：	温度表示
      		毎 45 ～ 54 秒の間：	湿度表示
		上記以外の間：		時間表示

		 (___: 時間表示、NNN: 年月日表示、OOO: 温度表示、SSS: 湿度表示)

		00        10        20        30        40        50        00
		.    .    .    .    .    .    .    .    .    .    .    .    .
		_____NNNNNNNNNN__________OOOOOOOOOO__________SSSSSSSSSS_____

・このとき、MODE スイッチを何度も続けて押していると、現在のモードが何なのか分かり辛くなるときがあるため、マ
　トリクス LED の１桁目（最左端桁）でそのときのモード種類を表示する。

・すなわち、MODE スイッチを押した直後に、１桁目の横１列の８個の LED が次のように数秒間だけ表示される。その後
　１桁目の LED は通常の表示に戻る。（例ではオートモード(モード 4) を表す。 ●は点灯、○は消灯）

	（例）	○○○○○○○○
		○○○○○○○○
		○○○○○○○○
		●●●●●●●●　←　オートモード
		○○○○○○○○　←　湿度表示
		○○○○○○○○　←　温度表示
		○○○○○○○○　←　年月日表示
		○○○○○○○○　←　時間表示

・また、年月日表示(モード 1) を選択したときには、年月日の表示とそのときの曜日の表示が、１秒ごとに切り替わっ
　てマトリクス LED に交互に表示がされる。 

	年月日表示　[ xx.xx.xx ]		曜日表示　[ _( xxx )_ ]

・本機では１２／２４時間の両表示機能を持ち、通常の NORMAL モード中であれば UP スイッチ によっていつでも切り
　替えることができる。すなわち、時間表示(モード 0) 中だけでなく、年月日表示(モード 1) ～ オートモード(モード 
　4) 中であっても切り替えられる。ただし、時間表示(モード 0) でなければ切り替わったことを目で確認することはで
　きない。

・そして、１２時間表示の場合には、左列の :（コロン）の上側 LEDで AM を、また下側 LEDで PM を、１秒間隔で点滅
　を繰り返すことで、それぞれを表現する。

					　　┌─ AM
					　　↓
	１２時間表示の場合		ｘｘ：ｘｘ：ｘｘ
					　　↑
					　　└─ PM

・次に、１２時間表示と２４時間表示の対応を示す。なお、１２時間表示の場合だけ 先頭の１桁目（左端）は、ゼロサ
　プレスを行なって表示をする。

	(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

・さて、ここで話を戻して、年月日、時分秒の設定を変更する手順としては、現在、時間表示(モード 0) ～ オートモー
　ド(モード 4) のどの内容が表示されている場合においても可能で、まず、表示内容（モード）を切り替えるときのよ
　うに "チョン押し" ではなく、同じ MODE / SET スイッチ を "長押し" することによって、年月日、時分秒を自由に
　変更することができる、SET モード に移行をする。 

・すなわち、MODE / SET スイッチ を３秒以上 "長押し" をしていると、マトリクス LED に次のメッセージが表示され
　て、NORMAL モードから SET モード に移行をしたことを知らせる。

	SET モード に移行		[ ** SET ** ]

・ユーザはそれを確認してスイッチから指を離すと、次には必ず年月日の表示パタンで "年" だけが表示される。この表
　示されている部分がこれから変更することが可能な対象項目であることを表している。

	年月日表示（"年" だけ表示）	[ xx.__.__ ]

・ここで変更が必要であれば、UP スイッチ を押すごとに現在値より１づつ増加し、また DOWN スイッチ を押すごとに
　１づつ減少するので、適宜希望する値に変更をする。また、このときの増減幅を大きくしたい場合には、 UP スイッチ、
　または DOWN スイッチを押したままにしていると、１秒当たり 4 ～ 5 の増減幅で更新をするようになる。

・"年" の変更が済んだら、再び MODE / SET スイッチ を押すと、次には年月日の表示パタンで "月" だけが表示され、
　変更の対象項目が次に移動されたことを示す。同様に変更が必要であれば、 UP スイッチ、または DOWN スイッチを押
　すことによって、適宜希望する値に変更をする。 

	年月日表示（"月" だけ表示）	[ __.xx.__ ]

・同様に、SET スイッチ を押すごとに "年"、"月"、"日"、"時"、"分"、"秒" と変更の対象項目が移動するので、該当
　の項目を選択後 UP または DOWN スイッチ によって値を変更設定する。最後の "秒" 設定後にもう一度 SET スイッチ
　を押すと、SET モードから抜け出て再び NORMAL モード に移行をし、必ず時間表示(モード 0) に戻る。

・この SET スイッチによって対象項目を選択中に、誤って希望する項目を通り過ぎてしまったような場合に、BACK スイ
　ッチ を押すごとに、ひとつずつ前の項目に戻ることができる。ZERO / BACK スイッチは、"年"、"月"、"日"、"時"、
　"分"、"秒" の設定中にはこのような機能を有する。 

	　　　　　　　　　　　　　　 BACK  　BACK  　BACK  　BACK  　BACK
	　　　　　　　　　　　　　　 ←─ 　 ←─ 　 ←─ 　 ←─ 　 ←─
	　　　　　　　　　　 SET  　 SET  　 SET  　 SET  　 SET  　 SET  　 SET
	５つのどれかのモード ─→ 年 ─→ 月 ─→ 日 ─→ 時 ─→ 分 ─→ 秒 ─→ 時間表示モード(モード 0) 
	　　　　　　　　　　　　　│　　　　　　　　　　　　　　　　　　　↑
	　　　　　　　　　　　BACK└───────────────────┘

・このように、各対象項目が選択されたときの表示パタンをまとめると、次のように表示される。

　　　（xx　選択項目、　__　消灯桁）

	xx.__.__　　年が選択,		__.xx.__　　月が選択,		__.__.xx　　日が選択
	xx:__:__　　時が選択,		__:xx:__　　分が選択,		__:__:xx　　秒が選択

・なお、NORMAL モードのときに１２時間表示に設定がされている場合には、SET モードに移行後もその表示が反映され
　るため、SET スイッチによって項目の "時"、"分"、"秒" を選択時には、左列の :（コロン）の上側 LED点灯 + 下側 
　LED消灯で AM を、上側 LED消灯 + 下側 LED点灯で PM を、それぞれ表現をする。また、この場合には先頭の１桁目
　（左端）のゼロサプレスも行われる。

・ZERO／DOWN スイッチは、SET モード中で "年"、"月"、"日"、"時"、"分"、"秒" の設定のときには、上述のように 
　DOWN スイッチとして機能をするが、それ以外の NORMAL モード中には、毎正時プラス・マイナス５分以内に押される
　と 00分00秒に設定するための ZERO スイッチ として機能をする。

・年月日カレンダー機能について、うるう年の計算は 2001年～2399年までの範囲で対応をしている。ただし、年の表示
　は下２桁のみになる。

・SIGNAL スイッチ は、毎時の時報音出力のブザー音を、押すごとに有効／無効に交互に設定をする。このときの設定状
　態は視覚的な表示がないため、有効になったときには "ピピピッ" 音を、無効になったときには "ブー" 音を、それぞ
　れ鳴らして知らせる。なお、電源を投入した直後は有効状態に設定がされている。また、有効に設定時には、時間表示
　(モード 0) 以外のモードにおいても、毎時の時報音は有効（鳴る）なので注意が必要である。

・本機では年月日(曜日)、時分秒の他に、温度湿度を表示するモードがあることは上述の通りであるが、年月日(曜日)、
　時分秒の情報は、上述した RTC（リアルタイムクロック）モジュール（ DS3231 ）と PIC とを、I2C シリアル通信に
　よって情報を得ているのに対して、温度湿度情報は、デジタル温度湿度センサーモジュール（ DHT22（AM2302））と 
　PIC との間を、たった１本だけのデータ線によるシリアル通信によって情報を得ている。

・そして、前者の場合には１秒間隔で通信を行うが、後者の場合には本機では４秒間隔（仕様により２秒以上の間隔が必
　要）で通信を行っている。また、後者のデジタル温度湿度センサーモジュール（ DHT22（AM2302））との通信において
　は、通信中にエラーが起こった場合には、次のようなエラーメッセージがマトリクス LED に表示されるとともに、"ブ
　ッブー" ブザー音が出力される。

	タイムアウトエラー		チェックサム(CRC)エラー
	[ Err. DHT22 TO ]		[ Err. DHT22 PE ]

・左の例では通信中にタイムアウトエラーが起こった場合で、データ線上の "high" または "low" 電圧の続く時間が、
　仕様で決められた時間をオーバーした場合に発生をする。また、右の例ではチェックサム(CRC)エラーが起こった場合
　で、DHT22（AM2302）からは１度の通信で、湿度情報が 16 ビット、温度情報が 16 ビット、チェックサムが 8 ビット
　の、計 40 ビットが送られてくるが、それらの情報でパリティチェックを行った結果、エラーが起こった場合に発生を
　する。

・（補足）本機に電源を入れてから１度目の温度湿度センサーモジュール（ DHT22（AM2302））との通信には、どういう
　訳か？時々チェックサム(CRC)エラーが起きるようである。しかし、その４秒後以降には正常な通信が行われて、エラ
　ーメッセージは消滅してしまうので、あまり問題はないものと思う。 

	　　　― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ―
 <機能追加>		; (Ver.1.10) で追加

・あらかじめ設定をしておいた時間（時分）になると、スイッチ（リレー）が ON/OFF/SLP 動作をするタイマースイッチ
　機能、また、温度の設定をしておくとその設定温度に達したときに、同様にスイッチ（リレー）が ON/OFF 動作をする 
　温度スイッチ機能の２つを、新しい機能として本機に追加をした。

・前者のタイマースイッチには CH 1 と CH 2 の２系統を用意し、後者の温度スイッチには CH 3 の１系統を用意してい
　る。そして、これらの時間（時分）や温度の設定情報を記憶しておくためのメモリは、本機では３系統分を共通で使用
　をし、合計 20 メモリまでを可能とする。

・また、これらのタイマースイッチ機能、温度スイッチ機能のユーザー・インターフェースとしての操作には、あらかじ
　めそれらの情報をメモリに設定をしておくためのメモリ設定機能、メモリに設定されている情報をいつでも読み出して
　確認ができるメモリ読み出し機能、不要になったメモリ情報を消去するためのメモリ消去機能がある。

・これらの操作には、新たに設けた４つのスイッチと、従来からある SIGNAL スイッチを除いた４つのスイッチとの組み
　合わせで行う。

・まず、メモリ設定機能の操作は、本機が NORMAL モードのときに、EXP スイッチを押しながら CH 1 ～ CH 3 スイッチ
　のどれかを押すことによって始める。CH 1 ～ CH 3 スイッチは上記のように、どの系統にスイッチ機能を設定するか
　を選択するものである。

・すると、選択をした CH x スイッチによって、マトリクス LED には次の２種類の内のどちらかが表示される。すなわ
　ち、CH 1、CH 2 スイッチの場合には左側の、CH 3 スイッチの場合には右側の形式で表示がされ、なおかつ先頭の２桁
　が点滅表示をしてこれから設定をする対象位置（~~）を表している。

	時分設定表示　[ 00:00 00 ]		温度設定表示　[ 00.0℃ 00 ]
	　　　　　　　  ~~        		　　　　　　　  ~~
・CH 1、CH 2 スイッチの場合には、設定をする "時"、"分" の内の "時" の位２桁であり、CH 3 スイッチの場合には、
　設定をする温度値の整数部２桁が設定の対象となる。なお、すべての設定項目の初期値は "00"、または "0" が表示さ
　れる。

・それぞれの値を設定するには、UP スイッチ を押すごとに現在値より１ずつ増加し、また DOWN スイッチを押すごとに
　１ずつ減少するので、適宜希望値に設定をする。また、このときの増減幅を大きくしたい場合には、UP スイッチ、ま
　たは DOWN スイッチを押したままにしていると、１秒当たり 4 ～ 5 の増減幅で更新をするようになる。

・"時" または、温度値の整数部の設定が済んだら、MODE / SET スイッチを押すと、次には "分" の位２桁 または、温
　度値の小数部１桁 が点滅表示され、設定の対象項目が次に移動したことを示す。同様に、UP スイッチ、または DOWN 
　スイッチを押すことによって、適宜希望値に設定をする。

	時分設定表示　[ xx:00 00 ]		温度設定表示　[ xx.0℃ 00 ]
	　　　　　　　     ~~        		　　　　　　　     ~
・なお、上述までで設定値の範囲は、"時" は "00" ～ "23"、"分" は "00" ～ "59"、温度値の整数部は "00" ～ "99"、
　小数部は "0" ～ "9" であり、それ以外の値を設定することはできない （プログラムが制限をかけている）。このよ
　うに、"時" の設定には常に 24 時間表示で行うこと。

・"分" または、温度値の小数部の設定が済んだら、再度 MODE / SET スイッチを押すことによって、点滅表示が次の設
　定の対象項目 "曜日" １桁 に移動をする。

	時分設定表示　[ xx:xx 00 ]		温度設定表示　[ xx.x℃ 00 ]
	　　　　　　　        ~        		　　　　　　　         ~
・"曜日" の設定方法は CH 1 ～ CH 3 すべて共通で、UP スイッチ、または DOWN スイッチによって、次の対応表のよう
　に数値によって指定をする。なお、このように温度スイッチの設定にも "曜日" の条件を加えてある。

	┌───┬──┬──┬──┬──┬──┬──┬──┬──┐
	│ 曜日 │毎日│ 日 │ 月 │ 火 │ 水 │ 木 │ 金 │ 土 │
	├───┼──┼──┼──┼──┼──┼──┼──┼──┤
	│設定値│  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │
	└───┴──┴──┴──┴──┴──┴──┴──┴──┘

・同様に、再々度 MODE / SET スイッチを押すと、４つ目（最後）の設定項目の右端１桁に点滅表示が移動をする。CH 1 
　～ CH 3 の各リレーの動作種類をどのように制御するかを設定するもので、UP スイッチ、または DOWN スイッチによ
　って、次の対応表のように数値によって指定をする。

	時分設定表示　[ xx:xx x0 ]		温度設定表示　[ xx.x℃ x0 ]
	　　　　　　　         ~        	　　　　　　　          ~
	┌────┬────────┬─────┐
	│　　　　│   CH 1、CH 2   │   CH 3   │
	├────┼──┬──┬──┼──┬──┤
	│動作種類│ OFF│ ON │ SLP│ OFF│ ON │
	├────┼──┼──┼──┼──┼──┤
	│ 設定値 │  0 │  1 │  3 │  0 │  1 │
	└────┴──┴──┴──┴──┴──┘

・上表のように、CH 3 の温度スイッチにはスリープ（SLP）動作を設定することはできない。また、CH 1、CH 2 のタイ
　マースイッチにおいて設定値 "2" は、プログラムの内部で使用するものでユーザが設定することはできない（ON 動作
　をしたリレーが１時間後に OFF 動作をさせるときの情報に使用）。

・また、UP スイッチ、または DOWN スイッチによって、上表２つのそれぞれの設定値以外を指定しようとしても、プロ
　グラムがそれぞれで制限をかけているので不可能である。

・なお、これまでの MODE / SET スイッチによって対象項目を選択中に、誤って希望する項目を通り過ぎてしまったよう
　な場合には、BACK スイッチを押すごとに、ひとつずつ前の項目に戻ることができる。また、これらの項目を設定途中
　に何らかの理由によって中止をしたいような場合には、EXP スイッチを押すとそれまでに設定をしてきた項目が破棄さ
　れ、メモリ設定機能を終了して、NORMAL モードに戻る。

・最後のリレーの動作種類を設定後、すなわち、右端１桁が点滅表示をしているときに、もう一度 MODE / SET スイッチ 
　を押すと、今まで入力をしてきたタイマースイッチ、または温度スイッチの設定情報を記憶するために、プログラムは 
　PIC 内部の RAM メモリに書き込み動作を行う。

・タイマースイッチ、または温度スイッチの設定情報が正常に書き込まれると、"ピピッ" ブザー音を鳴らしてユーザに
　それを知らせ、再び新たなメモリ設定のために、すべての設定項目を初期値の "00"、または "0" に戻して、先頭の２
　桁が点滅表示をするので、続けて次の設定情報の入力を行うことができる。

・ただし、この場合には CH x は前回のものが引き継がれるので、もしも他の CH x に変更をしたい場合には EXP スイ
　ッチ だけを押して、一旦、それまでの CH x でのメモリ設定機能を終了させて NORMAL モードに戻し、新たに EXP ス
　イッチ を押しながら CH 1 ～ CH 3 スイッチのどれかを押して、CH x の選択をし直す必要がある。

・また、プログラムが PIC 内部の RAM メモリに書き込み動作を行うときに、既に 20 メモリまでが書き込まれて満タン
　状態の場合には、次のエラーメッセージがマトリクス LED に表示されるとともに、"ブッブー" ブザー音が出力される。

	エラーメッセージ		[ Err. MEM    ]

・このエラーメッセージが表示された場合には、いつまでもその表示状態が続くので EXP スイッチを押してメモリ設定
　機能を終了させると、NORMAL モードに戻る。

・次に、メモリ読み出し機能の操作は、本機が NORMAL モードのときに、CH 1 ～ CH 3 スイッチのどれかを押すことに
　よって始める。本機では、CH x 別にメモリ読み出しを行うようにプログラミングがされているため、メモリ内容の確
　認を希望する CH x スイッチを押す。

・すると、押した CH x スイッチによって、マトリクス LED には次の２種類の内のどちらかが表示される。メモリ設定
　機能のときと同様に、CH 1、CH 2 スイッチの場合には左側の、CH 3 スイッチの場合には右側の形式で表示がされる。
　ただし、メモリ設定ではないため点滅表示が行われることはない。

	時分設定表示　[ xx:xx xx ]		温度設定表示　[ xx.x℃ xx ]

・CH x スイッチを押すと、20 メモリの内の先頭から検索を行い、まず、最初に見つかったメモリ内容が上記の形式で表
　示がされる。その後、続けて CH x スイッチを押すごとに、２番目に見つかったメモリ内容、３番目に見つかったメモ
　リ内容、・・・ の順にマトリクス LED に表示がされる。

・やがて最終の 20 メモリを過ぎると、一旦、次のように空白表示を行い、なおも CH x スイッチが押されると、また先
　頭からの検索に戻って以上の表示が繰り返される。

	時分設定表示　[ __:__ __ ]		温度設定表示　[ __.__ __ ]

・このメモリ読み出し機能では、現在検索中の CH x（例えば CH 1）スイッチのときに、異なった CH x（例えば CH 3）
　スイッチを押した場合には、検索対象が（CH 3 に）変更されて、新たに 20 メモリの内の先頭から検索がされるよう
　になる。

・このようにメモリ内容の確認中に、現在、マトリクス LED に表示がされている内容が不要となった場合には、そのと
　きに DOWN スイッチ を押すことによって、20 メモリの内のその情報だけを個別に消去することができる。

・メモリ内容が消去されると、次のメッセージが約 3 秒間マトリクス LED に表示されるとともに、"ピピッ" ブザー音
　が出力される。なお、上述のように最終の 20 メモリを過ぎて空白表示がされているときに DOWN スイッチ を押すと、
　右のメッセージが約 3 秒間表示されるとともに、"ブー" ブザー音が出力される。

	CLR メッセージ	[    CLR    ]		NOT メッセージ	[    NOT    ]

・上記の操作で現在表示中の情報が消去されると、消去をした次の順にメモリに記憶がされている同じ CH x の内容が読
　み出されて、新たにマトリクス LED に表示がされる。

・このようにメモリ読み出し機能では、後からの DOWN スイッチの併用によって個別のメモリ消去機能も有している。

・また、このメモリ読み出し機能を終了させるためには、前のメモリ設定機能と同様に EXP スイッチを押すことによっ
　て、再び NORMAL モードに戻る。

・上記の例では、個別に１件ずつメモリ内容を確認しながら消去をする方法であるが、これとは別に CH 別に一気に消去
　をしてしまう方法もある。

・本機が NORMAL モードのときに、DOWN スイッチを押しながら CH 1 ～ CH 3 スイッチのどれかを押すと、その指定さ
　れた CH x の内容のすべてが一気に消去され、次のメッセージが約 3 秒間マトリクス LED に表示されるとともに、
　"ピピッ" ブザー音が出力される。なお、このとき指定された該当の CH x のメモリ内容が１つもなかった場合には、
　右のメッセージが約 3 秒間表示されるとともに、"ブー" ブザー音が出力される。

	CLR メッセージ	[ CHx CLR    ]		NOT メッセージ	[ CHx NOT    ]

・そして、メモリ設定機能やメモリ読み出し機能とは異なって、メッセージの表示時間約 3 秒が過ぎると、再び NORMAL 
　モードに戻る（EXP スイッチの操作は不要）。

・上述のメモリ設定機能で一旦メモリに記憶設定された情報は、本機の電源が断になって消滅をした場合や、ユーザがメ
　モリ消去機能で故意に消去をしない限り、いつまでもメモリ内に存在し続けて、タイマースイッチや温度スイッチのプ
　ログラムでの監視対象となる。

・タイマースイッチの情報としては、"時"、"分"、"曜日"、リレーの動作種類、CH 番号がメモリに記憶されているため、
　本機の時計機能が毎分 "00" 秒になると、該当の情報がメモリ内に設定されていないかどうかを、監視プログラムが検
　索をする。

・また、温度スイッチ の情報としては、温度値の整数部、小数部、"曜日"、リレーの動作種類、CH 番号がメモリに記憶
　されていて、本機では 4 秒ごとに温度情報をセンサから読み出して更新をするため、その都度監視プログラムが同様
　に検索をする。ただし、この温度スイッチの場合には、現在、設定情報がメモリ内に存在しているかどうかだけを常に
　プログラムが把握をしていて、存在している場合に限ってメモリ検索を行う。

・このようにメモリ検索をした結果、該当の設定情報がメモリ内に存在した場合には、それぞれの CH 番号のスイッチ（
　リレー）が、指定をされた動作種類（ ON/OFF/SLP ）に応じた動作をするとともに、SIGNAL スイッチ によってアラー
　ム音の出力が有効に設定されている場合には、スイッチが ON 動作のときには "ピポッピポッ" ブザー音を、また OFF 
　動作のときには "ブーー" ブザー音を併せて出力をする。

・なお、以上述べてきたメモリ設定、メモリ読み出し、メモリ消去、それぞれの操作時に伴う "ピピッ" ブザー音、"ブッ
　ブー" ブザー音、"ブー" ブザー音は、SIGNAL スイッチ によるアラーム音の有効／無効にかかわらず出力されるので、
　注意が必要である。


 <機能追加 2>		; (Ver.1.13) で追加

・改めて言うまでもなく本機には、8 x 8 ドットマトリクス LED が６個使用されているが、それらの LED の輝度につい
　て従来は、プログラミング時の一定値に固定がされていて、変更することはできなかった。それを簡単なスイッチ操作
　によって自由に調節ができるように、機能追加を行った。

・本機が NORMAL モードのときに、毎正時プラス・マイナス５分以内に ZERO／BACK スイッチが押されると、00分 00秒
　に設定するための ZERO スイッチ機能が優先するが、それ以外の、毎正時プラス・マイナス５分以外に、ZERO／BACK 
　スイッチを押しながら UP スイッチ、または DOWN スイッチを押すことによって、ＬＥＤの 輝度調節として機能 をす
　るようになる。

・まず、このように毎正時プラス・マイナス５分以外のときに、ZERO／BACK スイッチ を１秒間以上押している と、次
　のように、現在の輝度レベルの設定値がマトリクス LED に表示される。

		輝度レベルの表示例	[ Bri. Lev = 0 ]  ...  Brightness

・そして次に、ZERO／BACK スイッチを押したままで UP スイッチ、または DOWN スイッチを押すと、輝度レベルの設定
　値が更新されるとともに、マトリクス LED の表示も更新される。

・本機では、輝度調節のレベルを 0 から 9 までの 10 段階 * を、変更設定することができる。すなわち、ZERO／BACK 
　スイッチを押しながら、UP スイッチを押すごとに現在値より１ずつ増加し、また DOWN スイッチを押すごとに１ずつ
　減少する。ただし、このときにそれぞれの限度値になってから尚も、UP スイッチ、または DOWN スイッチを押しても、
　それぞれの限度値を超えることはない。（デフォルト値 = 0）

	* 本機で使用したＩＣ MAX7219 では 16 段階で変更することが可能であるが、ＬＥＤの安全性を考慮して上限
	　を 9 までに制限をした。

・ただし、このように輝度調節ができるのは６個の 8 x 8 ドットマトリクス LED だけで、時と分、分と秒、それぞれの
　間のコロン(：)、またはピリオド(．)用の４つの LED については対象外で、輝度調節をすることはできない。

#endif

;==========================================================================

;	PIC16F690 のピンと用途

;	  (1) VDD: 電源 +5V DC			(20) VSS: 電源 GND
;	  (2) RA5: SW4(ZERO/BACK) スイッチ入力	(19) RA0: SW1(MODE/SET) スイッチ入力
;	  (3) RA4: SW3(DOWN) スイッチ入力　	(18) RA1: SW2(UP) スイッチ入力
;	  (4) RA3: 予備				(17) RA2: INT外部割り込み入力
;	  (5) RC5: コロン LED RU 出力		(16) RC0: MAX7219 DIN 出力
;	  (6) RC4: コロン LED RL 出力		(15) RC1: MAX7219 LOAD 出力
;	  (7) RC3: SW5(SIGNAL) スイッチ入力	(14) RC2: MAX7219 CLK 出力
;	  (8) RC6: コロン LED LL 出力		(13) RB4: DS3231 SDA 入出力
;	  (9) RC7: コロン LED LU 出力		(12) RB5: DHT22 DATA
;	 (10) RB7: Bz 出力			(11) RB6: DS3231 SCL 出力

;==========================================================================

	list		p=pic16f690		;デバイス情報
	include		p16f690.inc		;インクルードファイル
	errorlevel	-302			;Eliminate bank warning
	errorlevel	-306			;Eliminate page warning

;==========================================================================
;		コンフィギュレーションの設定
;==========================================================================
 
	__config 	_CP_OFF & _CPD_OFF & _BOREN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

;==========================================================================
;		定数の定義と変数のレジスタ割付け
;==========================================================================

		radix	dec

ver_no		equ	h'114'		;バージョン番号: 1.14

tm0_h_val	equ	256 - 250	;ハードタイマー０カウント値（割り込み周期）(4/8Mz*16*250=2msec)
tm0_s_val	equ	100		;ソフトタイマー０カウント値                (2msec*100=200msec)

_swMOD		equ	0		;MODE スイッチ		;┐
_swSET		equ	0		;SET  スイッチ		;│
_swUP		equ	1		;UP   スイッチ		;│PORTA
_swDWN		equ	4		;DOWN スイッチ		;│
_swZER		equ	5		;ZERO スイッチ		;│
_swBAK		equ	5		;BACK スイッチ		;┘

DHT		equ	5		;DHT22 DATAポート	;┐
SCL		equ	6		;I2C SCL		;│PORTB
SDA		equ	4		;I2C SDA		;│
_BZ		equ	7		;アラーム音 出力	;┘

maxDIN		equ	0		;MAX7219 DIN 制御	;┐
maxLOAD		equ	1		;MAX7219 LOAD 制御	;│PORTC
maxCLK		equ	2		;MAX7219 CLK 制御	;│
_swSIG		equ	3		;SIGNAL スイッチ	;┘

_swEXP		equ	0		;EXP スイッチ		;┐
_swCH1		equ	1		;CH1 スイッチ		;│拡張ポート
_swCH2		equ	2		;CH2 スイッチ		;│
_swCH3		equ	3		;CH3 スイッチ		;┘

f_rah		equ	65536 - 1136	;ラ (880.00 Hz)  at 8MHz
f_doh		equ	65536 - 1911	;ド (523.26 Hz)
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		;音長

		cblock  h'20'		; (( バンク 0 ))
int_flg					;外部(RA2/INT)割り込みフラグ
					;bit0: RTC DS3231 からデータ読み出し要求フラグ
					;bit1: DHT22 からデータ読み出し要求フラグ, （取消変更）*
					;bit1-2: 4 秒カウンタ,                     （変更）*
					;bit3: DHT22 からデータ読み出し要求フラグ, （変更）*
bcd_yh					;年(上位2桁) BCD カウンタ
bcd_yl					;年(下位2桁) BCD カウンタ
;bcd_yy					;年 BCD カウンタ
bcd_nn					;月 BCD カウンタ
bcd_dd					;日 BCD カウンタ
bcd_hh					;時 BCD カウンタ
bcd_mm					;分 BCD カウンタ
bcd_ss					;秒 BCD カウンタ
bcd_ww					;曜日 BCD カウンタ
temp_hh					;仮の時 BCD カウンタ
temp_mm					;仮の分 BCD カウンタ
temp_ss					;仮の秒 BCD カウンタ
time_flg				;時間表示モードフラグ  bit1=0:24H/1:12H, bit0=0:am/1:pm
mod_flg					;表示モードフラグ, 0:時間, 1:年月日, 2:気温, 3:湿度, 4:オート, (5:SET)
mod_cnt					;モードNo表示時間カウンタ
tg_point				;対象の位置ポインタ
chg_flg					;データ変更フラグ, bit0:対象の位置の変更, :bit1:対象の位置のデータ変更
alm_flg					;アラーム音出力フラグ, bit7:出力許可
					; bit0:リレー ON 音, :bit1:リレー OFF 音, bit2:時報予報音, :bit3:時報正報音
uru_flg					;0:平年 / 1:閏年
cur_yh					;年(上位2桁)(変) BCD カウンタ
cur_yl					;年(下位2桁)(変) BCD カウンタ
cur_nn					;月(変) BCD カウンタ
cur_week				;週位置カウンタ（曜日 1～7）
xxx_yh					;ワーク

wk_order				;ワーク
work1					;ワーク
work2					;ワーク
work3					;ワーク
lp_cnt1					;汎用ループカウンタ
lp_cnt2					;汎用ループカウンタ
buff0		;(00)			;汎用バッファエリア
buff1		;(01)			;
buff2		;(02)			;
buff3		;(03)			;
buff4		;(04)			;
data_h					;変換する上位バイト
data_l					;変換する下位バイト

const_high				;音階用分周定数 high の保存
const_low				;音階用分周定数 low の保存
wt1cnt					;ウェイト用ループカウンタ
wt2cnt					;ウェイト用ループカウンタ
wt3cnt					;ウェイト用ループカウンタ

reg_addr				;MAX7219 のレジスタアドレス
reg_data				;レジスタへの書き込みデータ
maxtmp					;送信データの一時保存
mbit_cnt				;ループカウンタ
mlpcnt1					;ループカウンタ
mlpcnt2					;ループカウンタ
mlpcnt3					;ループカウンタ
nop_cnt					;該当の桁より左側の桁数
segment					;Segment データ変数
digit					;Digit データ変数
addr_high				;文字フォントデータの high アドレス
addr_low				;文字フォントデータの low アドレス
dspdigit				;表示桁指定フラグ
fsr_mem					;フォントデータバッファのアドレス記憶
tbl_type				;フォントデータテーブルの種類 (0/1/2/3)
intensity				;bit7: 輝度更新フラグ, 			; (Ver.1.13) で追加
					;bit3-0: 輝度調節値			;
;
tm0_s_cnt				;ソフトタイマー０カウンタ
exp_flg					;拡張機能フラグ
					; bit7: メモリの内容表示フラグ, bit6: 反転表示フラグ, 
					; bit2: CH3 フラグ, bit1-0: CH 番号、01:CH1, 10:CH2, 11:CH3
ch3_cnt					;CH3 メモリカウンタ
dsp_cnt					;タイマー用メモリの表示カウンタ
fmmwwwss				;タイマー制御バイト
tmon_flg				;タイマー & 温度監視フラグ,  bit1: 温度,  bit0: タイマー
exp_port				;拡張ポートのリレー制御データ
del_fsr					;消去対象のタイマー用メモリのアドレス記憶

;（PCF8574/74A で使用）
exptmp					;書き込み／読み出しデータ

; (DHT22.sub で使用)
humidity_h				;湿度上位 8 bit
humidity_l				;湿度下位 8 bit
temperature_h				;温度上位 8 bit
temperature_l				;温度下位 8 bit
time_cnt				;bit0-5: 時間計測カウンタ, 
					;bit6: チェックサム(CRC)エラー, bit7: タイムアウトエラー

; (I2C_RTC.sub で使用)
rtc_lpcnt				;ループカウンタ
rtc_addr_high				;読み出すデータの high アドレス
rtc_addr_low				;読み出すデータの low アドレス

; (I2C_XS_100K.sub で使用)
i2ctmp					;送受信データの一時保存
bit_cnt					;ループカウンタ
		endc

		cblock	h'80' - 4
w_save					;W レジスタの退避用
s_save					;STATUS レジスタの退避用
f_save					;FSR レジスタの退避用
p_save					;PCLATH レジスタの退避用
		endc

		cblock  h'a0'		; (( バンク 1 ))
; (I2C_RTC.sub で使用)
seconds					;00h: Seconds: 00-59
minutes					;01h: Minutes: 00-59
hours					;02h: Hours:   1-12 + AM/PM, 00-23
day					;03h: Day:     1-7
date					;04h: Date:    01-31
month					;05h: Month/Century: 01-12 + Century
year					;06h: Year:    00-99
alarm1s					;07h: Alarm 1 Seconds: 00-59
alarm1m					;08h: Alarm 1 Minutes: 00-59
alarm1h					;09h: Alarm 1 Hours:   1-12 + AM/PM, 00-23
alarm1dy				;0Ah: Alarm 1 Day:     1-7
alarm1d					;0Bh: Alarm 1 Date:    1-31
alarm2h					;0Ch: Alarm 2 Hours:   1-12 + AM/PM, 00-23
alarm2d					;0Dh: Alarm 2 Day:     1-7, Alarm 2 Date:    1-31
control					;0Eh: Control
cont_stat				;0Fh: Control/Status
aging					;10h: Aging Offset
temp_m					;11h: MSB of Temp
temp_l					;12h: LSB of Temp

; (フォントデータのバッファエリア)
fd_buff					;バッファエリアの先頭
;	     (8 *  6 = 48 byte 使用)
		endc

		cblock  h'120'		; (( バンク 2 ))
; (タイマー用メモリエリア)
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

;==========================================================================
;		プログラム開始
;==========================================================================

		org	h'0000'		;リセットベクタ
		goto	start

;==========================================================================
;		割り込み処理
;==========================================================================

		org	h'0004'		;割り込みベクタ

; INTCON:   bit  7     6     5     4     3     2     1     0
;		GIE, PEIE, T0IE, INTE, RABIE, T0IF, INTF, RABIF

interrupt
		; レジスタの保存

		movwf	w_save		;W レジスタの保存
		swapf	STATUS,W
		movwf	s_save		;STATUS レジスタの保存
		movf	FSR,W
		movwf	f_save		;FSR レジスタの保存
		movf	PCLATH,W
		movwf	p_save		;PCLATH レジスタの保存

		movlw	high $		;この場所の high アドレスを
		movwf	PCLATH		;PCLATH に設定
		clrf	STATUS		;バンク 0

		btfsc	INTCON,INTF	;外部(RA2/INT)割り込み か？
		goto	ra2_int		;Yes

		btfsc	INTCON,T0IF	;タイマー０割り込み か？
		goto	t0_int		;Yes

		btfsc	PIR1,TMR1IF	;タイマー１割り込み か？
		goto	t1_int		;Yes
		goto	int_end		;(Illegal interrupt)

;---------------- 外部(RA2/INT)割り込み処理 -------------------------------

ra2_int		bcf	INTCON,INTF	;外部(RA2/INT)割り込みフラグをクリア
		bsf	int_flg,0	;bit0: RTC DS3231 から年月日、時分秒の読み出し要求フラグ = ON
		movlw	b'00000010'
	;	xorwf	int_flg,F	;bit1: DHT22 から温度、湿度の読み出し要求フラグ = ON/OFF, （変更）*
		addwf	int_flg,F	;bit1-2: 4 秒カウンタ
					;bit3: DHT22 から温度、湿度の読み出し要求フラグ = ON
		movf	mod_cnt,W
		btfss	STATUS,Z	;モードNo表示時間カウンタ = 0 か？
		decf	mod_cnt,F	;No. モードNo表示時間カウンタ - 1 
		goto	int_end

;---------------- タイマー０割り込み処理 ----------------------------------

		;（タイマー０を許可したときのみ: 割り込み周期 = 4/8Mz*16*250=2msec）

t0_int		bcf	INTCON,T0IF	;タイマー０割り込みフラグをクリア
		movlw	tm0_h_val	;ハードタイマー０カウント値 = (256 - 250) を
		movwf	TMR0		;TMR0 に設定
		decfsz	tm0_s_cnt,F	;ソフトタイマー０カウンタ - 1 = 0 か？
		goto	int_end		;No

		movlw	1 << 6		;対象ビットをセット
		xorwf	exp_flg,F	;反転表示フラグを 200 mS 毎にビット反転
		bsf	exp_flg,7	;メモリの内容表示フラグ = ON

		movlw	tm0_s_val	;ソフトタイマー０カウント値 = 100 を
		movwf	tm0_s_cnt	;ソフトタイマー０カウンタに設定
		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	PORTB,F		;出力をビット反転
;		goto	int_end

;---------------- 割り込み処理の終了 --------------------------------------

		; レジスタの復帰
int_end		movf	p_save,W
		movwf	PCLATH		;PCLATH レジスタの復帰
		movf	f_save,W
		movwf	FSR		;FSR レジスタの復帰
		swapf	s_save,W
		movwf	STATUS		;STATUS レジスタの復帰
		swapf	w_save,F
		swapf	w_save,W	;W レジスタの復帰

		retfie

;==========================================================================
;		サブルーチンファイルのインクルード
;==========================================================================

#define 	TRISX	TRISB		;PORTB で I2C を行う場合、
#define 	PORTX	PORTB		;
;#define 	_not_wait		;Fast mode で使用	;;... Standard mode に変更

		include		D:\Project\PIC\_sub\I2C_XS.sub		; ドライブ、パス名は
		include		D:\Project\PIC\_sub\I2C_RTC.sub		; 各自の開発環境に
		include		D:\Project\PIC\_sub\DHT22.sub		; 合わせるように !!

;==========================================================================
;		初期化処理
;==========================================================================

#define 	bcd_yy	bcd_yl		;年(下位2桁) BCD カウンタ ***

start
		clrf	STATUS		;STATUS クリア	;バンク 0 （明示的に）
	 	clrf	INTCON		;INTCON クリア

		movlw	h'20'
		movwf	bcd_yh		;年(上位2桁) BCD カウンタ ***

		; PORTA,PORTB,PORTC をデジタルI/O に設定

		bsf	STATUS,RP1	;バンク 2
		clrf	ANSEL		;Digital I/O
		clrf	ANSELH		;

		bcf	STATUS,RP1
		bsf	STATUS,RP0	;バンク 1
		movlw	b'00111111'
		movwf	TRISA		;ポートA の I/0 設定
		movlw	b'00100000'
		movwf	TRISB		;ポートB の I/0 設定
					;RB5: DHT22のDATAポートを入力ポート = 外部プルアップで DHT="H"
		movlw	b'00001000'
		movwf	TRISC		;ポートC の I/0 設定

		movlw	b'00110111'	;RA5,4,2,1,0 を プルアップ
		movwf	WPUA

		; 内部クロックを 8 MHzに設定

		movlw	b'01110001'	;IRCF2-0: bit6-4=111: 内部クロック周波数選択=8MHz
					;OSTS:    bit3=0:R    オシレータ起動タイムアウトステータスビット
					;HTS:     bit2=0:R    HFINTOSCステータスビット
					;LTS:     bit1=0:R    LFINTOSCステータスビット
					;SCS:     bit0=1:     システムクロック選択=内部クロック
		movwf	OSCCON

		; OPTION_REG の設定

		movlw	b'01000011'	;RABPU:  bit7=0:     プルアップ有効
					;INTEDG: bit6=1:     INTピンの立ち上がりエッジで割り込み
					;T0CS:   bit5=0:     タイマー０クロックソース選択 = 内部クロック
					;T0SE:   bit4=0:     タイマー０エッジ選択 = low-to-high
					;PSA:    bit3=0:     タイマー０でプリスケーラを使用
					;PS2-0:  bit2-0=011: プリスケーラのスケール値 = 1:16 
		movwf	OPTION_REG

		; 割り込みの設定

		bcf	PIE1,TMR1IE	;TMR1IE: タイマー１割り込みを禁止
		bcf	STATUS,RP0	;バンク 0

		movlw	b'00000001'	;T1GINV:    bit7=0:    Timer1ゲート反転ビット
					;TMR1GE:    bit6=0:    Timer1ゲートイネーブルビット
					;T1CKPS1-0: bit5-4=00: プリスケーラのスケール値 = 1:1
					;T1OSCEN:   bit3=0:    専用の発振器を使う場合に指定
					;T1SYNC:    bit2=0:    外部入力クロック指定時に有効
					;TMR1CS:    bit1=0:    内部クロックを使う
					;TMR1ON:    bit0=1:    タイマー１を動作
		movwf	T1CON

		movlw	b'11000000'	;GIE:   bit7=1: グローバル割り込みを許可
					;PEIE:  bit6=1: ペリフェラル割り込みを許可
					;T0IE:  bit5=0: TMR0オーバーフロー割り込みを禁止
					;INTE:  bit4=0: RA2 / INT外部割り込みを禁止
					;RABIE: bit3=0: PORTA / PORTB割り込みを禁止
					;T0IF:  bit2=0: TMR0オーバーフロー割り込みフラグ
					;INTF:  bit1=0: RA2 / INT外部割り込みフラグ
					;RABIF: bit0=0: PORTA / PORTB割り込みフラグ
		movwf	INTCON

;--------------------------------------------------------------------------

		bsf	PORTB,SDA	;SDA="H"
		bsf	PORTB,SCL	;SCL="H"
		movlw	h'0f'
		movwf	exp_port	;初期値
		movwf	exptmp		;拡張ポートのリレー制御データ
		call	ExpPCF8574_Write ;（PCF8574/74A）の拡張ポートを初期設定

		movlw	b'11110010'	;bit1:maxLOAD="H", bit2:maxCLK="L"
		movwf	PORTC		;MAX7219 制御の初期設定

		; ドットマトリクス LED のデモ表示

		call	max_led_init	;マトリクス LED モジュールの初期化
		call	buzzer_pipo	;"ピポッ" ブザー音出力
		bcf	PORTB,_BZ	;ブザー出力ビットを "L" にしておく

		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movlw	h'05'		;11/32 ..... 強調表示のため少し多めに
		movwf	reg_data
		call	max_led_contr	;同一データ 6個分の制御

		call	xdemo_display  ;;
		;call	demo1_display	;LED のドット点灯移行デモ-1
		;call	demo2_display	;LED のドット点灯移行デモ-2

		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movlw	h'00'		;1/32 ...... 最小値でもかなり明るい 
		movwf	reg_data
		movwf	intensity	;輝度調節値: デフォルト設定		; (Ver.1.13) で追加
		call	max_led_contr	;同一データ 6個分の制御
		call	led_1s_off	;LED を 1 秒間消灯

		; ドットマトリクス LED の９～０表示テスト

	 	clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		movlw	10		;
		movwf	mlpcnt2		;ループカウンタ2 にセット

dxtst01		movlw	fd_buff		;フォントデータ格納バッファの先頭アドレス
		movwf	FSR		;間接アドレスに設定
		decf	mlpcnt2,W	;表示文字
		call	xfont_read_buff;;１文字フォントデータパタンの読み出しとビット列変換

		movlw	fd_buff		;格納バッファの先頭アドレス
		movwf	FSR		;間接アドレスに再設定
		movlw	8		;
		movwf	digit		;ループカウンタ digit にセット

dxtst02		movf	digit,W
		movwf	reg_addr	;レジスタアドレス
		movf	INDF,W		;バッファから読み出し
		movwf	reg_data
		call	max_led_contr	;同一データ 6個分の制御

		incf	FSR,F		;間接アドレス +1 更新
		decfsz	digit,F		;ループカウンタ digit - 1 = 0 か？
		goto	dxtst02		;No

	;;	call	wait_1sec	;1 秒 ウェイト
		call	wait_500ms	;500m 秒 ウェイト
		decfsz	mlpcnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	dxtst01		;No

		call	led_1s_off	;LED を 1 秒間消灯

		; バージョン番号の表示

		clrf	mod_cnt		;モードNo表示時間カウンタの初期設定
		clrf	exp_flg		;拡張機能フラグの初期設定

		movlw	h'cd'		;"Ver"
		movwf	temp_hh
		movlw	high ver_no	;バージョン番号
		movwf	temp_mm
		movlw	low ver_no	;
		movwf	temp_ss
		movlw	h'dd'		;(xx._x.xx)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;ドットマトリクス LED の表示（3 秒間）

		call	wait_3sec	;3 秒 ウェイト
		movlw	h'f0'		;
		iorwf	PORTC,F		;"Period" 消灯
		call	led_1s_off	;LED を 1 秒間消灯

;--------------------------------------------------------------------------

		; I2C RTC（DS3231）モジュールのチェック

rtcinit01	Rtc_Read_M	cont_stat,1	;h'a0' + 0Fh: Control/Status 読み出し

		bsf	STATUS,RP0	;バンク 1
		movf	cont_stat,W
		bcf	STATUS,RP0	;バンク 0
		movwf	work3
		btfss	work3,7		;OSF = 1 か？
		goto	varinit01	;No

;		[ Error DS3231 ]	;DS3231 RTC エラーメッセージ

		movlw	2
		movwf	tbl_type	;フォントデータテーブルの種類 = 2 を指定
		movlw	h'34'		;"Err."
		movwf	temp_hh
		movlw	h'56'		;"DS"
		movwf	temp_mm
		movlw	h'78'		;"32","31"
		movwf	temp_ss
		movlw	h'fc'		;(xx_xx_xx)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;ドットマトリクス LED の表示
		call	buzzer_bubuu	;"ブッブー" ブザー音出力

rtcinit02	movlw	h'33'		;SW1～SW4 スイッチ
		andwf	PORTA,W
		xorlw	h'33'
		btfsc	STATUS,Z	;どれかのスイッチ = ON か？
		goto	rtcinit02	;No

		; I2C RTC（DS3231）モジュールの初期設定

		call	I2cRtc_Init	;I2C RTC（DS3231）モジュールの初期設定
		goto	rtcinit01

;--------------------------------------------------------------------------

		; 各変数の初期設定

varinit01	clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		clrf	mod_flg		;表示モードフラグの初期設定
		clrf	time_flg	;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		clrf	tmon_flg	;タイマー & 温度監視フラグの初期設定
		clrf	ch3_cnt		;CH3 メモリカウンタの初期設定
		movlw	b'10000000'
		movwf	alm_flg		;アラーム音出力許可フラグ = ON
;
		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		movlw	low timer_mem	;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	3 * 20
		movwf	lp_cnt1		;ループカウンタ

varinit02	clrf	INDF		;タイマー用メモリの初期設定
		incf	FSR,F		;間接アドレス +1 更新
		decfsz	lp_cnt1,F	;ループカウンタ - 1 = 0 か？
		goto	varinit02	;No

		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
;
		Rtc_Read_M  seconds,7	;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter

		movlw	b'11010000'	;GIE:   bit7=1: グローバル割り込みを許可
					;PEIE:  bit6=1: ペリフェラル割り込みを許可
					;T0IE:  bit5=0: TMR0オーバーフロー割り込みを禁止
					;INTE:  bit4=1: RA2 / INT外部割り込みを許可
					;RABIE: bit3=0: PORTA / PORTB割り込みを禁止
		movwf	INTCON		;各割り込み要因の再設定
		clrf	int_flg		;外部割り込みフラグの初期設定
		bsf	mod_flg,7	;表示変更フラグ = ON
		goto	main

;==========================================================================
;		MAX7219 レジスタの基本制御
;==========================================================================

		; マトリクス LED モジュールの初期化

max_led_init
		movlw	h'0f'		;ディスプレイテストレジスタ
		movwf	reg_addr
		movlw	h'00'		;通常動作
		movwf	reg_data
		call	max_led_contr

		movlw	h'09'		;デコードモードレジスタ
		movwf	reg_addr
		movlw	h'00'		;デコードなし
		movwf	reg_data
		call	max_led_contr

		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movlw	h'00'		;1/32 (minimum)
		movwf	reg_data
		call	max_led_contr

		movlw	h'0b'		;スキャン制限レジスタ
		movwf	reg_addr
		movlw	h'07'		;スキャン対象 8桁
		movwf	reg_data
		call	max_led_contr

		movlw	h'0c'		;シャットダウンレジスタ
		movwf	reg_addr
		movlw	h'01'		;通常動作
		movwf	reg_data
		call	max_led_contr

		call	digit_reg_clr	;全 Digit レジスタのクリア
		return		

;--------------------------------------------------------------------------

;		同一データ MAX7219 x 6個分の制御

max_led_contr
		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movlw	6		;
		movwf	mlpcnt1		;ループカウンタにセット

maxcont01	movf	reg_addr,W	;レジスタアドレス
		call	max_byte_send
		movf	reg_data,W	;レジスタデータ
		call	max_byte_send

		decfsz	mlpcnt1,F	;6個分送信した か？
		goto	maxcont01	;No

		bsf	PORTC,maxLOAD	;maxLOAD="H"
		return		

;--------------------------------------------------------------------------

;		データ 1 バイト送信 

max_byte_send
		movwf	maxtmp		;Wレジスタの内容を一時保存
		movlw	8
		movwf	mbit_cnt	;ループカウンタにセット

mbsend01	bcf	PORTC,maxDIN	;maxDIN="L"
		btfsc	maxtmp,7	;送り出しデータの 7ビット目 = 1 か？
		bsf	PORTC,maxDIN	;Yes. maxDIN="H"
		bsf	PORTC,maxCLK	;maxCLK="H"
		nop
		bcf	PORTC,maxCLK	;maxCLK="L"

		rlf	maxtmp,F	;送り出しデータを 1ビット左にシフト
		decfsz	mbit_cnt,F	;8ビット送信した か？
		goto	mbsend01	;No

		return		

;--------------------------------------------------------------------------

;		全 Digit レジスタのクリア

digit_reg_clr
		clrf	reg_data	;レジスタデータ
		movlw	8		;Digit レジスタ数
		movwf	reg_addr	;ループカウンタにセット

dclr01		call	max_led_contr
		decfsz	reg_addr,F	;全 Digit レジスタに送信した か？
		goto	dclr01		;No

		return

;--------------------------------------------------------------------------

;		LED を 1 秒間消灯

led_1s_off
		movlw	h'0c'		;シャットダウンレジスタ
		movwf	reg_addr
		clrf	reg_data	;シャットダウン（LED 消灯）
		call	max_led_contr

		call	wait_1sec	;1 秒 ウェイト

		movlw	h'0c'		;シャットダウンレジスタ
		movwf	reg_addr
		movlw	h'01'		;通常動作
		movwf	reg_data
		call	max_led_contr
		return		

;==========================================================================

#ifdef comment
;	INTCON の内容を表示（最左桁: "HH"桁、最上行: Digit 7 に表示）... デバッグ用

;	   bit   7     6     5     4     3     2     1     0
;		GIE, PEIE, T0IE, INTE, RABIE, T0IF, INTF, RABIF

intcon_disp
		movf	INTCON,W
		movwf	work1		;反転前のビット列
		movlw	8		;
		movwf	lp_cnt1		;ループカウンタ1（segment カウンタ）	

idisp00		rlf	work1,F		;C bit を出力
		rrf	work2,F		;C bit を入力
		decfsz	lp_cnt1,F	;ループカウンタ1 - 1 = 0 か？
		goto	idisp00		;No

		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movlw	5
		bsf	PCLATH,3	;Page 1
		call	no_operation
		bcf	PCLATH,3	;Page 0

		movlw	8		;Digit 7
		call	max_byte_send	;レジスタアドレス
		movf	work2,W		;反転後のビット列
		call	max_byte_send	;レジスタデータ
		bsf	PORTC,maxLOAD	;maxLOAD="H"
		return		
#endif

;==========================================================================
;==========================================================================
;			メイン・ルーチン
;==========================================================================
;==========================================================================

;	mod_flg(表示モードフラグ). bit7: 表示変更フラグ
;				   0:時間, 1:年月日, 2:気温, 3:湿度, 4:オート, (5:SET)

main
		btfsc	mod_flg,7	;表示変更フラグ = ON か？
		goto	main01		;Yes

		movf	mod_cnt,W
		btfss	STATUS,Z	;モードNo表示時間カウンタ = 0 か？
		goto	main05		;No

		btfss	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = ON（１秒周期） か？
		goto	main05		;No

main01		Rtc_Read_M  seconds,7	;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter
	;;;	call	xtime_monitor  ;;
		bsf	PCLATH,3	;Page 1
		call	time_monitor   ;;タイマー & 温度の監視とその処理
		bcf	PCLATH,3	;Page 0

	;;	btfss	int_flg,1	;DHT22 からデータ読み出し要求フラグ = ON（２秒周期） か？
		btfss	int_flg,3	;DHT22 からデータ読み出し要求フラグ = ON（４秒周期） か？, （変更）*
		goto	main04		;No

main02		call	dht22_measure	;DHT22 から温度、湿度を読み出し
		movlw	h'c0'
		andwf	time_cnt,W
		btfsc	STATUS,Z	;読み出しエラーがあった か？
		goto	main03		;No

		call	xdht22_err_display ;;読み出しエラーの表示
		clrf	time_cnt	;初期設定
		bcf	int_flg,3	;DHT22 からデータ読み出し要求フラグ = OFF
		btfss	int_flg,3	;DHT22 からデータ読み出し要求フラグ = ON（４秒周期） か？
		goto	$ - 1		;No
		goto	main02

main03		movf	ch3_cnt,W	;
		btfsc	STATUS,Z	;CH3 メモリカウンタ = 0 か？
		goto	main04		;Yes

		call	temp_cnv	;温度の BCD 変換
	;;;	call	xtime_monitor  ;;
		bsf	PCLATH,3	;Page 1
		call	time_monitor   ;;タイマー & 温度の監視とその処理
		bcf	PCLATH,3	;Page 0

		; 各表示モードの処理

main04		bcf	mod_flg,7	;表示変更フラグ = OFF
		movf	mod_flg,W
		movwf	wk_order
		btfsc	STATUS,Z	;mod_flg = 0 か？
		call	xtime_display  ;;Yes. 時分秒の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 1 か？
		call	xdate_display  ;;Yes. 年月日の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 2 か？
		call	xtemp_display  ;;Yes. 温度の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 3 か？
		call	xhumi_display  ;;Yes. 湿度の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 4 か？
		call	xauto_display  ;;Yes. オートの表示

		bcf	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = OFF
		bcf	int_flg,3	;DHT22 からデータ読み出し要求フラグ = OFF

		call	time_signal	;時報音出力コントロール	
		call	alarm_sound	;アラームフラグの監視とアラーム音出力

		; 各スイッチの ON／OFF 状態のチェック

main05		btfss	PORTA,_swMOD	;MODE / SET スイッチ = ON か？
		call	mode_switch	;Yes

		btfss	PORTA,_swUP	;UP / TIME MODE スイッチ = ON か？
		call	tmode_switch	;Yes

		btfss	PORTA,_swZER	;ZERO スイッチ = ON か？
		call	zero_switch	;Yes

		btfss	PORTC,_swSIG	;SIGNAL スイッチ = ON か？
		call	signal_switch	;Yes

		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		movlw	h'0f'
		andwf	exptmp,W	;スイッチデータを取り出し
		xorlw	h'0f'		;反転する
		btfss	STATUS,Z	;どれかスイッチ = ON か？
		call	exp_processing	;Yes

;;;;;;;;							;;(2021/10/08)
;	movf	exp_flg,F					;;bugfix:  Ver. 1.12
;	btfss	STATUS,Z	;exp_flg = h'00' か？		;;
;	call	buzzer_pi	;No. "ピッ" ブザー音		;;コロン(:)表示の異常を調査
;;;;;;;;							;;するために挿入したTRAP

		clrf	exp_flg		;念のため
		goto	main

;==========================================================================
;		タイマースイッチ機能等の関連処理
;==========================================================================

;	(main) → (exp_processing) → (xdxled_display) → (dxled_display) → (font_read6_buff)
;	       (1)                 (2)                 (3)                (-)
;								     goto に変更
;	       → (font_read_buff) → (font_read) → (interrupt)
;	       (4)                 (5)            (6)

;	exp_flg(拡張機能フラグ). bit7: メモリの内容表示フラグ
;			       . bit6: 反転表示フラグ
;			       . bit2: CH3 フラグ
;			       . bit1-0: CH 番号、01:CH1, 10:CH2 ... タイマースイッチ
;						  11:CH3         ... 温度スイッチ

exp_processing
		call	chx_set		;CH 番号のフラグ設定
		btfsc	STATUS,Z	;EXP スイッチだけ ON か？
		goto	expro2y		;Yes. 終了

;--------------------------------------------------------------------------

		btfsc	PORTA,_swDWN	;DOWN スイッチ = ON か？
		goto	expro01		;No

		; DOWN + CH1～CH3 スイッチ（タイマー用メモリの消去）
		; -------------------------------------------------

		call	wait_30ms	;チャッタリング吸収
		btfss	PORTA,_swDWN	;DOWN スイッチ = OFF か？
		goto	$ - 1		;No

expro00		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		movlw	h'0f'
		andwf	exptmp,W	;スイッチデータを取り出し
		xorlw	h'0f'		;反転する
		btfss	STATUS,Z	;すべてスイッチ = OFF か？
		goto	expro00		;No

		btfsc	exp_flg,2	;CH = 3 か？
		clrf	ch3_cnt		;Yes. CH3 メモリカウンタ = 0　クリア
		call	xclear_memory  ;;CH 別タイマー用メモリの消去

		movlw	3
		movwf	tbl_type	;フォントデータテーブルの種類 = 3 を指定
		movf	exp_flg,W	;
		andlw	h'03'		;"CHx" を取り出し
		movwf	temp_hh
		movlw	h'45'		;"CLR"
		btfss	work3,0		;ワーク, 消去フラグ = ON か？
		movlw	h'67'		;No. "NOT" = 該当の CH がなかったとき
		movwf	temp_mm
		movlw	h'f0'		;(xx xx __)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;ドットマトリクス LED の表示
		clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定

		btfsc	work3,0		;ワーク, 消去フラグ = ON か？
		call	buzzer_pipi	;Yes. "ピピッ" ブザー音
		btfss	work3,0		;ワーク, 消去フラグ = ON か？
		call	buzzer_buu	;No. "ブー" ブザー音
		call	wait_3sec	;3 秒 ウェイト
		goto	expro2x		;終了

;--------------------------------------------------------------------------

expro01		btfss	exptmp,_swEXP	;EXP スイッチ = ON か？
		goto	expro10		;Yes

		; CH1～CH3 スイッチ（タイマーメモリ内容の表示）
		; --------------------------------------------

		call	wait_30ms	;チャッタリング吸収
		clrf	dsp_cnt		;表示カウンタの初期設定

expro02		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		movlw	h'0f'
		andwf	exptmp,W	;スイッチデータを取り出し
		xorlw	h'0f'		;反転する
		btfss	STATUS,Z	;すべてスイッチ = OFF か？
		goto	expro02		;No

		bsf	exp_flg,7	;メモリの内容表示フラグ = ON

expro03		call	exp_monitor	;タイマーと温度の監視

		btfss	exp_flg,7	;メモリの内容表示フラグ = ON か？
		goto	expro06		;No

		call	xread_memory   ;;タイマー用メモリの読み出し
		btfss	dsp_cnt,5	;タイマー用メモリ検索終了フラグ = ON か？
		goto	expro04		;No

		movlw	h'02'		;(__:__ __)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'01'		;Yes. (__.__ __)表示
		goto	expro05

expro04		movf	fmmwwwss,W	;fmmwwwss を壊さないためにワークへ
					;(参考)の delete_memory 内で使用する
		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		
		rrf	work1,W		;swww.sxfm  m
		andlw	h'70'		;www bit を取り出す
		iorwf	temp_ss,F	;

		movlw	h'fe'		;(xx:xx xx)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'fd'		;Yes. (xx.xx xx)表示

expro05		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;メモリ内容の表示
		bcf	exp_flg,7	;メモリの内容表示フラグ = OFF

expro06		btfss	PORTA,_swDWN	;DOWN スイッチ = ON か？
		goto	expro07		;Yes

		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		movlw	h'0f'
		andwf	exptmp,W	;スイッチデータを取り出し
		xorlw	h'0f'		;反転する
		btfsc	STATUS,Z	;どれかスイッチ = ON か？
		goto	expro03		;No

		call	wait_30ms	;チャッタリング吸収
		movf	exp_flg,W	;
		movwf	work1		;退避
		call	chx_set		;CH 番号のフラグ設定
		btfsc	STATUS,Z	;EXP スイッチ = ON か？
		goto	expro2x		;Yes. 終了

		movf	work1,W		;復帰
		xorwf	exp_flg,W	;比較する
		btfss	STATUS,Z	;前回と等しい か？
		clrf	dsp_cnt		;No. 表示カウンタの初期設定

		btfsc	dsp_cnt,5	;タイマー用メモリ検索終了フラグ = ON か？
		clrf	dsp_cnt		;Yes. 表示カウンタの初期設定
		goto	expro02

		; DOWN スイッチ（タイマーメモリ内容の個別消去）
		; --------------------------------------------

expro07		call	wait_30ms	;チャッタリング吸収
		btfss	PORTA,_swDWN	;DOWN スイッチ = OFF か？
		goto	$ - 1		;No

		movlw	3
		movwf	tbl_type	;フォントデータテーブルの種類 = 3 を指定
		movlw	h'67'		;"NOT"
		btfsc	dsp_cnt,5	;タイマー用メモリ検索終了フラグ = ON か？
		goto	expro08		;Yes

		call	xdelete_memory ;;タイマー用メモリの個別消去
		decf	dsp_cnt,F	;表示カウンタの更新
		btfsc	exp_flg,2	;CH3 フラグ = ON か？
		decf	ch3_cnt,F	;Yes. CH3 メモリカウンタ -1 更新
		movlw	h'45'		;"CLR"

expro08		movwf	temp_mm
		movlw	h'30'		;(__ xx __)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;ドットマトリクス LED の表示
		clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定

		btfss	dsp_cnt,5	;タイマー用メモリ検索終了フラグ = ON か？
		call	buzzer_pipi	;No. "ピピッ" ブザー音
		btfsc	dsp_cnt,5	;タイマー用メモリ検索終了フラグ = ON か？
		call	buzzer_buu	;Yes. "ブー" ブザー音

		call	wait_3sec	;3 秒 ウェイト
		goto	expro02

;--------------------------------------------------------------------------

;	exp_flg(拡張機能フラグ). bit7: メモリの内容表示フラグ
;			       . bit6: 反転表示フラグ
;			       . bit2: CH3 フラグ
;			       . bit1-0: CH 番号、01:CH1, 10:CH2 ... タイマースイッチ
;						  11:CH3         ... 温度スイッチ

		; EXP + CH1～CH3 スイッチ（タイマーの設定）
		; ----------------------------------------

expro10		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		movlw	h'0f'
		andwf	exptmp,W	;スイッチデータを取り出し
		xorlw	h'0f'		;反転する
		btfss	STATUS,Z	;すべてスイッチ = OFF か？
		goto	expro10		;No

		call	wait_30ms	;チャッタリング吸収
		movlw	tm0_h_val	;ハードタイマー０カウント値を
		movwf	TMR0		;TMR0 に設定
		movlw	tm0_s_val	;ソフトタイマー０カウント値を
		movwf	tm0_s_cnt	;ソフトタイマー０カウンタに設定
		bcf	INTCON,T0IF	;タイマー０割込みフラグをクリア
		bsf	INTCON,T0IE	;bit5(T0IE)=1: タイマー０割り込み許可

expro11		clrf	temp_hh		;初期設定
		clrf	temp_mm		;
		clrf	temp_ss		;
		clrf	tg_point	;対象の位置ポインタ = 0
		clrf	chg_flg		;データ変更フラグをクリア

		movlw	h'0a'		;℃
		btfsc	exp_flg,2	;CH = 3 か？
		movwf	temp_mm		;Yes. "ML" 桁
		bsf	exp_flg,7	;メモリの内容表示フラグ = ON

		; メモリ設定データの表示
expro12		call	exp_monitor	;タイマーと温度の監視

		btfss	exp_flg,7	;メモリの内容表示フラグ = ON か？
		goto	expro18		;No

		btfsc	exp_flg,6	;反転表示フラグ = ON (非表示) か？
		goto	expro13		;Yes

		movlw	h'fe'		;(xx:xx xx)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'fd'		;(xx.xC xx)表示
		goto	expro17

expro13		movf	tg_point,F
		btfss	STATUS,Z	;tg_point = 0 か？
		goto	expro14		;No

		movlw	h'3e'		;(__:xx xx)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'3d'		;(__.xC xx)表示
		goto	expro17

expro14		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z	;tg_point = 1 か？
		goto	expro15		;No

		movlw	h'ce'		;(xx:__ xx)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'dd'		;(xx._C xx)表示
		goto	expro17

expro15		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z	;tg_point = 2 か？
		goto	expro16		;No

		movlw	h'f6'		;(xx:xx _x)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'f5'		;(xx.xC _x)表示
		goto	expro17

expro16		movlw	h'fa'		;(xx:xx x_)表示
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'f9'		;(xx.xC x_)表示

expro17		movwf	dspdigit	;表示桁指定フラグの設定
	;;;	call	xdxled_display ;;設定データの表示
		bsf	PCLATH,3	;Page 1
		call	dxled_display	;
		bcf	PCLATH,3	;Page 0
		bcf	exp_flg,7	;メモリの内容表示フラグ = OFF

		; 各スイッチの入力処理
expro18		btfss	PORTA,_swSET	;SET スイッチ = ON か？
		call	set2_switch	;Yes

		btfss	PORTA,_swUP	;UP スイッチ = ON か？
		call	up2_switch	;Yes

		btfss	PORTA,_swDWN	;DOWN スイッチ = ON か？
		call	down2_switch	;Yes

		btfss	PORTA,_swBAK	;BACK スイッチ = ON か？
		call	back2_switch	;Yes

		movlw	h'03'
		andwf	chg_flg,W	;
		btfss	STATUS,Z	;データ変更フラグ = セット か？
		bsf	exp_flg,7	;Yes. メモリの内容表示フラグ = ON
		btfss	STATUS,Z	;データ変更フラグ = セット か？
		bcf	exp_flg,6	;Yes. 反転表示フラグ = OFF (表示)
		clrf	chg_flg		;データ変更フラグをクリア

		movlw	4
		subwf	tg_point,W
		btfsc	STATUS,Z	;tg_point = 4 か？
		goto	expro19		;Yes

		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		btfsc	exptmp,_swEXP	;EXP スイッチ = ON か？
		goto	expro12		;No
		goto	expro21		;Yes

		; タイマー用メモリへの書き込み      C
		;	temp_ss		;0www.00mm  x
expro19		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

		movlw	h'03'
		andwf	exp_flg,W	;ss bit を取り出す
		iorwf	fmmwwwss,F	;0mmw.wwss
					;f bit は write_memory 内で書き込む
		call	xwrite_memory  ;;タイマー用メモリへの書き込み
		btfsc	STATUS,C	;書き込み済み OK か？
		goto	expro20		;No. メモリオーバー

		btfsc	exp_flg,2	;CH3 フラグ = ON か？
		incf	ch3_cnt,F	;Yes. CH3 メモリカウンタ +1 更新

		call	buzzer_pipi	;"ピピッ" ブザー音
		goto	expro11

expro20		movlw	2
		movwf	tbl_type	;フォントデータテーブルの種類 = 2 を指定
		movlw	h'34'		;"Err."
		movwf	temp_hh
		movlw	h'ef'		;"MEM"
		movwf	temp_mm
		movlw	h'f0'		;(xx xx __)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;ドットマトリクス LED の表示
		call	buzzer_bubuu	;"ブッブー" ブザー音出力
		clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定

		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		btfsc	exptmp,_swEXP	;EXP スイッチ = ON か？
		goto	$ - 2		;No

expro21		bcf	INTCON,T0IE	;タイマー０割り込みを禁止
		bcf	INTCON,T0IF	;タイマー０割込みフラグをクリア
		call	wait_30ms	;チャッタリング吸収

		call	ExpPCF8574_Read	;（PCF8574/74A）の拡張ポートからデータを読み出し
		btfss	exptmp,_swEXP	;EXP スイッチ = OFF か？
		goto	$ - 2		;No

expro2x		clrf	exp_flg		;
		bsf	mod_flg,7	;表示変更フラグ = ON

expro2y		return

		;（参考）どちらでも命令数は同じ
#ifdef comment
		;	temp_ss		;0www.00mm  x
expro19		rlf	temp_ss,F	;www0.0mmx  0
		swapf	temp_ss,F	;0mmx.www0  0
		movf	temp_ss,W	;0mmx.www0  0
		andlw	h'60'		;0mm0.0000  0
		movwf	fmmwwwss	;0mm0.0000  0
		rlf	temp_ss,W	;mmxw.ww00  0
		andlw	h'1c'		;000w.ww00  0
		iorwf	fmmwwwss,F	;0mmw.ww00  0
#endif

;==========================================================================

		; CH 番号のフラグ設定
chx_set
		clrf	exp_flg		;初期設定
		incf	exp_flg,F
		btfss	exptmp,_swCH1	;CH1 スイッチ = ON か？
		goto	chset01		;Yes

		incf	exp_flg,F
		btfss	exptmp,_swCH2	;CH2 スイッチ = ON か？
		goto	chset01		;Yes

		incf	exp_flg,F
		bsf	exp_flg,2	;CH3 フラグ = ON
		btfss	exptmp,_swCH3	;CH3 スイッチ = ON か？
		goto	chset01		;Yes

		clrf	exp_flg		;EXP スイッチだけのとき

chset01		movf	exp_flg,W
		return

;--------------------------------------------------------------------------

;	 Page0								   Page1
;	(main) → (exp_processing) → (exp_monitor) → (xtime_monitor) → (time_monitor) → (xExpPCF8574_Write) 
;	       (1)                 (2)              (3)                (4)               (5)                
;		   Page0
;	       → (ExpPCF8574_Write) → (i2c_byte_send) → (i2c_wait) → (interrupt)
;	       (6)                   (7)                (8)           (x)               

;改善後  Page0						Page1		  Page0
;	(main) → (exp_processing) → (exp_monitor) → (time_monitor) → (ExpPCF8574_Write) 
;	       (1)                 (2)              (3)               (4)               
;
;	       → (i2c_byte_send) → (i2c_wait) → (interrupt)
;	       (5)                (6)           (7)             

		; タイマーと温度の監視（EXP 処理中）
exp_monitor
		btfss	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = ON（１秒周期） か？
		goto	exmon02		;No

		Rtc_Read_M  seconds,7	;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter
	;;;	call	xtime_monitor  ;;
		bsf	PCLATH,3	;Page 1
		call	time_monitor   ;;タイマー & 温度の監視とその処理
		bcf	PCLATH,3	;Page 0
		bcf	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = OFF

		movf	ch3_cnt,W	;
		btfsc	STATUS,Z	;CH3 メモリカウンタ = 0 か？
		goto	exmon01		;Yes

		btfss	int_flg,3	;DHT22 からデータ読み出し要求フラグ = ON（４秒周期） か？
		goto	exmon02		;No

		call	dht22_measure	;DHT22 から温度、湿度を読み出し
		movlw	h'c0'
		andwf	time_cnt,W
		btfss	STATUS,Z	;読み出しエラーがあった か？
		goto	exmon01		;Yes. （EXP 処理中はエラーメッセージを出さない）

		call	temp_cnv	;温度の BCD 変換
	;;;	call	xtime_monitor  ;;
		bsf	PCLATH,3	;Page 1
		call	time_monitor   ;;タイマー & 温度の監視とその処理
		bcf	PCLATH,3	;Page 0

exmon01		bcf	int_flg,3	;DHT22 からデータ読み出し要求フラグ = OFF

exmon02		return

;--------------------------------------------------------------------------

		; 温度の BCD 変換
temp_cnv
		movf	temperature_h,W	;温度上位 8 bit
		andlw	h'7f'
		movwf	data_h
		movf	temperature_l,W	;温度下位 8 bit
		movwf	data_l
		call	bindec16c_cnv	;16 ビット数値を 10進数 5桁の文字列に変換

		movlw	h'0f'		;
		andwf	buff2,W		;
		movwf	data_h
		swapf	data_h,F	;整数十位

		movlw	h'0f'		;
		andwf	buff3,W		;
		iorwf	data_h,F	;整数一位

		movlw	h'0f'		;
		andwf	buff4,W		;
		movwf	data_l
		swapf	data_l,F	;小数一位

		movlw	h'0a'		;
		iorwf	data_l,F	;℃

		bsf	tmon_flg,1	;温度監視フラグ = ON
		return

;==========================================================================
;	I/O エキスパンダ IC（PCF8574/74A）のポートとのデータ入出力
;==========================================================================

;ExpAddr	equ	h'20'		; I/O エキスパンダ IC（PCF8574） のスレーブアドレス
ExpAddr		equ	h'38'		; I/O エキスパンダ IC（PCF8574A）のスレーブアドレス

;<使用外部ルーチン>

;(i2c_start, i2c_stop, i2c_byte_send, i2c_byte_reciv, i2c_nack)

;<使用レジスタ>

;exptmp					;書き込み／読み出しデータ

;--------------------------------------------------------------------------
;		（PCF8574/74A）のポートへデータを書き込み
;--------------------------------------------------------------------------

ExpPCF8574_Write
		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

;==========================================================================

;--------------------------------------------------------------------------
;		バッファと BCD カウンタ間のデータ移動
;--------------------------------------------------------------------------

		; バッファからカウンタへコピー

buffer_to_counter
		movlw	seconds		;RTC バッファの先頭アドレス
		movwf	FSR
		movf	INDF,W		;Seconds
		movwf	bcd_ss		;秒 BCD カウンタ

		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;Minutes
		movwf	bcd_mm		;分 BCD カウンタ

		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;Hours
		movwf	bcd_hh		;時 BCD カウンタ

		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;Day
		movwf	bcd_ww		;曜日 BCD カウンタ

		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;Date
		movwf	bcd_dd		;日 BCD カウンタ

		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;Month
		andlw	h'1f'		;
		movwf	bcd_nn		;月 BCD カウンタ

		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;Year
		movwf	bcd_yy		;年 BCD カウンタ

		movf	bcd_ss,W	;秒 BCD カウンタ
		btfsc	STATUS,Z	;bcd_ss = h'00' か？
		bsf	tmon_flg,0	;Yes. タイマー監視フラグ = ON
		return

;--------------------------------------------------------------------------

		; カウンタからバッファへコピー

counter_to_buffer
		movlw	seconds		;RTC バッファの先頭アドレス
		movwf	FSR
		movf	bcd_ss,W	;秒 BCD カウンタ
		movwf	INDF		;Seconds

		incf	FSR,F		;間接アドレス +1 更新
		movf	bcd_mm,W	;分 BCD カウンタ
		movwf	INDF		;Minutes

		incf	FSR,F		;間接アドレス +1 更新
		movf	bcd_hh,W	;時 BCD カウンタ
		movwf	INDF		;Hours

		incf	FSR,F		;間接アドレス +1 更新
		movf	bcd_ww,W	;曜日 BCD カウンタ
		movwf	INDF		;Day

		incf	FSR,F		;間接アドレス +1 更新
		movf	bcd_dd,W	;日 BCD カウンタ
		movwf	INDF		;Date

		incf	FSR,F		;間接アドレス +1 更新
		movf	bcd_nn,W	;月 BCD カウンタ
		movwf	INDF		;Month

		incf	FSR,F		;間接アドレス +1 更新
		movf	bcd_yy,W	;年 BCD カウンタ
		movwf	INDF		;Year
		return

;==========================================================================
;     各スイッチのメイン・ルーチンでの処理と SET / EXP モードでの処理
;==========================================================================
;--------------------------------------------------------------------------
;	   MODE / SET スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

;	(main) → (mode_switch) → (xdate_display) → (date_display) → (dxled_display) → (font_read6_buff)
;	       (1)              (2)                (3)               (4)                (-)
;										     goto に変更
;	       → (font_read_buff) → (font_read) → (interrupt)
;	       (5)                 (6)            (7)

mode_switch
		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swMOD	;再度 MODE スイッチ = ON か？
		goto	modsw10		;No

		movlw	60		;50ms x 60 = 3 秒間の監視
		movwf	wk_order	;ループカウンタ

modsw01		call	wait_50ms	;50m 秒 ウエイト

		movlw	h'7f'
		andwf	mod_flg,W
		btfss	STATUS,Z	;mod_flg = 0 か？
		goto	modsw02		;No

		btfss	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = ON か？	;
		goto	modsw02		;No							;
												;これらの命令がないと
		Rtc_Read_M  seconds,7	;RTC DS3231 から年月日、時分秒を読み出し		;表示が停止して違和感
		call	buffer_to_counter							;を感じたので挿入した
		call	xtime_display  ;;時分秒の表示						;
		bcf	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = OFF		;
modsw02												;
		btfsc	PORTA,_swMOD	;MODEスイッチ = OFF か？
		goto	modsw03		;Yes

		decfsz	wk_order,F	;ループカウンタ - 1 = 0 か？
		goto	modsw01		;No
		goto	modsw04		;Yes

		; 表示モードフラグの更新

modsw03		incf	mod_flg,F	;表示モードフラグの更新
		movlw	5
		subwf	mod_flg,W
		btfsc	STATUS,Z	;表示モードフラグ = 5 か？
		clrf	mod_flg		;Yes. mod_flg = 0 にクリア
		bsf	mod_flg,7	;表示変更フラグ = ON
		movlw	2		;2 秒
		movwf	mod_cnt		;モードNo表示時間カウンタ設定
		goto	modsw10

;--------------------------------------------------------------------------

		;;;;; SET モードに移行 ;;;;;

modsw04		bcf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止

		movlw	2
		movwf	tbl_type	;フォントデータテーブルの種類 = 2 を指定

		movlw	h'22'		;"**"
		movwf	temp_hh
		movlw	h'01'		;"SET"
		movwf	temp_mm
		movlw	h'22'		;"**"
		movwf	temp_ss
		movlw	h'fc'		;(xx xx xx)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	xdxled_display ;;
	 	clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定

		btfss	PORTA,_swSET	;MODE/SET スイッチ = OFF か？
		goto	$ - 1		;No

		movlw	5		;(SET モード)
		movwf	mod_flg		;表示モードフラグ = 5
		clrf	tg_point	;対象の位置ポインタ = 0
		clrf	chg_flg		;データ変更フラグをクリア
		clrf	int_flg		;

modsw05		bcf	chg_flg,0	;対象の位置の変更フラグ = 0
		movlw	3		;
		subwf	tg_point,W	;
		btfsc	STATUS,C	;対象の位置ポインタ < 3 か？
		goto	modsw06		;No

		call	xdate_display  ;;年月日の表示
		goto	modsw07

modsw06		call	xtime_display  ;;時分秒の表示

		; 各スイッチの入力処理

modsw07		btfss	PORTA,_swSET	;SET スイッチ = ON か？
		call	set_switch	;Yes

		btfss	PORTA,_swUP	;UP スイッチ = ON か？
		call	up_switch	;Yes

		btfss	PORTA,_swDWN	;DOWN スイッチ = ON か？
		call	down_switch	;Yes

		btfss	PORTA,_swBAK	;BACK スイッチ = ON か？
		call	back_switch	;Yes

		movlw	6
		subwf	tg_point,W
		btfsc	STATUS,Z	;終了 tg_point = 6 か？
		goto	modsw08		;Yes

		movlw	h'03'
		andwf	chg_flg,W
		btfsc	STATUS,Z	;どれかのキー操作があった か？
		goto	modsw07		;No
		goto	modsw05		;Yes

modsw08		btfss	PORTA,_swSET	;SET スイッチ = OFF か？
		goto	$ - 1		;No

		btfss	chg_flg,1	;対象の位置のデータ変更があった か？
		goto	modsw09		;No

		call	counter_to_buffer
		Rtc_Write_M  seconds,7	;RTC DS3231 へ年月日、時分秒を書き込み

modsw09		clrf	chg_flg		;データ変更フラグをクリア
		clrf	mod_flg		;表示モードフラグをクリア
		bsf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止解除

modsw10		btfss	PORTA,_swMOD	;MODE スイッチ = OFF か？
		goto	$ - 1		;No

		return

;--------------------------------------------------------------------------
;	      SET スイッチの処理 ... SET / EXP モードから CALL
;--------------------------------------------------------------------------

set_switch	;; SET モード
set2_switch	;; EXP モード

		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swSET	;再度 SET スイッチ = ON か？
		goto	setsw01		;No

		bsf	chg_flg,0	;対象の位置の変更フラグ = ON
		incf	tg_point,F	;対象の位置ポインタ + 1

setsw01		btfss	PORTA,_swSET	;SET スイッチ = OFF か？
		goto	$ - 1		;No

		call	wait_30ms	;チャッタリング吸収
		return

;--------------------------------------------------------------------------
;	      UP スイッチの処理 ... SET / EXP モードから CALL
;--------------------------------------------------------------------------

up_switch	;; SET モード

		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swUP	;再度 UP スイッチ = ON か？
		goto	upsw07		;No

		bsf	chg_flg,1	;対象の位置のデータ変更フラグ = ON
		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	PORTA,_swUP	;UP スイッチ = OFF か？
	;	goto	$ - 1		;No

		call	wait_200ms	;早送りの速度調整
		return

;--------------------------------------------------------------------------

up2_switch	;; EXP モード

		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swUP	;再度 UP スイッチ = ON か？
		goto	upsw25		;No

		bsf	chg_flg,1	;対象の位置のデータ変更フラグ = ON
		movf	tg_point,W
		btfss	STATUS,Z	;tg_point = 0 か？
		goto	upsw21		;No

		btfss	exp_flg,2	;CH = 3 か？
		call	bcd_hh_inc2	;No. 時 BCD カウンタのインクリメント
		btfsc	exp_flg,2	;CH = 3 か？
		call	temp_int_inc	;Yes. 温度(整数) BCD カウンタのインクリメント
		goto	upsw25

upsw21		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z	;tg_point = 1 か？
		goto	upsw22		;No

		btfss	exp_flg,2	;CH = 3 か？
		call	bcd_mm_inc2	;No. 分 BCD カウンタのインクリメント
		btfsc	exp_flg,2	;CH = 3 か？
		call	temp_dec_inc	;Yes. 温度(小数) BCD カウンタのインクリメント
		goto	upsw25

upsw22		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z	;tg_point = 2 か？
		goto	upsw23		;No

		movlw	h'10'
		addwf	temp_ss,F	;曜日 BCD カウンタのインクリメント
		movlw	h'80'
		subwf	temp_ss,W
		btfss	STATUS,C	;temp_ss < h'80' か？
		goto	upsw25		;Yes

		movlw	h'0f'
		andwf	temp_ss,F	;上位4ビット = 0
		goto	upsw25

		; CH1,CH2: 00:OFF → 01:ON → 11:SLP → 00
		;     CH3: 00:OFF → 01:ON → 00
upsw23		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	upsw25		;Yes. 01:ON

		btfsc	exp_flg,2	;CH = 3 か？
		goto	upsw24		;Yes

		incf	temp_ss,F	
		btfss	temp_ss,2	;下位4ビット >= 4 か？
		goto	upsw25		;No. 11:SLP

upsw24		movlw	h'f0'
		andwf	temp_ss,F	;MODE(OFF,ON,SLP) = 00:OFF

upsw25	;	btfss	PORTA,_swUP	;UP スイッチ = OFF か？
	;	goto	$ - 1		;No

		call	wait_200ms	;早送りの速度調整
		return

		; 温度(整数) BCD カウンタのインクリメント
temp_int_inc
		movlw	temp_hh		;温度(整数) BCD カウンタの番地
		movwf	FSR		;間接アドレスに設定
		call	inc_bcd		;BCDインクリメント

		movlw	h'a0'
		subwf	temp_hh,W
		btfss	STATUS,Z	;温度(整数) BCD カウンタ = h'a0' か？
		goto	tiinc01		;No

		clrf	temp_hh		;温度(整数) BCD カウンタのクリア

tiinc01		return

		; 温度(小数) BCD カウンタのインクリメント
temp_dec_inc
		movlw	h'10'
		addwf	temp_mm,F	;温度(小数) BCD カウンタ + 1
		movlw	h'a0'
		subwf	temp_mm,W
		btfss	STATUS,C	;temp_mm < h'a0' か？
		goto	tdinc01		;Yes

		movlw	h'0f'
		andwf	temp_mm,F	;温度(小数) BCD カウンタ = 0

tdinc01		return

;--------------------------------------------------------------------------
;	     DOWN スイッチの処理 ... SET / EXP モードから CALL
;--------------------------------------------------------------------------

down_switch	;; SET モード

		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swDWN	;再度 DOWN スイッチ = ON か？
		goto	dwnsw07		;No

		bsf	chg_flg,1	;対象の位置のデータ変更フラグ = ON
		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	PORTA,_swDWN	;DWN スイッチ = OFF か？
	;	goto	$ - 1		;No

		call	wait_200ms	;早送りの速度調整
		return

;--------------------------------------------------------------------------

down2_switch	;; EXP モード

		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swDWN	;再度 DOWN スイッチ = ON か？
		goto	dwnsw25		;No

		bsf	chg_flg,1	;対象の位置のデータ変更フラグ = ON
		movf	tg_point,W
		btfss	STATUS,Z	;tg_point = 0 か？
		goto	dwnsw21		;No

		btfss	exp_flg,2	;CH = 3 か？
		call	bcd_hh_dec2	;No. 時 BCD カウンタのデクリメント
		btfsc	exp_flg,2	;CH = 3 か？
		call	temp_int_dec	;Yes. 温度(整数) BCD カウンタのデクリメント
		goto	dwnsw25

dwnsw21		movlw	1
		subwf	tg_point,W
		btfss	STATUS,Z	;tg_point = 1 か？
		goto	dwnsw22		;No

		btfss	exp_flg,2	;CH = 3 か？
		call	bcd_mm_dec2	;No. 分 BCD カウンタのデクリメント
		btfsc	exp_flg,2	;CH = 3 か？
		call	temp_dec_dec	;Yes. 温度(小数) BCD カウンタのデクリメント
		goto	dwnsw25

dwnsw22		movlw	2
		subwf	tg_point,W
		btfss	STATUS,Z	;tg_point = 2 か？
		goto	dwnsw23		;No

		movlw	h'10'
		subwf	temp_ss,F	;曜日 BCD カウンタのデクリメント
		btfsc	STATUS,C	;temp_ss < h'10' か？
		goto	dwnsw25		;No

		movlw	h'80'
		addwf	temp_ss,F	;曜日 BCD カウンタ = 7
		goto	dwnsw25

		; CH1,CH2: 11:SLP → 01:ON → 00:OFF → 11
		;     CH3:           01:ON → 00:OFF → 01
dwnsw23		movf	temp_ss,W	;現在の値
		andlw	h'0f'
		btfsc	STATUS,Z	;下位4ビット = 0 か？
		goto	dwnsw24		;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	dwnsw25

dwnsw24		movlw	h'03'		;00:OFF, 01:ON, 10:--, 11:SLP
		btfsc	exp_flg,2	;CH = 3 か？
		movlw	h'01'		;Yes. 00:OFF, 01:ON
		iorwf	temp_ss,F	;MODE(OFF,ON,SLP) = 最大値

dwnsw25	;	btfss	PORTA,_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

		movlw	h'66'
		subwf	temp_hh,F	;温度(整数) 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
		movlw	h'f0'
		andwf	temp_mm,W
		btfsc	STATUS,Z	;温度(小数) BCD カウンタ = 0 か？
		goto	tddec01		;Yes

		movlw	h'10'
		subwf	temp_mm,F	;温度(小数) BCD カウンタ - 1
		goto	tddec02

tddec01		movlw	h'0f'
		andwf	temp_mm,F
		movlw	h'90'
		iorwf	temp_mm,F	;温度(小数) BCD カウンタ = 9

tddec02		return

;--------------------------------------------------------------------------
;	     BACK スイッチの処理 ... SET / EXP モードから CALL
;--------------------------------------------------------------------------

back_switch	;; SET モード
back2_switch	;; EXP モード

		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swBAK	;再度 BACK スイッチ = ON か？
		goto	baksw01		;No

		bsf	chg_flg,0	;対象の位置の変更フラグ = ON
		decf	tg_point,F	;対象の位置ポインタ - 1
		incf	tg_point,W
		btfss	STATUS,Z	;対象の位置ポインタ = 0 か？
		goto	baksw01		;No

		movlw	5		;(SET モード)
		movf	exp_flg,F
		btfss	STATUS,Z	;exp_flg = h'00' か？
		movlw	3		;No. (EXP モード)
		movwf	tg_point	;最大値 tg_point = 5 or 3 に設定

baksw01		btfss	PORTA,_swBAK	;BACK スイッチ = OFF か？
		goto	$ - 1		;No

		call	wait_30ms	;チャッタリング吸収
		return

;--------------------------------------------------------------------------
;	UP / TIME MODE スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

tmode_switch
		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swUP	;再度 UP スイッチ = ON か？
		goto	tmodsw01	;No

		movlw	b'00000010'
		xorwf	time_flg,F	;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		bsf	mod_flg,7	;表示変更フラグ = ON

tmodsw01	btfss	PORTA,_swUP	;UP スイッチ = OFF か？
		goto	$ - 1		;No

		call	wait_30ms	;チャッタリング吸収
		return

;--------------------------------------------------------------------------
;	     ZERO スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

zero_switch
		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swZER	;再度 ZERO スイッチ = ON か？
		goto	zersw04		;No

		movlw	h'05'
		subwf	bcd_mm,W
		btfss	STATUS,C	;分 BCD カウンタ < h'05' か？
		goto	zersw02		;Yes

		movlw	h'55'
		subwf	bcd_mm,W
		btfss	STATUS,C	;分 BCD カウンタ >= h'55' か？
	;;	goto	zersw04		;No. 無視				; (Ver.1.13 で変更)
		goto	zersw05		;No					;

		bcf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止
		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	zersw01		;No

		call	bcd_nn_inc	;月 BCD カウンタのインクリメント
		movlw	h'01'
		subwf	bcd_nn,W
		btfss	STATUS,Z	;月 BCD カウンタ = h'01' か？
		goto	zersw01		;No

		call	bcd_yl_inc	;年(下位2桁) BCD カウンタのインクリメント

zersw01		call	day_week	;該当日の曜日を取得
		movwf	bcd_ww		;曜日 BCD カウンタ
		goto	zersw03

zersw02		bcf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止

zersw03		clrf	bcd_mm		;分 BCD カウンタのクリア
		clrf	bcd_ss		;秒 BCD カウンタのクリア
		call	counter_to_buffer
		Rtc_Write_M  seconds,7	;RTC DS3231 へ年月日、時分秒を書き込み

		bsf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止解除
		bsf	mod_flg,7	;表示変更フラグ = ON, （強制再表示）

zersw04		btfss	PORTA,_swZER	;ZERO スイッチ = OFF か？
		goto	$ - 1		;No

		call	wait_30ms	;チャッタリング吸収
		return

;--------------------------------------------------------------------------	; (Ver.1.13 で追加)

zersw05		movlw	20		;50ms x 20 = 1 秒間の監視
		movwf	wk_order	;ループカウンタ

zersw06		call	wait_50ms	;50m 秒 ウエイト
		btfsc	PORTA,_swZER	;ZERO スイッチ = OFF か？
		goto	zersw04		;Yes

		decfsz	wk_order,F	;ループカウンタ - 1 = 0 か？
		goto	zersw06		;No

		bsf	PCLATH,3	;Page 1
		call	bright_adj	;輝度調節機能 (Ver.1.13 で機能追加)
		bcf	PCLATH,3	;Page 0
		goto	zersw04

;--------------------------------------------------------------------------
;	     SIGNAL スイッチの処理 ... メイン・ルーチンから CALL
;--------------------------------------------------------------------------

;出力:	alm_flg: アラーム音出力フラグ ( bit0:リレー ON, bit1:リレー OFF, bit2:予報音, bit3:正報音, bit7:出力許可 )

signal_switch
		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTC,_swSIG	;再度 SIGNAL スイッチ = ON か？
		goto	sigsw01		;No

		movlw	b'10000000'
		xorwf	alm_flg,F	;アラーム音出力許可フラグの更新

		btfsc	alm_flg,7	;アラーム音出力許可フラグ = ON か？
		call	buzzer_pipipi	;Yes. 許可  "ピピピッ" ブザー音出力
		btfss	alm_flg,7	;アラーム音出力許可フラグ = OFF か？
		call	buzzer_buu	;Yes. 禁止  "ブー" ブザー音出力

sigsw01		btfss	PORTC,_swSIG	;SIGNAL スイッチ = OFF か？
		goto	$ - 1		;No

		call	wait_30ms	;チャッタリング吸収
		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

;--------------------------------------------------------------------------
;		16 ビット数値を 10進数 5桁の文字列に変換
;--------------------------------------------------------------------------

		;	(data_h,data_l): 変換する 16 ビット数値
		;	work1: ワーク

bindec16c_cnv
		movlw	buff0 + 4	;変換文字列の格納エリア
		movwf	FSR		;間接アドレスの設定
		call	bd16c		;(04) 最下位変換
		call	bd16c		;(03)
		call	bd16c		;(02)
		call	bd16c		;(01)
		call	bd16c		;(00) 最上位変換
		return

		; ÷10（10で除算）
bd16c
		movlw	16		;16ビット繰り返し
		movwf	lp_cnt1		;ループカウンタに設定
		clrf	work1

bd16c01		bcf	STATUS,C	;キャリフラグのクリア
		rlf	data_l,F
		rlf	data_h,F
		rlf	work1,F
		movlw	-10		;-10 = h'f6'
		addwf	work1,W
		btfss	STATUS,C	;C = 1 か？
		goto	bd16c02		;No

		movwf	work1		;
		incf	data_l,F	;

bd16c02		decfsz	lp_cnt1,F	;ループカウンタ - 1 = 0 か？
		goto	bd16c01		;No

		movf	work1,W		;余り
		iorlw	h'30'
		movwf	INDF		;文字コードに変換
		decf	FSR,F		;間接アドレスの更新
		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

;--------------------------------------------------------------------------

month_day2
		decf	work2,W
		movwf	addr_low
		movlw	high day_tbl
		movwf	addr_high	;先頭 high アドレス
		movlw	low day_tbl
		addwf	addr_low,F	;先頭 low アドレス
		btfsc	STATUS,C	;オーバーフローした場合は
		incf	addr_high,F	;high アドレスの更新
;		call	day_read	;day_tbl データの読み出し
;		return

;day_read
		movf	addr_high,W	;文字フォントデータの high アドレス
		movwf	PCLATH
		movf	addr_low,W	;文字フォントデータの low アドレス
		movwf	PCL

;;month_day2								;; (2021/10/07)
;;		decf	work2,W						;; bugfix:  Ver. 1.11
;;		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  (使用しない)

;==========================================================================
;		時報音出力コントロール
;==========================================================================

;  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	;アラーム音出力許可フラグ = ON か？
		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	;正報音フラグのセット

ts102		return

;--------------------------------------------------------------------------

;		アラームフラグの監視とアラーム音出力

; alm_flg: アラームフラグ
;		┌───────────  signal_switch で設定
;		│　　　　 ┌────── time_signal で設定	
;		│　　　　 │　┌──── time_monitor で設定
;		│　　　　┌┐┌┐
;		ｘ０００．ｘｘｘｘ
;		│　　　　││││
;		│　　　　│││└─── リレー ON フラグ	;"ピポッピポッ"
;		│　　　　││└──── リレー OFF フラグ	;"ブーー"
;		│　　　　│└───── 時報予報音フラグ	;"プッ"
;		│　　　　└────── 時報正報音フラグ	;"ポッ～～ン"
;		└─────────── アラーム音出力許可フラグ

alarm_sound
;		btfss	alm_flg,7	;アラーム音出力許可フラグ = ON か？
;		goto	alarm05		;（このフラグ = OFF のときは、
					;４つのフラグ = ON になることはない）
		movlw	h'7f'
		andwf	alm_flg,W
		btfsc	STATUS,Z	;どれかアラームフラグ = ON か？
		goto	alarm05		;No

		btfss	alm_flg,0	;リレー ON フラグ = ON か？
		goto	alarm01		;No

		call	buzzer_pipo2	;"ピポッピポッ" ブザー音出力 (490 mS)
		goto	alarm04

alarm01		btfss	alm_flg,1	;リレー OFF フラグ = ON か？
		goto	alarm02		;No

		call	buzzer_buu	;"ブー" ブザー音出力 (250 mS)
		call	buzzer_buu	;"ブー" ブザー音出力 (250 mS)
		goto	alarm04

alarm02		btfss	alm_flg,2	;時報予報音フラグ = ON か？
		goto	alarm03		;No

		call	buzzer_pu	;"プッ" ブザー音出力 (100 mS)
		goto	alarm04

alarm03	;	btfss	alm_flg,3	;時報正報音フラグ = ON か？
	;	goto	alarm04		;No

		call	buzzer_poon	;"ポッ～～ン" ブザー音出力 (1000 mS)
		bcf	PORTB,_BZ	;ブザー出力ビットを "L" にしておく	; (Ver.1.13) で追加
	;	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

					;常時に "ジー" という異音防止のため	;
		btfss	alm_flg,3	;時報正報音フラグ = ON のとき以外は	; (Ver.1.13) で追加
		bcf	PORTB,_BZ	;ブザー出力ビットを "L" にしておく	;
		return

;==========================================================================
;		ウェイト・ルーチン (8 MHz)
;==========================================================================

		; 10μ秒 ウェイトルーチン
wait_10us
		movlw	4		;1
		movwf	wt1cnt		;1
wu03		nop			;1
		decfsz	wt1cnt,F	;1,2
		goto	wu03		;2,0	1+1+(1+1+2)*3+(1+2+0)=17
		nop			;1
		return			;2	17+1+2=20
					;Total	20/8MHz*4 = 10 μS

		; 40μ秒 ウェイトルーチン
wait_40us
		movlw	15		;1
		movwf	wt1cnt		;1
wu01		goto	$+1		;2
		decfsz	wt1cnt,F	;1,2
		goto	wu01		;2,0	1+1+(2+1+2)*14+(2+2+0)=76
		goto	$+1		;2
		return			;2	76+2+2=80
					;Total	80/8MHz*4 = 40 μS

		; 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

		; 10m 秒 ウェイトルーチン
wait_10ms
		movlw	10
		goto	wait_xxms

		; 30m 秒 ウェイトルーチン
wait_30ms
		movlw	30
		goto	wait_xxms

		; 50m 秒 ウエイト
wait_50ms
		movlw	50
		goto	wait_xxms

		; 100m 秒 ウェイトルーチン
wait_100ms
		movlw	100
		goto	wait_xxms

		; 200m 秒 ウェイトルーチン
wait_200ms
		movlw	200
		goto	wait_xxms

		; 1m 秒 ウェイトルーチン
wait_1ms
		movlw	1

		; xx m 秒（ 1m 秒 x W ）ウェイトルーチン
wait_xxms
		movwf	wt2cnt		;1

w1m01		movlw	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
		goto	w1s01

		; 3 秒 ウェイトルーチン
wait_3sec
		movlw	30
w1s01		movwf	wt3cnt

w1s02		call	wait_100ms
		decfsz	wt3cnt,F
		goto	w1s02
		return

;==========================================================================
;	Message[306] Crossing page boundary -- ensure page bits are set.
;==========================================================================

xtime_display
		bsf	PCLATH,3	;Page 1
		call	time_display	;
		bcf	PCLATH,3	;Page 0
		return

xdate_display
		bsf	PCLATH,3	;Page 1
		call	date_display	;
		bcf	PCLATH,3	;Page 0
		return

xtemp_display
		bsf	PCLATH,3	;Page 1
		call	temp_display	;
		bcf	PCLATH,3	;Page 0
		return

xhumi_display
		bsf	PCLATH,3	;Page 1
		call	humi_display	;
		bcf	PCLATH,3	;Page 0
		return

xauto_display
		bsf	PCLATH,3	;Page 1
		call	auto_display	;
		bcf	PCLATH,3	;Page 0
		return

xdht22_err_display
		bsf	PCLATH,3	;Page 1
		call	dht22_err_display ;
		bcf	PCLATH,3	;Page 0
		return

xclear_memory
		bsf	PCLATH,3	;Page 1
		call	clear_memory	;
		bcf	PCLATH,3	;Page 0
		return

xdelete_memory
		bsf	PCLATH,3	;Page 1
		call	delete_memory	;
		bcf	PCLATH,3	;Page 0
		return

xread_memory
		bsf	PCLATH,3	;Page 1
		call	read_memory	;
		bcf	PCLATH,3	;Page 0
		return

xwrite_memory
		bsf	PCLATH,3	;Page 1
		call	write_memory	;
		bcf	PCLATH,3	;Page 0
		return

;;xtime_monitor									; (Ver.1.13 で削除)
;;		bsf	PCLATH,3	;Page 1
;;		call	time_monitor	;
;;		bcf	PCLATH,3	;Page 0
;;		return

xdemo_display
		bsf	PCLATH,3	;Page 1
		call	demo1_display	;
;		bsf	PCLATH,3	;Page 1
		call	demo2_display	;
		bcf	PCLATH,3	;Page 0
		return

xdxled_display
		bsf	PCLATH,3	;Page 1
		call	dxled_display	;
		bcf	PCLATH,3	;Page 0
		return

xfont_read_buff
		bsf	PCLATH,3	;Page 1
		call	font_read_buff	;
		bcf	PCLATH,3	;Page 0
		return

;=============================================================================================================
 		org	h'800'		;(Page 1)
;=============================================================================================================

xinc_bcd
		bcf	PCLATH,3	;Page 0
		call	inc_bcd		;
		bsf	PCLATH,3	;Page 1
		return

xdec_bcd
		bcf	PCLATH,3	;Page 0
		call	dec_bcd		;
		bsf	PCLATH,3	;Page 1
		return

xbindec16c_cnv
		bcf	PCLATH,3	;Page 0
		call	bindec16c_cnv	;
		bsf	PCLATH,3	;Page 1
		return

xmax_byte_send
		bcf	PCLATH,3	;Page 0
		call	max_byte_send	;
		bsf	PCLATH,3	;Page 1
		return

xwait_10ms
		bcf	PCLATH,3	;Page 0
		call	wait_10ms	;
		bsf	PCLATH,3	;Page 1
		return

xwait_30ms									; (Ver.1.13 で追加)
		bcf	PCLATH,3	;Page 0
		call	wait_30ms	;
		bsf	PCLATH,3	;Page 1
		return

xbuzzer_bubuu
		bcf	PCLATH,3	;Page 0
		call	buzzer_bubuu	;
		bsf	PCLATH,3	;Page 1
		return

;;xExpPCF8574_Write								; (Ver.1.13 で削除)
;;		bcf	PCLATH,3	;Page 0
;;		call	ExpPCF8574_Write ;
;;		bsf	PCLATH,3	;Page 1
;;		return

;==========================================================================
;		タイマー用メモリの構成
;==========================================================================

; １メモリ単位 ... (タイマー制御バイト)、(時_BCD カウンタバイト)、(分_BCD カウンタバイト)

; (タイマー制御バイト) ／ fmmwwwss

;		fmmw.wwss	fmmw.wwss	fmmw.wwss	fmmw.wwss
;		:		 ::		   : ::		       ::
;		0  メモリ無効	 00  OFF	   0 00  EDAY	       01  SW1
;		1  メモリ有効	 01  ON		   0 01  SUN	       10  SW2
;				 10  SLP OFF	   0 10  MON	       11  SW3
;				 11  SLP ON	   0 11  TUE	      (00  SW4)*
;						   1 00  WED
;						   1 01  THU
;						   1 10  FRI
;						   1 11  SAT

;								*印: 本プログラムでは使用しない

; (時_BCD カウンタバイト)

;		chhh.hhhh		chhh.hhhh	chhh.hhhh
;		:			 :::		     ::::
;		1 メモリ自動消去有効	 十時(0～2)	     時(0～9)

;					iiii.iiii	iiii.iiii
;					::::		     ::::
;				温度値の整数十位(0～9)	     一位(0～9)

; (分_BCD カウンタバイト)

;					mmmm.mmmm	mmmm.mmmm
;					::::		     ::::
;					十分(0～5)	     分(0～9)

;					dddd.1010	dddd.1010
;					::::		     ::::
;				温度値の小数一位(0～9)	     固定(℃)

;--------------------------------------------------------------------------
;		タイマー用メモリの CH(SW)別消去
;--------------------------------------------------------------------------

;	  汎用変数:	work3, lp_cnt1

clear_memory
		clrf	work3		;ワーク, 消去フラグ = OFF
		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		movlw	low timer_mem	;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1		;ループカウンタ

clmem01		btfss	INDF,7		;(タイマー制御バイト) の f bit = 1 (有効) か？
		goto	clmem02		;No

		movf	exp_flg,W
		xorwf	INDF,W		;比較する
		andlw	h'03'		;ss bit を取り出し
		btfss	STATUS,Z	;ss bit は等しい か？
		goto	clmem02		;No

		clrf	INDF		;Yes. 消去
		bsf	work3,0		;ワーク, 消去フラグ = ON

clmem02		movlw	3
		addwf	FSR,F		;間接アドレス +3 更新
		decfsz	lp_cnt1,F	;ループカウンタ - 1 = 0 か？
		goto	clmem01		;No

		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
		return

;--------------------------------------------------------------------------
;		タイマー用メモリの個別消去
;--------------------------------------------------------------------------

delete_memory
		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		movf	del_fsr,W	;消去対象のタイマー用メモリのアドレス
		movwf	FSR		;
		clrf	INDF		;タイマー制御バイトを消去
		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
		return

#ifdef comment		; (参考)
delete_memory
		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		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'		;メモリ自動消去フラグ = OFF
		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		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
		return
#endif

;--------------------------------------------------------------------------
;		タイマー用メモリの読み出し
;--------------------------------------------------------------------------

;	  汎用変数:	work1, lp_cnt1

read_memory
		; タイマー用メモリの検索

		movf	dsp_cnt,W	;表示カウンタ
		movwf	work1

		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		movlw	low timer_mem	;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1		;ループカウンタ

rdmem01		btfss	INDF,7		;fmmwwwss の f bit = 1 (有効) か？
		goto	rdmem02		;No

		movf	exp_flg,W
		xorwf	INDF,W		;比較する
		andlw	h'03'		;ss bit を取り出し
		btfss	STATUS,Z	;ss bit は等しい か？
		goto	rdmem02		;No

		movf	work1,W
		btfsc	STATUS,Z	;表示カウンタ = 0 か？
		goto	rdmem03		;Yes

		decf	work1,F		;表示カウンタ - 1

rdmem02		movlw	3
		addwf	FSR,F		;間接アドレス +3 更新
		decfsz	lp_cnt1,F	;ループカウンタ - 1 = 0 か？
		goto	rdmem01		;No

		bsf	dsp_cnt,5	;タイマー用メモリ検索終了フラグ = ON
		goto	rdmem04

		; タイマー用メモリの読み出し

rdmem03		movf	FSR,W
		movwf	del_fsr		;消去対象（となるかもしれない）タイマー用メモリアドレスを記憶
		movf	INDF,W		;
		movwf	fmmwwwss	;タイマー制御バイト
		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;
	;;	andlw	h'7f'		;メモリ自動消去フラグ = OFF
		movwf	temp_hh		;時_BCD カウンタ
		incf	FSR,F		;間接アドレス +1 更新
		movf	INDF,W		;
		movwf	temp_mm		;分_BCD カウンタ
		incf	dsp_cnt,F	;表示カウンタの更新

rdmem04		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
		return

;--------------------------------------------------------------------------
;		タイマー用メモリへの書き込み
;--------------------------------------------------------------------------

;	  汎用変数:	lp_cnt1

write_memory
		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		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'8888'

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		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
		return

;==========================================================================
;		タイマー & 温度の監視とその処理
;==========================================================================

;	  汎用変数:	work1, work2, lp_cnt1, lp_cnt2

;		tmon_flg: タイマー & 温度監視フラグ、 bit1: 温度,  bit0: タイマー

time_monitor
		movlw	h'03'
		andwf	tmon_flg,W	;
		btfsc	STATUS,Z	;タイマー監視フラグ = ON か？
		goto	tmon17		;No

		movf	bcd_ww,W	;曜日 BCD カウンタ
		movwf	cur_week	;ワーク
		bcf	STATUS,C
		rlf	cur_week,F	;WEEK カウンタ
		rlf	cur_week,F	;左に 2 ビットシフト

		bsf	STATUS,IRP	;バンク 2,3（間接アドレス指定用）
		movlw	low timer_mem	;タイマー用メモリの先頭アドレス
		movwf	FSR
		movlw	20
		movwf	lp_cnt1		;ループカウンタ

tmon01		btfss	INDF,7		;fmmwwwss の f bit = 1 (メモリ有効) か？
		goto	tmon14		;No

		movf	INDF,W
		andlw	h'1c'		;www bit を取り出す
		btfsc	STATUS,Z	;www bit = 0: EDAY か？
		goto	tmon02		;Yes

		xorwf	cur_week,W
		btfss	STATUS,Z	;WEEK カウンタは等しいか？
		goto	tmon14		;No

tmon02		movf	INDF,W
		movwf	fmmwwwss	;fmmwwwss を一旦退避
		incf	FSR,F		;間接アドレス +1 更新、(時_BCD カウンタバイト)

		btfss	tmon_flg,1	;温度監視フラグ = ON か？
		goto	tmon03		;No

		movlw	h'03'
		andwf	fmmwwwss,W	;ss bit を取り出す
		xorlw	h'03'
		btfss	STATUS,Z	;ss bit = 3 か？
		goto	tmon15		;No

		movf	INDF,W
		subwf	data_h,W
		btfss	STATUS,Z	;温度(整数)は等しいか？
		goto	tmon15		;No

		incf	FSR,F		;間接アドレス +1 更新、(分_BCD カウンタバイト)
		movf	INDF,W
		subwf	data_l,W
		btfsc	STATUS,Z	;温度(小数)は等しいか？
		goto	tmon04		;Yes
		goto	tmon16		;No

tmon03		movf	INDF,W
		andlw	h'7f'		;メモリ自動消去フラグを削除
		subwf	bcd_hh,W
		btfss	STATUS,Z	;時_BCD カウンタは等しいか？
		goto	tmon15		;No

		incf	FSR,F		;間接アドレス +1 更新、(分_BCD カウンタバイト)
		movf	INDF,W
		subwf	bcd_mm,W
		btfss	STATUS,Z	;分_BCD カウンタは等しいか？
		goto	tmon16		;No

		; WEEK, 時, 分, または 温度(整数), (小数) が等しいときの出力（リレー）制御

tmon04		movf	fmmwwwss,W
		andlw	h'03'		;ss bit を取り出す
		movwf	lp_cnt2
		movlw	h'10'
		movwf	work1		;CH(SW) 出力の初期値

tmon05		decf	lp_cnt2,F
		btfsc	STATUS,Z	;lp_cnt2 - 1 = 0 か？
		goto	tmon06		;Yes

		bcf	STATUS,C
		rlf	work1,F		;CH(SW) 出力を左に 1 ビットシフト
		goto	tmon05

tmon06		movf	exp_port,W	;
		movwf	work2		;変更前の拡張ポートのリレー制御データ

		movf	work1,W
		btfsc	fmmwwwss,5	;mm bit = x1: ON 出力 か？
		iorwf	exp_port,F	;Yes. リレーを ON
		xorlw	h'ff'
		btfss	fmmwwwss,5	;mm bit = x0: OFF 出力 か？
		andwf	exp_port,F	;Yes. リレーを OFF

		movf	exp_port,W	;拡張ポートのリレー制御データ
		movwf	exptmp		;書き込みデータ
	;;;	call	xExpPCF8574_Write ;
		bcf	PCLATH,3	;Page 0
		call	ExpPCF8574_Write ;;（PCF8574/74A）の拡張ポートへデータを書き込み
		bsf	PCLATH,3	;Page 1

		; アラームフラグの設定
		btfss	alm_flg,7	;アラーム音出力許可フラグ = ON か？
		goto	tmon08		;No

		btfsc	tmon_flg,0	;タイマー監視フラグ = ON か？
		goto	tmon07		;Yes

		movf	work2,W		;変更前のリレー制御データを
		xorwf	exp_port,W	;変更後のリレー制御データと比較
		andlw	h'40'		;CH3
		btfsc	STATUS,Z	;等しい か？
		goto	tmon16		;Yes

tmon07		btfsc	fmmwwwss,5	;mm bit = x1: ON 出力 か？
		bsf	alm_flg,0	;Yes. リレー ON フラグのセット
		btfss	fmmwwwss,5	;mm bit = x0: OFF 出力 か？
		bsf	alm_flg,1	;Yes. リレー OFF フラグのセット

tmon08		btfsc	tmon_flg,1	;温度監視フラグ = ON か？
		goto	tmon16		;Yes

		; メモリの自動消去

		decf	FSR,F		;間接アドレス -1 更新、(時_BCD カウンタバイト)
		btfss	INDF,7		;メモリ自動消去フラグ = 1 か？
		goto	tmon10		;No

		btfss	fmmwwwss,6	;mm bit = 1x: SLP か？
		goto	tmon09		;No

		btfsc	fmmwwwss,5	;mm bit = 10: OFF か？
		goto	tmon11		;No

tmon09		decf	FSR,F		;間接アドレス -1 更新、(タイマー制御バイト)
	;;	bcf	INDF,7		;f bit = 0
		clrf	INDF		;メモリの消去
		goto	tmon14		;No

		; SLP のときのメモリ内容変更

tmon10		btfss	fmmwwwss,6	;mm bit = 1x: SLP か？
		goto	tmon15		;No

tmon11		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	tmon12		;No. ON 出力

		; ON 出力時間に変更（メモリ自動消去フラグ = 1 のものはない）
		call	xdec_bcd       ;;時_BCD カウンタバイト - 1
		movlw	h'f9'		;h'00' - h'01' - h'06'
		subwf	INDF,W
		btfss	STATUS,Z	;時_BCD カウンタ = h'f9' か？
		goto	tmon15		;No

		movlw	h'23'
		movwf	INDF		;時_BCD カウンタ = h'23' 設定

		movlw	h'1c'
		andwf	fmmwwwss,F
		btfsc	STATUS,Z	;www bit = 0: EDAY か？
		goto	tmon15		;Yes

		movlw	h'04'
		subwf	fmmwwwss,F	;www bit を - 1
		btfss	STATUS,Z	;www bit = 0 か？
		goto	tmon13		;No

		movlw	h'1c'
		movwf	fmmwwwss	;www bit = 7 にする
		goto	tmon13

		; OFF 出力時間に変更
tmon12		movf	INDF,W
		movwf	work1		;時_BCD カウンタバイトを一旦退避
		bcf	INDF,7		;メモリ自動消去フラグ = 0
		call	xinc_bcd       ;;時_BCD カウンタバイト + 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	tmon15		;No

		movlw	h'1c'
		andwf	fmmwwwss,F
		btfsc	STATUS,Z	;www bit = 0: EDAY か？
		goto	tmon15		;Yes

		movlw	h'04'
		addwf	fmmwwwss,F	;www bit を + 1
		btfss	fmmwwwss,5	;www bit = 8 か？
		goto	tmon13		;No

		movlw	h'04'
		movwf	fmmwwwss	;www bit = 1 にする

		; WEEK を変更
tmon13		decf	FSR,F		;間接アドレス -1 更新、(タイマー制御バイト)
		movlw	h'e3'
		andwf	INDF,F		;www bit をクリア
		movf	fmmwwwss,W	;www bit
		iorwf	INDF,F		;新しい www bit に更新

tmon14		incf	FSR,F		;(時_BCD カウンタバイト)

tmon15		incf	FSR,F		;(分_BCD カウンタバイト)

tmon16		incf	FSR,F		;(次の タイマー制御バイト)
		decfsz	lp_cnt1,F	;ループカウンタ - 1 = 0 か？
		goto	tmon01		;No

		bcf	STATUS,IRP	;バンク 0,1（間接アドレス指定用）
		clrf	tmon_flg	;タイマー & 温度監視フラグ = OFF

tmon17		return

;==========================================================================
;		各表示モード別のマトリクス LED モジュールの表示
;==========================================================================

;--------------------------------------------------------------------------
;		モード 0： 時分秒をマトリクス LED モジュールに表示
;--------------------------------------------------------------------------

time_display
		movf	bcd_hh,W	;時 BCD カウンタ
		movwf	temp_hh

		btfsc	time_flg,1	;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		call	cnv_24to12	;Yes. 24時間表示を12時間表示に変換

		movf	bcd_mm,W	;分 BCD カウンタ
		movwf	temp_mm
		movf	bcd_ss,W	;秒 BCD カウンタ
		movwf	temp_ss

		movlw	5
		subwf	mod_flg,W
		movlw	h'fe'		;    (xx:xx:xx)表示
		btfss	STATUS,Z	;表示モードフラグ = 5 (SET モード) か？
		goto	tmdsp01		;No

		movlw	4
		subwf	tg_point,W
		movlw	h'32'		;    (__:xx:__)表示, "MH","ML" 桁
		btfsc	STATUS,Z	;対象の位置ポインタ = 4 か？
		goto	tmdsp01		;Yes

		movlw	h'c2'		;    (xx:__:__)表示, "HH","HL" 桁
		btfsc	STATUS,C	;対象の位置ポインタ < 4 か？
		movlw	h'0e'		;No. (__:__:xx)表示, "SH","SL" 桁

tmdsp01		movwf	dspdigit	;表示桁指定フラグの設定

		btfss	time_flg,1	;12H 表示 か？
		goto	tmdsp02		;No

		movlw	h'f0'
		andwf	temp_hh,W
		btfsc	STATUS,Z	;"HH" 桁 = 0 か？
		bcf	dspdigit,7	;Yes. ゼロクリア

tmdsp02		call	dxled_display	;
		return

;--------------------------------------------------------------------------
;		24時間表示を12時間表示に変換
;--------------------------------------------------------------------------

;(24H) 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 
;(12H) 12  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11
;      am am am am am am am am am am am am pm pm pm pm pm pm pm pm pm pm pm pm
;                                          -----------------------------------
;     +12                                 -12
;    ( 12 ef f0 f1 f2 f3 f4 f5 f6 f7 fe ff 00 01 02 03 04 05 06 07 0e 0f 10 11 )

cnv_24to12
		; (am)
		bcf	time_flg,0	;時間表示モードフラグ.bit0=0: am に設定

		movf	temp_hh,W
		btfss	STATUS,Z	;仮の時 BCD カウンタ = h'00' か？
		goto	cnv01		;No

		movlw	h'12'
		movwf	temp_hh		;仮の時 BCD カウンタ temp_hh = h'12'
		goto	cnv02

cnv01		movlw	h'12'
		subwf	temp_hh,W
		btfss	STATUS,C	;仮の時 BCD カウンタ < h'12' か？
		goto	cnv02		;Yes

		; (pm)
		bsf	time_flg,0	;時間表示モードフラグ.bit0=1: pm に設定

		btfsc	STATUS,Z	;仮の時 BCD カウンタ = h'12' か？
		goto	cnv02		;Yes

		movwf	temp_hh		;仮の時 BCD カウンタ temp_hh = temp_hh - 12
		movlw	h'0e'
		subwf	temp_hh,W
		btfss	STATUS,C	;仮の時 BCD カウンタ < h'0e' か？
		goto	cnv02		;Yes

		movlw	h'10'
		subwf	temp_hh,W
		btfsc	STATUS,C	;仮の時 BCD カウンタ < h'10' か？
		goto	cnv02		;No

		movlw	h'06'
		subwf	temp_hh,F	;補正

cnv02		return

;--------------------------------------------------------------------------
;	モード 1： 年月日（曜日）をマトリクス LED モジュールに表示
;--------------------------------------------------------------------------

date_display
		btfsc	int_flg,1	;12時間表示時の AM/PM 表示点滅タイミング
		goto	ddsp01		;Yes

		movf	bcd_yy,W	;年 BCD カウンタ
		movwf	temp_hh
		movf	bcd_nn,W	;月 BCD カウンタ
		movwf	temp_mm
		movf	bcd_dd,W	;日 BCD カウンタ
		movwf	temp_ss

		movlw	5
		subwf	mod_flg,W
		movlw	h'fd'		;    (xx.xx.xx)表示
		btfss	STATUS,Z	;表示モードフラグ = 5 (SET モード) か？
		goto	ddsp02		;No

		movlw	1
		subwf	tg_point,W
		movlw	h'31'		;    (__.xx.__)表示, "MH","ML" 桁
		btfsc	STATUS,Z	;対象の位置ポインタ = 1 か？
		goto	ddsp02		;Yes

		movlw	h'c1'		;    (xx.__.__)表示, "HH","HL" 桁
		btfsc	STATUS,C	;対象の位置ポインタ < 1 か？
		movlw	h'0d'		;No. (__.__.xx)表示, "SH","SL" 桁
		goto	ddsp02

ddsp01		movlw	1
		movwf	tbl_type	;フォントデータテーブルの種類 = 1 を指定

		movlw	h'0e'		;" ("
		movwf	temp_hh
		decf	bcd_ww,W	;曜日 BCD カウンタ
	;;	call	week_table	;曜日データのテーブル読み出し

		movwf	addr_low
		movlw	high week_table
		movwf	addr_high	;先頭 high アドレス
		movlw	low week_table
		addwf	addr_low,F	;先頭 low アドレス
		btfsc	STATUS,C	;オーバーフローした場合は
		incf	addr_high,F	;high アドレスの更新
		call	font_read	;曜日データの読み出し
		movwf	temp_mm
		movlw	high $		;この場所の high アドレスを
		movwf	PCLATH		;PCLATH に設定

		movlw	h'f0'		;") "
		movwf	temp_ss
		movlw	h'78'		;(_x xx x_)表示

ddsp02		movwf	dspdigit	;表示桁指定フラグの設定
		call	dxled_display	;
	 	clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		return

		; 曜日データのテーブル読み出し
week_table
	;;	addwf	PCL,F		;プログラム・カウンタに加算

		retlw	h'01'		;Day = 1, "SUN"
		retlw	h'23'		;      2, "MON"
		retlw	h'45'		;      3, "TUE"
		retlw	h'67'		;      4, "WED"
		retlw	h'89'		;      5, "THU"
		retlw	h'ab'		;      6, "FRI"
		retlw	h'cd'		;      7, "SAT"

;--------------------------------------------------------------------------
;		モード 2： 温度をマトリクス LED モジュールに表示
;--------------------------------------------------------------------------

temp_display
		movf	temperature_h,W	;温度上位 8 bit
		andlw	h'7f'
		movwf	data_h
		movf	temperature_l,W	;温度下位 8 bit
		movwf	data_l
		call	xbindec16c_cnv ;;16 ビット数値を 10進数 5桁の文字列に変換

		clrf	temp_hh
		movlw	b'00111101'	;(_- xx.xC)表示
		movwf	dspdigit	;表示桁指定フラグの設定

		btfss	temperature_h,7	;マイナスの温度 か？
		goto	tdsp01		;No

		movlw	h'0e'		;'-'
		movwf	temp_hh		;"HL" 桁
		bsf	dspdigit,6

tdsp01		clrf	temp_mm
		movlw	'0'
		subwf	buff2,W
		btfsc	STATUS,Z	;buff2 = '0' か？
		goto	tdsp02		;Yes

	;	movlw	h'0f'		;
	;	andwf	buff2,W		;
		movwf	temp_mm
		swapf	temp_mm,F	;"MH" 桁
		bsf	dspdigit,5

tdsp02		movlw	h'0f'		;
		andwf	buff3,W		;
		iorwf	temp_mm,F	;"ML" 桁

		movlw	h'0f'		;
		andwf	buff4,W		;
		movwf	temp_ss
		swapf	temp_ss,F	;"SH" 桁

		movlw	h'0a'		;℃
		iorwf	temp_ss,F	;"SL" 桁

		call	dxled_display	;
		return

;--------------------------------------------------------------------------
;		モード 3： 湿度をマトリクス LED モジュールに表示
;--------------------------------------------------------------------------

humi_display
		movf	humidity_h,W	;湿度上位 8 bit
		movwf	data_h
		movf	humidity_l,W	;湿度下位 8 bit
		movwf	data_l
		call	xbindec16c_cnv ;;16 ビット数値を 10進数 5桁の文字列に変換

		clrf	temp_hh
		movlw	b'00011101'	;(_x xx.x%)表示
		movwf	dspdigit	;表示桁指定フラグの設定

		movlw	'0'
		subwf	buff1,W
		btfsc	STATUS,Z	;buff1 = '0' か？
		goto	hdsp01		;Yes

		movwf	temp_hh		;"HL" 桁
		bsf	dspdigit,6

hdsp01		clrf	temp_mm
		movlw	'0'
		subwf	buff2,W
		btfsc	STATUS,Z	;buff2 = '0' か？
		goto	hdsp02		;Yes

		movwf	temp_mm
		swapf	temp_mm,F	;"MH" 桁
		bsf	dspdigit,5

hdsp02		movlw	h'0f'		;
		andwf	buff3,W		;
		iorwf	temp_mm,F	;"ML" 桁

		movlw	h'0f'		;
		andwf	buff4,W		;
		movwf	temp_ss
		swapf	temp_ss,F	;"SH" 桁

		movlw	h'0b'		;%
		iorwf	temp_ss,F	;"SL" 桁

		call	dxled_display	;
		return

;--------------------------------------------------------------------------
;	モード 4： オートモード時のマトリクス LED モジュールの表示
;--------------------------------------------------------------------------

;		 (___: 時間表示、NNN: 年月日表示、OOO: 温度表示、SSS: 湿度表示)

;		00        10        20        30        40        50        00
;		.    .    .    .    .    .    .    .    .    .    .    .    .
;		_____NNNNNNNNNN__________OOOOOOOOOO__________SSSSSSSSSS_____

auto_display
		movlw	h'05'		;
		subwf	bcd_ss,W	;秒 BCD カウンタ
		btfss	STATUS,C	;bcd_ss < h'05' か？
		goto	adsp03		;Yes

		movlw	h'15'		;
		subwf	bcd_ss,W	;秒 BCD カウンタ
		btfsc	STATUS,C	;bcd_ss < h'15' か？
		goto	adsp01		;No

		call	date_display	;Yes. 年月日の表示
		goto	adsp04

adsp01		movlw	h'25'		;
		subwf	bcd_ss,W	;秒 BCD カウンタ
		btfss	STATUS,C	;bcd_ss < h'25' か？
		goto	adsp03		;Yes

		movlw	h'35'		;
		subwf	bcd_ss,W	;秒 BCD カウンタ
		btfsc	STATUS,C	;bcd_ss < h'35' か？
		goto	adsp02		;No

		call	temp_display	;Yes. 温度の表示
		goto	adsp04

adsp02		movlw	h'45'		;
		subwf	bcd_ss,W	;秒 BCD カウンタ
		btfss	STATUS,C	;bcd_ss < h'45' か？
		goto	adsp03		;Yes

		movlw	h'55'		;
		subwf	bcd_ss,W	;秒 BCD カウンタ
		btfsc	STATUS,C	;bcd_ss < h'55' か？
		goto	adsp03		;No

		call	humi_display	;Yes. 湿度の表示
		goto	adsp04

adsp03		call	time_display	;Yes. 時分秒の表示

adsp04		return

;--------------------------------------------------------------------------
;		DHT22 から読み出しエラーの表示
;--------------------------------------------------------------------------

dht22_err_display
		movlw	2
		movwf	tbl_type	;フォントデータテーブルの種類 = 2 を指定
		btfss	time_cnt,7	;タイムアウトエラー か？
		goto	erdsp01		;No. チェックサム(CRC)エラー

;		[ Err. DHT22 TO ]	;DHT22 TO エラーメッセージ

		movlw	h'34'		;"Err."
		movwf	temp_hh
		movlw	h'9a'		;"DHT"
		movwf	temp_mm
		movlw	h'bc'		;"22","TO"
		movwf	temp_ss
		goto	erdsp02

;		[ Err. DHT22 PE ]	;DHT22 PE エラーメッセージ

erdsp01		movlw	h'34'		;"Err."
		movwf	temp_hh
		movlw	h'9a'		;"DHT"
		movwf	temp_mm
		movlw	h'bd'		;"22","PE"
		movwf	temp_ss

erdsp02		movlw	h'fc'		;(xx_xx_xx)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	dxled_display	;ドットマトリクス LED の表示
		call	xbuzzer_bubuu  ;;"ブッブー" ブザー音出力
		clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		return

;==========================================================================
;		ドットマトリクス LED ６桁分の表示
;==========================================================================

;	  汎用変数:	mlpcnt1, mlpcnt2

dxled_display
	;;	call	font_read6_buff	;文字フォントデータの６桁分の読み出し
		goto	font_read6_buff	;** スタック改善のため: call → goto **

dxdsp00		movf	mod_cnt,W
		btfsc	STATUS,Z	;モードNo表示時間カウンタ = 0 か？
		goto	dxdsp02		;Yes

		; バッファ "HH" 桁をモードNoに置き換え

		movlw	fd_buff		;フォントデータ格納バッファ "HH" 桁の先頭アドレス
		movwf	FSR		;間接アドレスの先頭番地
		movlw	8		;
		movwf	mlpcnt2		;ループカウンタにセット

dxdsp01		incf	mod_flg,W
		subwf	mlpcnt2,W	;Z フラグだけが必要
		movlw	h'00'		;h'00'
		btfsc	STATUS,Z	;ループカウンタ = mod_flg + 1 か？
		movlw	h'ff'		;Yes
		movwf	INDF		;バッファ "HH" 桁を置き換え
		incf	FSR,F		;間接アドレス +1 更新
		decfsz	mlpcnt2,F	;ループカウンタ - 1 = 0 か？
		goto	dxdsp01		;No

		; フォントデータを６桁分表示

dxdsp02		movlw	fd_buff + 8 * 5	;フォントデータ格納バッファ"SL" 桁の先頭アドレス
		movwf	FSR		;間接アドレスの先頭番地
		movwf	fsr_mem		;フォントデータバッファのアドレス記憶

		movlw	h'08'		;Digit = 7
		movwf	digit		;Digit の初期値

dxdsp03		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movlw	6		;
		movwf	mlpcnt1		;ループカウンタにセット

dxdsp04		movf	digit,W		;Digit = X
		call	xmax_byte_send ;;レジスタアドレス
		movf	INDF,W		;バッファから読み出し
		call	xmax_byte_send ;;レジスタデータ

		movlw	8
		subwf	FSR,F		;間接アドレスを１つ前の桁
		decfsz	mlpcnt1,F	;6桁分表示した か？
		goto	dxdsp04		;No

		bsf	PORTC,maxLOAD	;maxLOAD="H"
		incf	fsr_mem,F	;バッファアドレスの記憶更新
		movf	fsr_mem,W
		movwf	FSR		;間接アドレス +1 更新
		decfsz	digit,F		;全 Digit 表示した か？
		goto	dxdsp03		;No

		; :("Colon") / .("Period") の LED表示

		; PC7, PC6, PC5, PC4, PC3, PC2, PC1, PC0  ... （ポート番号）
		; LU,  LL,  RU,  RL,  SW5, CLK, LOAD,DIN  ... （信号名）

		movlw	h'07'
		andwf	PORTC,F		;下位 3bit だけをそのまま残す

		btfss	dspdigit,1	;表示桁指定フラグ.1 ("Colon") = ON か？
		goto	dxdsp06		;No

		; :("Colon") の LED表示
		movlw	h'c0'		;:("Colon")指定,  (LU, LL, xx, xx)
		btfsc	exp_flg,7	;メモリの内容表示フラグ = ON か？
		goto	dxdsp08		;Yes

		movlw	h'f0'		;:("Colon")指定,  (RL, RU, LL, LU)
		btfss	time_flg,1	;12時間表示 か？
		goto	dxdsp08		;No

		movlw	5
		subwf	mod_flg,W
		btfss	STATUS,Z	;MODEフラグ = 5(SET モード) か？
		goto	dxdsp05		;No

		movlw	h'b0'		;am指定, :("Colon")左列上側 + 右列上下 LED点灯,  (LU, xx, RU, RL)
		btfss	time_flg,1	;pm表示 か？
		goto	dxdsp08		;No

		movlw	h'70'		;pm指定, :("Colon")左列下側 + 右列上下 LED点灯,  (xx, LL, RU, RL)
		goto	dxdsp08

dxdsp05		movlw	h'f0'		;:("Colon")指定,  (RL, RU, LL, LU)
		btfss	int_flg,1	;12時間表示時の AM/PM 表示点滅タイミング
		goto	dxdsp08		;No

		movlw	h'70'		;am指定, :("Colon")左列上側 LED点滅,  (xx, LL, RU, RL)
		btfss	time_flg,0	;pm表示 か？
		goto	dxdsp08		;No

		movlw	h'b0'		;pm指定, :("Colon")左列下側 LED点滅,  (LU, xx, RU, RL)
		goto	dxdsp08

		; .("Period") の LED表示
dxdsp06		movlw	h'00'		;無表示指定,  (xx, xx, xx, xx)
		btfss	dspdigit,0	;表示桁指定フラグ.0 ("Period") = ON か？
		goto	dxdsp08		;No. 無表示

		movlw	5
		subwf	mod_flg,W
		btfsc	STATUS,Z	;MODEフラグ = 5(SET モード) か？
		goto	dxdsp07		;Yes

		movlw	h'40'		;.("Period")指定,  (xx, LL, xx, xx)
		btfsc	exp_flg,7	;メモリの内容表示フラグ = ON か？
		goto	dxdsp08		;Yes

;		movlw	h'40'		; 左. ("Period")指定,  (xx, LL, xx, xx)
;		btfss	dspdigit,3	;表示桁指定フラグ.3 ("SH") = ON か？
;		goto	dxdsp08		;No

		movlw	h'10'		; 右 .("Period")指定,  (xx, xx, xx, RL)
		btfss	dspdigit,6	;表示桁指定フラグ.6 ("HL") = ON か？
		goto	dxdsp08		;No.                                    ... 気温(__ xx.x℃), 湿度(__ xx.x％)

dxdsp07		movlw	h'50'		; 両..("Period")指定,  (xx, LL, xx, RL) ... 年月日(xx.xx.xx), Ver(xx._x.xx)

dxdsp08		xorlw	h'f0'		;ビット反転
		iorwf	PORTC,F		;
		return

;==========================================================================
;		文字フォントデータの６桁分の読み出し
;==========================================================================

;		入力	dspdigit: (xx:xx:xx)
;				  bit7: "HH" 桁の指定
;				  bit6: "HL" 桁の指定
;				  bit5: "MH" 桁の指定
;				  bit4: "ML" 桁の指定
;				  bit3: "SH" 桁の指定
;				  bit2: "SL" 桁の指定
;				  bit1: :("Colon") の指定
;				  bit0: .("Period")の指定

;			temp_hh: 仮の時 BCD カウンタ
;			temp_mm: 仮の分 BCD カウンタ
;			temp_ss: 仮の秒 BCD カウンタ

;		出力:	fd_buff(8 x 6 = 48 byte): フォントデータ

font_read6_buff
		movlw	fd_buff		;フォントデータ格納バッファの先頭アドレス
		movwf	FSR		;間接アドレスの先頭番地

		btfss	dspdigit,7	;"HH" 桁 = 1 か？
		goto	fr6buf01	;No

		swapf	temp_hh,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf02

fr6buf01	call	zero_clear	;ゼロクリア

fr6buf02	btfss	dspdigit,6	;"HL" 桁 = 1 か？
		goto	fr6buf03	;No

		movf	temp_hh,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf04

fr6buf03	call	zero_clear	;ゼロクリア

fr6buf04	btfss	dspdigit,5	;"MH" 桁 = 1 か？
		goto	fr6buf05	;No

		swapf	temp_mm,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf06

fr6buf05	call	zero_clear	;ゼロクリア

fr6buf06	btfss	dspdigit,4	;"ML" 桁 = 1 か？
		goto	fr6buf07	;No

		movf	temp_mm,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf08

fr6buf07	call	zero_clear	;ゼロクリア

fr6buf08	btfss	dspdigit,3	;"SH" 桁 = 1 か？
		goto	fr6buf09	;No

		swapf	temp_ss,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf10

fr6buf09	call	zero_clear	;ゼロクリア

fr6buf10	btfsc	intensity,7	;輝度更新フラグ = ON か？		; (Ver.1.13) で追加
		clrf	tbl_type	;Yes. テーブルの種類 = 0 を強制指定	;

		btfss	dspdigit,2	;"SL" 桁 = 1 か？
		goto	fr6buf11	;No

		movf	temp_ss,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf12

fr6buf11	call	zero_clear	;ゼロクリア

fr6buf12 ;;	return
		goto	dxdsp00		;** スタック改善のため: return → goto **

;--------------------------------------------------------------------------

		; ゼロクリア

zero_clear
		movlw	8
		movwf	lp_cnt2		;ループカウンタ

zclr01		clrw
		movwf	INDF		;バッファへ格納
		incf	FSR,F		;間接アドレス +1 更新
		decfsz	lp_cnt2,F	;ループカウンタ - 1 = 0 か？
		goto	zclr01		;No

		return

;--------------------------------------------------------------------------
;   １文字フォントデータパタンの読み出しとビット列の反転後バッファへ格納
;   ( フォントデータ segment のビット列並びを逆に変換してバッファへ格納 )
;--------------------------------------------------------------------------

;	  汎用変数:	work1, work2, lp_cnt1, lp_cnt2

;	  入力:	　             W: 表示文字データ (h'x0'～h'x9', h'xa'～h'xf')
;			tbl_type: フォントデータテーブルの種類 (0/1/2/3)

;	  出力:	 fd_buff(8 byte): フォントデータ（ビット列並びを逆に変換）

;	(例)	movlw	fd_buff		;フォントデータ格納バッファの先頭アドレス
;		movwf	FSR		;間接アドレスに設定

font_read_buff
		andlw	h'0f'		;下位4ビットを取り出す
		movwf	addr_low
		bcf	STATUS,C
		rlf	addr_low,F	;8倍する
		rlf	addr_low,F
		rlf	addr_low,F

		movf	tbl_type,W
		btfss	STATUS,Z	;フォントデータテーブルの種類 = 0 か？
		goto	frbuf01		;No

		movlw	high font_data_tbl_0
		movwf	addr_high	;文字フォントデータの先頭 high アドレス
		movlw	low font_data_tbl_0
		goto	frbuf04

frbuf01		movwf	work1		;ワーク
		decf	work1,F
		btfss	STATUS,Z	;フォントデータテーブルの種類 = 1 か？
		goto	frbuf02		;No

		movlw	high font_data_tbl_1
		movwf	addr_high	;文字フォントデータの先頭 high アドレス
		movlw	low font_data_tbl_1
		goto	frbuf04

frbuf02		decf	work1,F
		btfss	STATUS,Z	;フォントデータテーブルの種類 = 2 か？
		goto	frbuf03		;No

		movlw	high font_data_tbl_2
		movwf	addr_high	;文字フォントデータの先頭 high アドレス
		movlw	low font_data_tbl_2
		goto	frbuf04

frbuf03	;	decf	work1,F
	;	btfss	STATUS,Z	;フォントデータテーブルの種類 = 3 か？
	;	goto	frbuf0x		;No

		movlw	high font_data_tbl_3
		movwf	addr_high	;文字フォントデータの先頭 high アドレス
		movlw	low font_data_tbl_3

frbuf04		addwf	addr_low,F	;文字フォントデータの先頭 low アドレス
		btfsc	STATUS,C	;オーバーフローした場合は
		incf	addr_high,F	;文字フォントデータ high アドレスの更新

		movlw	8		;
		movwf	lp_cnt2		;ループカウンタ2（digit カウンタ）

frbuf05		call	font_read	;文字フォントデータの読み出し
		movwf	work1		;反転前のビット列

		movlw	high $		;この場所の high アドレスを
		movwf	PCLATH		;PCLATH に設定
		movlw	8		;
		movwf	lp_cnt1		;ループカウンタ1（segment カウンタ）	

frbuf06		rlf	work1,F		;C bit を出力
		rrf	work2,F		;C bit を入力
		decfsz	lp_cnt1,F	;ループカウンタ1 - 1 = 0 か？
		goto	frbuf06		;No

		movf	work2,W		;反転後のビット列
		movwf	INDF		;バッファへ格納
		incf	FSR,F		;間接アドレス +1 更新

		incf	addr_low,F	;文字フォントデータ low アドレスの更新
		btfsc	STATUS,Z	;オーバーフローした場合は
		incf	addr_high,F	;文字フォントデータ high アドレスの更新
		decfsz	lp_cnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	frbuf05		;No

		return

;--------------------------------------------------------------------------
;		文字フォントデータの読み出し
;--------------------------------------------------------------------------

		; 入力:	addr_high: 文字フォントデータ high アドレス
		;	addr_low:  文字フォントデータ low アドレス
		; 出力:	W: 文字フォントデータ

font_read
		movf	addr_high,W	;文字フォントデータの high アドレス
		movwf	PCLATH
		movf	addr_low,W	;文字フォントデータの low アドレス
		movwf	PCL
																																																																						
;==========================================================================
;		文字フォントデータテーブル
;==========================================================================

font_data_tbl_0
		retlw	b'01111100'	;00: 0
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01111100'

		retlw	b'00011000'	;01: 1
		retlw	b'00111000'
		retlw	b'00011000'
		retlw	b'00011000'
		retlw	b'00011000'
		retlw	b'00011000'
		retlw	b'00011000'
		retlw	b'00111100'

		retlw	b'01111100'	;02: 2
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'00001100'
		retlw	b'00011000'
		retlw	b'00110000'
		retlw	b'01100000'
		retlw	b'11111110'

		retlw	b'01111100'	;03: 3
		retlw	b'11000110'
		retlw	b'00001100'
		retlw	b'00111000'
		retlw	b'00001100'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01111100'

		retlw	b'00011000'	;04: 4
		retlw	b'00111000'
		retlw	b'01011000'
		retlw	b'11011000'
		retlw	b'11011000'
		retlw	b'11111110'
		retlw	b'00011000'
		retlw	b'00011000'

		retlw	b'11111100'	;05: 5
		retlw	b'11000000'
		retlw	b'11000000'
		retlw	b'11111100'
		retlw	b'00000110'
		retlw	b'00000110'
		retlw	b'11000110'
		retlw	b'01111100'

		retlw	b'01111100'	;06: 6
		retlw	b'11000110'
		retlw	b'11000000'
		retlw	b'11111100'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01111100'

		retlw	b'11111110'	;07: 7
		retlw	b'11000110'
		retlw	b'00000110'
		retlw	b'00001100'
		retlw	b'00011000'
		retlw	b'00110000'
		retlw	b'00110000'
		retlw	b'00110000'

		retlw	b'01111100'	;08: 8
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01111100'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01111100'

		retlw	b'01111100'	;09: 9
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01111110'
		retlw	b'00000110'
		retlw	b'11000110'
		retlw	b'01111100'

		retlw	b'11001110'	;0a: ℃
		retlw	b'11010001'
		retlw	b'00110000'
		retlw	b'00110000'
		retlw	b'00110000'
		retlw	b'00110000'
		retlw	b'00110001'
		retlw	b'00011110'

		retlw	b'11100010'	;0b: %
		retlw	b'10100100'
		retlw	b'11101000'
		retlw	b'00010000'
		retlw	b'00010000'
		retlw	b'00101110'
		retlw	b'01001010'
		retlw	b'10001110'

		retlw	b'11000110'	;0c: V
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'11000110'
		retlw	b'01101100'
		retlw	b'00111000'
		retlw	b'00010000'

		retlw	b'00000000'	;0d: er
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'01100101'
		retlw	b'10010110'
		retlw	b'11110100'
		retlw	b'10000100'
		retlw	b'01100100'

		retlw	b'00000000'	;0e: -
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'11111110'
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'00000000'

;--------------------------------------------------------------------------

font_data_tbl_1
		retlw	b'00000000'	;00: "SUN"
		retlw	b'01100100'
		retlw	b'10010100'
		retlw	b'10000100'
		retlw	b'01100100'
		retlw	b'00010100'
		retlw	b'00010100'
		retlw	b'11100011'

		retlw	b'00000000'	;01:
		retlw	b'10100010'
		retlw	b'10100010'
		retlw	b'10110010'
		retlw	b'10101010'
		retlw	b'10100110'
		retlw	b'10100010'
		retlw	b'00100010'

		retlw	b'00000000'	;02: "MON"
		retlw	b'10001001'
		retlw	b'11011010'
		retlw	b'10101010'
		retlw	b'10101010'
		retlw	b'10001010'
		retlw	b'10001010'
		retlw	b'10001001'

		retlw	b'00000000'	;03:
		retlw	b'10010001'
		retlw	b'01010001'
		retlw	b'01011001'
		retlw	b'01010101'
		retlw	b'01010011'
		retlw	b'01010001'
		retlw	b'10010001'

		retlw	b'00000000'	;04: "TUE"
		retlw	b'11111010'
		retlw	b'00100010'
		retlw	b'00100010'
		retlw	b'00100010'
		retlw	b'00100010'
		retlw	b'00100010'
		retlw	b'00100001'

		retlw	b'00000000'	;05:
		retlw	b'01011110'
		retlw	b'01010000'
		retlw	b'01010000'
		retlw	b'01011100'
		retlw	b'01010000'
		retlw	b'01010000'
		retlw	b'10011110'

		retlw	b'00000000'	;06: "WED"
		retlw	b'10001011'
		retlw	b'10001010'
		retlw	b'10001010'
		retlw	b'10101011'
		retlw	b'10101010'
		retlw	b'10101010'
		retlw	b'01010011'

		retlw	b'00000000'	;07:
		retlw	b'11011100'
		retlw	b'00010010'
		retlw	b'00010010'
		retlw	b'10010010'
		retlw	b'00010010'
		retlw	b'00010010'
		retlw	b'11011100'

		retlw	b'00000000'	;08: "THU"
		retlw	b'11111010'
		retlw	b'00100010'
		retlw	b'00100010'
		retlw	b'00100011'
		retlw	b'00100010'
		retlw	b'00100010'
		retlw	b'00100010'

		retlw	b'00000000'	;09:
		retlw	b'01010010'
		retlw	b'01010010'
		retlw	b'01010010'
		retlw	b'11010010'
		retlw	b'01010010'
		retlw	b'01010010'
		retlw	b'01001100'

		retlw	b'00000000'	;0a: ""FRI"
		retlw	b'01111011'
		retlw	b'01000010'
		retlw	b'01000010'
		retlw	b'01110011'
		retlw	b'01000010'
		retlw	b'01000010'
		retlw	b'01000010'

		retlw	b'00000000'	;0b:
		retlw	b'10011100'
		retlw	b'01001000'
		retlw	b'01001000'
		retlw	b'10001000'
		retlw	b'01001000'
		retlw	b'01001000'
		retlw	b'01011100'

		retlw	b'00000000'	;0c: "SAT"
		retlw	b'01100011'
		retlw	b'10010100'
		retlw	b'10000100'
		retlw	b'01100100'
		retlw	b'00010111'
		retlw	b'00010100'
		retlw	b'11100100'

		retlw	b'00000000'	;0d:
		retlw	b'00111110'
		retlw	b'10001000'
		retlw	b'10001000'
		retlw	b'10001000'
		retlw	b'10001000'
		retlw	b'10001000'
		retlw	b'10001000'

		retlw	b'00000000'	;0e: " ("
		retlw	b'00000010'
		retlw	b'00000100'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00000100'
		retlw	b'00000010'

		retlw	b'00000000'	;0f: ") "
		retlw	b'10000000'
		retlw	b'01000000'
		retlw	b'00100000'
		retlw	b'00100000'
		retlw	b'00100000'
		retlw	b'01000000'
		retlw	b'10000000'

;--------------------------------------------------------------------------

font_data_tbl_2
		retlw	b'00000000'	;00: "SET"
		retlw	b'01100111'
		retlw	b'10010100'
		retlw	b'10000100'
		retlw	b'01100111'
		retlw	b'00010100'
		retlw	b'00010100'
		retlw	b'11100111'

		retlw	b'00000000'	;01:
		retlw	b'10111110'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'10001000'

		retlw	b'00000000'	;02: *
		retlw	b'00000000'
		retlw	b'00010000'
		retlw	b'01010100'
		retlw	b'00111000'
		retlw	b'01010100'
		retlw	b'00010000'
		retlw	b'00000000'

		retlw	b'00000000'	;03: "Err."
		retlw	b'11110000'
		retlw	b'10000000'
		retlw	b'10000101'
		retlw	b'11100110'
		retlw	b'10000100'
		retlw	b'10000100'
		retlw	b'11110100'

		retlw	b'00000000'	;04: 
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'10101100'
		retlw	b'00110000'
		retlw	b'00100000'
		retlw	b'00100000'
		retlw	b'00100001'

		retlw	b'00000000'	;05: "DS"
		retlw	b'00000001'
		retlw	b'00000001'
		retlw	b'00000001'
		retlw	b'00000001'
		retlw	b'00000001'
		retlw	b'00000001'
		retlw	b'00000001'

		retlw	b'00000000'	;06: 
		retlw	b'11000110'
		retlw	b'00101001'
		retlw	b'00101000'
		retlw	b'00100110'
		retlw	b'00100001'
		retlw	b'00100001'
		retlw	b'11001110'

		retlw	b'00000000'	;07: "32"
		retlw	b'01100110'
		retlw	b'10011001'
		retlw	b'00010001'
		retlw	b'00100010'
		retlw	b'00010100'
		retlw	b'10011000'
		retlw	b'01101111'

		retlw	b'00000000'	;08: "31"
		retlw	b'01100010'
		retlw	b'10010110'
		retlw	b'00010010'
		retlw	b'00100010'
		retlw	b'00010010'
		retlw	b'10010010'
		retlw	b'01100111'

		retlw	b'00000000'	;09: "DHT"
		retlw	b'01110010'
		retlw	b'01001010'
		retlw	b'01001010'
		retlw	b'01001011'
		retlw	b'01001010'
		retlw	b'01001010'
		retlw	b'01110010'

		retlw	b'00000000'	;0a: 
		retlw	b'01011111'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'11000100'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'01000100'

		retlw	b'00000000'	;0b: "22"
		retlw	b'01100110'
		retlw	b'10011001'
		retlw	b'00010001'
		retlw	b'00100010'
		retlw	b'01000100'
		retlw	b'10001000'
		retlw	b'11111111'

		retlw	b'00000000'	;0c: "TO"
		retlw	b'11100110'
		retlw	b'01001001'
		retlw	b'01001001'
		retlw	b'01001001'
		retlw	b'01001001'
		retlw	b'01001001'
		retlw	b'01000110'

		retlw	b'00000000'	;0d: "PE"
		retlw	b'11001111'
		retlw	b'10101000'
		retlw	b'10101000'
		retlw	b'11001110'
		retlw	b'10001000'
		retlw	b'10001000'
		retlw	b'10001111'

		retlw	b'00000000'	;0e: "MEM"
		retlw	b'10001011'
		retlw	b'11011010'
		retlw	b'10101010'
		retlw	b'10101011'
		retlw	b'10001010'
		retlw	b'10001010'
		retlw	b'10001011'

		retlw	b'00000000'	;0f:
		retlw	b'11010001'
		retlw	b'00011011'
		retlw	b'00010101'
		retlw	b'10010101'
		retlw	b'00010001'
		retlw	b'00010001'
		retlw	b'11010001'

;--------------------------------------------------------------------------

font_data_tbl_3

		retlw	b'00000000'	;00: "CH"
		retlw	b'00110010'
		retlw	b'01001010'
		retlw	b'01000010'
		retlw	b'01000011'
		retlw	b'01000010'
		retlw	b'01001010'
		retlw	b'00110010'

		retlw	b'00000000'	;01: "H1"
		retlw	b'01000100'
		retlw	b'01001100'
		retlw	b'01000100'
		retlw	b'11000100'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'01001110'

		retlw	b'00000000'	;02: "H2"
		retlw	b'01001100'
		retlw	b'01010010'
		retlw	b'01000010'
		retlw	b'11000100'
		retlw	b'01001000'
		retlw	b'01010000'
		retlw	b'01011110'

		retlw	b'00000000'	;03: "H3"
		retlw	b'01001100'
		retlw	b'01010010'
		retlw	b'01000010'
		retlw	b'11000100'
		retlw	b'01000010'
		retlw	b'01010010'
		retlw	b'01001100'

		retlw	b'00000000'	;04: "CLR"
		retlw	b'00110010'
		retlw	b'01001010'
		retlw	b'01000010'
		retlw	b'01000010'
		retlw	b'01000010'
		retlw	b'01001010'
		retlw	b'00110011'

		retlw	b'00000000'	;05:
		retlw	b'00011100'
		retlw	b'00010010'
		retlw	b'00010010'
		retlw	b'00011100'
		retlw	b'00010010'
		retlw	b'00010010'
		retlw	b'11010010'

		retlw	b'00000000'	;06: "NOT"
		retlw	b'10001001'
		retlw	b'10001010'
		retlw	b'11001010'
		retlw	b'10101010'
		retlw	b'10011010'
		retlw	b'10001010'
		retlw	b'10001001'

		retlw	b'00000000'	;07:
		retlw	b'10011111'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'01000100'
		retlw	b'10000100'

		retlw	b'00000000'	;08: "Bri."		;以下 (Ver.1.13) で追加
		retlw	b'01110000'
		retlw	b'01001000'
		retlw	b'01001010'
		retlw	b'01110011'
		retlw	b'01001010'
		retlw	b'01001010'
		retlw	b'01110010'

		retlw	b'00000000'	;09:
		retlw	b'00001000'
		retlw	b'00000000'
		retlw	b'11011000'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00001000'
		retlw	b'00011101'

		retlw	b'00000000'	;0a: "Lev"
		retlw	b'10000000'
		retlw	b'10000000'
		retlw	b'10000011'
		retlw	b'10000100'
		retlw	b'10000111'
		retlw	b'10000100'
		retlw	b'11110011'

		retlw	b'00000000'	;0b:
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'00100010'
		retlw	b'10100010'
		retlw	b'10100010'
		retlw	b'00010100'
		retlw	b'00001000'

		retlw	b'00000000'	;0c: "="
		retlw	b'00000000'
		retlw	b'00000000'
		retlw	b'00111000'
		retlw	b'00000000'
		retlw	b'00111000'
		retlw	b'00000000'
		retlw	b'00000000'

;==========================================================================
;		輝度調節機能の追加 ... (Ver.1.13) で追加
;==========================================================================

;	     (1)            (2)           (3)               (4)               (5)              (6)
;	main → zero_switch → bright_adj → dxled_display  → xmax_byte_send → max_byte_send → interrupt
;					 (font_read6_buff)  → font_read_buff → font_read     → 
;					  → max_led_contr  → max_byte_send  → 
;					  → z_up_switch    → xwait_30ms     → wait_30ms     → 

		; intensity		;bit7: 輝度更新フラグ, bit3-0: 輝度調節値 (h'00' ～ h'09')

bright_adj
		bsf	intensity,7	;輝度更新フラグ = ON

		; 輝度レジスタの更新

badj01		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movf	intensity,W	;輝度調節値
		andlw	h'0f'
		movwf	reg_data
		bcf	PCLATH,3	;Page 0
		call	max_led_contr	;6個分の制御
		bsf	PCLATH,3	;Page 1

		; 輝度調節値の LED 表示

		movlw	3
		movwf	tbl_type	;フォントデータテーブルの種類 = 3 を指定

		movlw	h'89'		;"Bri."
		movwf	temp_hh
		movlw	h'ab'		;"Lev"
		movwf	temp_mm
		movlw	h'c0'		;"="
		movwf	temp_ss
		movf	intensity,W	;輝度調節値
		andlw	h'0f'
		iorwf	temp_ss,F

		movlw	h'fc'		;(xx_xx_xx)表示
		movwf	dspdigit	;表示桁指定フラグの設定
		call	dxled_display	;ドットマトリクス LED の表示
;		clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		bcf	intensity,7	;輝度更新フラグ = OFF

		; 各スイッチの入力チェック

badj02		btfss	PORTA,_swUP	;UP スイッチ = ON か？
		call	z_up_switch	;Yes

		btfss	PORTA,_swDWN	;DOWN スイッチ = ON か？
		call	z_down_switch	;Yes

		btfsc	intensity,7	;輝度更新フラグ = ON か？
		goto	badj01		;Yes

		btfss	PORTA,_swZER	;ZERO スイッチ = ON か？
		goto	badj02		;Yes

		; 輝度調節処理の終了

		bsf	mod_flg,7	;表示変更フラグ = ON
		return

;--------------------------------------------------------------------------
;	      UP スイッチの処理 ... 輝度調節機能から CALL			; (Ver.1.13) で追加
;--------------------------------------------------------------------------

z_up_switch
		call	xwait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swUP	;再度 UP スイッチ = ON か？
		goto	zupsw01		;No

		incf	intensity,F	;+1 更新
		movlw	h'0a'		;MAX h'0f' を h'09' に制限した
		subwf	intensity,W
		btfsc	STATUS,C	;intensity >= h'0a' か？
		decf	intensity,F	;Yes. MAX 値(= h'09') にする
		bsf	intensity,7	;輝度更新フラグ = ON

zupsw01		btfss	PORTA,_swUP	;UP スイッチ = OFF か？
		goto	$ - 1		;No

		call	xwait_30ms	;チャッタリング吸収
		return

;--------------------------------------------------------------------------
;	     DOWN スイッチの処理 ... 輝度調節機能から CALL			; (Ver.1.13) で追加
;--------------------------------------------------------------------------

z_down_switch
		call	xwait_30ms	;チャッタリング吸収
		btfsc	PORTA,_swDWN	;再度 DOWN スイッチ = ON か？
		goto	zdwsw01		;No

		decf	intensity,F	;-1 更新
		incf	intensity,W	;
		btfsc	STATUS,Z	;intensity = h'00' か？
		clrf	intensity	;Yes. MIN 値(= h'00') にする
		bsf	intensity,7	;輝度更新フラグ = ON

zdwsw01		btfss	PORTA,_swDWN	;DOWN スイッチ = OFF か？
		goto	$ - 1		;No

		call	xwait_30ms	;チャッタリング吸収
		return

;==========================================================================
;		ドットマトリクス LED のデモ表示
;==========================================================================

;	     (1)              (2)              (3)            (4)             (5)               (6)               (7)              (8)
;      start → xdemo_display → demo1_display → lower_upper → demo_dig_seg → no_operation   → xmax_byte_send → max_byte_send → 
;										 xmax_byte_send → max_byte_send  → 
;										 xwait_10ms     → wait_10ms      → 

;		LED のドット点灯移行デモ-1

demo1_display
		movlw	2
		movwf	mlpcnt3		;ループカウンタ3 = 2 を設定

demo1		clrw			;0: "HH" 桁の指定
		call	lower_upper
		clrw			;0: "HH" 桁の指定
		call	left_right
		movlw	1		;1: "HL" 桁の指定
		call	left_right
		movlw	1		;1: "HL" 桁の指定
		call	upper_lower
		movlw	1		;1: "HL" 桁の指定
		call	right_left
		clrw			;0: "HH" 桁の指定
		call	right_left

		movlw	2		;2: "MH" 桁の指定
		call	lower_upper
		movlw	2		;2: "MH" 桁の指定
		call	left_right
		movlw	3		;3: "ML" 桁の指定
		call	left_right
		movlw	3		;3: "ML" 桁の指定
		call	upper_lower
		movlw	3		;3: "ML" 桁の指定
		call	right_left
		movlw	2		;2: "MH" 桁の指定
		call	right_left

		movlw	4		;4: "SH" 桁の指定
		call	lower_upper
		movlw	4		;4: "SH" 桁の指定
		call	left_right
		movlw	5		;5: "SL" 桁の指定
		call	left_right
		movlw	5		;5: "SL" 桁の指定
		call	upper_lower
		movlw	5		;5: "SL" 桁の指定
		call	right_left
		movlw	4		;4: "SH" 桁の指定
		call	right_left

		decfsz	mlpcnt3,F	;ループカウンタ3 - 1 = 0 か？
		goto	demo1		;No

		return

;--------------------------------------------------------------------------

;		LED のドット点灯移行デモ-2

demo2_display
		movlw	3
		movwf	mlpcnt3		;ループカウンタ3 = 3 を設定

demo2		clrw			;0: "HH" 桁の指定
		call	lower_upper
		clrw			;0: "HH" 桁の指定
		call	left_right
		movlw	1		;1: "HL" 桁の指定
		call	left_right
		movlw	2		;2: "MH" 桁の指定
		call	left_right
		movlw	3		;3: "ML" 桁の指定
		call	left_right
		movlw	4		;4: "SH" 桁の指定
		call	left_right
		movlw	5		;5: "SL" 桁の指定
		call	left_right

		movlw	5		;5: "SL" 桁の指定
		call	upper_lower
		movlw	5		;5: "SL" 桁の指定
		call	right_left
		movlw	4		;4: "SH" 桁の指定
		call	right_left
		movlw	3		;3: "ML" 桁の指定
		call	right_left
		movlw	2		;2: "MH" 桁の指定
		call	right_left
		movlw	1		;1: "HL" 桁の指定
		call	right_left
		clrw			;0: "HH" 桁の指定
		call	right_left

		decfsz	mlpcnt3,F	;ループカウンタ3 - 1 = 0 か？
		goto	demo2		;No

		return

;--------------------------------------------------------------------------

;		下 → 上 方向に LED が点灯移行

;		入力	W reg: 該当の桁より左側の桁数

lower_upper
		movwf	nop_cnt		;Wレジスタの内容を保存
		movlw	h'01'		;Digit = 0
		movwf	digit		;Digit の初期値
		movlw	h'01'		;Segment = G
		movwf	segment		;Segment は一定
		movlw	8
		movwf	mlpcnt2		;ループカウンタ2 にセット

lu01		call	demo_dig_seg	;
		incf	digit,F		;digit + 1 更新
		decfsz	mlpcnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	lu01		;No

		return

;--------------------------------------------------------------------------

;		上 → 下 方向に LED が点灯移行

;		入力	W reg: 該当の桁より左側の桁数

upper_lower
		movwf	nop_cnt		;Wレジスタの内容を保存
		movlw	h'08'		;Digit = 7
		movwf	digit		;Digit の初期値
		movlw	h'80'		;Segment = DP
		movwf	segment		;Segment は一定
		movlw	8
		movwf	mlpcnt2		;ループカウンタ2 にセット

ul01		call	demo_dig_seg	;
		decf	digit,F		;digit - 1 更新
		decfsz	mlpcnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	ul01		;No

		return

;--------------------------------------------------------------------------

;		左 → 右 方向に LED が点灯移行

;		入力	W reg: 該当の桁より左側の桁数

left_right
		movwf	nop_cnt		;Wレジスタの内容を保存
		movlw	h'08'		;Digit = 7
		movwf	digit		;Digit は一定
		movlw	h'01'		;Segment = G
		movwf	segment		;Segment の初期値
		movlw	8
		movwf	mlpcnt2		;ループカウンタ2 にセット

lr01		call	demo_dig_seg	;
		bcf	STATUS,C
		rlf	segment,F	;左にシフト
		decfsz	mlpcnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	lr01		;No

		return

;--------------------------------------------------------------------------

;		右 → 左 方向に LED が点灯移行

;		入力	W reg: 該当の桁より左側の桁数

right_left
		movwf	nop_cnt		;Wレジスタの内容を保存
		movlw	h'01'		;Digit = 0
		movwf	digit		;Digit は一定
		movlw	h'80'		;Segment = DP
		movwf	segment		;Segment の初期値
		movlw	8
		movwf	mlpcnt2		;ループカウンタ2 にセット

rl01		call	demo_dig_seg	;
		bcf	STATUS,C
		rrf	segment,F	;右にシフト
		decfsz	mlpcnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	rl01		;No

		return

;--------------------------------------------------------------------------

;	指定 Digit レジスタに Segment データを送出と 10 m秒後にクリア

;		入力	digit:   Digit レジスタ
;			segment: Segment データ

demo_dig_seg
		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movf	nop_cnt,W
		sublw	5
		call	no_operation
		movf	digit,W		;Digit = X
		call	xmax_byte_send ;;レジスタアドレス
		movf	segment,W	;Segment = X
		call	xmax_byte_send ;;レジスタデータ
		movf	nop_cnt,W
		call	no_operation
		bsf	PORTC,maxLOAD	;maxLOAD="H"

		call	xwait_10ms	;10 m秒 ウェイトルーチン

 		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movf	nop_cnt,W
		sublw	5
		call	no_operation
		movf	digit,W		;Digit = X
		call	xmax_byte_send ;;レジスタアドレス
		clrw			;Segment = クリア
		call	xmax_byte_send ;;レジスタデータ
		movf	nop_cnt,W
		call	no_operation
		bsf	PORTC,maxLOAD	;maxLOAD="H"
		return

;--------------------------------------------------------------------------

;		ノーオペレーション

no_operation
		movwf	mlpcnt1		;ループカウンタ1 にセット
		movf	mlpcnt1,W
		btfsc	STATUS,Z	;mlpcnt1 = 0 か？
		goto	nop02		;Yes

nop01		clrw			;no-opレジスタ
		call	xmax_byte_send ;;
		clrw
		call	xmax_byte_send ;;
		decfsz	mlpcnt1,F	;ループカウンタ1 - 1 = 0 か？
		goto	nop01		;No

nop02		return

;==========================================================================
;		EEPROM エリア
;==========================================================================

		org	h'2100'

eep_st		de	"Copyright (C) 2021-2022 by M.Yamamoto"

		de	h'ff'

;==========================================================================

		end			;プログラムの終了
