;***** Matrix88LED_ClockII.asm ********************************************
;
;	ドットマトリクス 8 x 8 LED 表示時計 II （ MAX7219 版）
;
;	Copyright (C) 2021   by M.Yamamoto. All rights reserved.
;
;     ( 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 ファイル名を変更
;	bugfix:  Ver. x.xx
;
;******************************************************* PicAsm 0255 ******

;	Device: PIC16F690	Clock: 8MHz (Internal OSC)

;==========================================================================

#ifdef comment

 <機能と使用法>

・本機の電源を投入すると、"ピポッ" と開始ブザー音を出力後、ドットマトリクス LED のデモ表示が数秒間行われ、
　続いてプログラムのバージョン番号がマトリクス LED に約３秒間表示される。

	バージョン番号			[ Ver. x.xx ]

・次に、0.5秒間ずつ９から０までの数字をカウントダウンしながら、ドットマトリクス LED 全６桁分の表示テストを
　計５秒間行う。

・その後１秒間の空白をおいた後、RTC（リアルタイムクロック）モジュールの状態がチェックされ、初めて電源を入れ
　たときや、バックアップ用バッテリーが異常なとき等に、次のエラーメッセージがマトリクス LED に表示されるとと
　もに、"ブッブー" ブザー音が出力される。

	エラーメッセージ		[ Err. DS3231 ]

・ユーザはバックアップ用バッテリーの状態等を確認してその対処を行った後、SIGNAL スイッチを除いた４つのスイッ
　チの内のどれかを押して応答をする。

・すると、RTC（リアルタイムクロック）モジュールの初期設定をした後、再度 RTC（リアルタイムクロック）モジュー
　ルの状態がチェックされ、なおも NG であれば同様にエラーメッセージの表示が繰り返されるが、OK であれば時計機
　能が開始され、次のように時分秒が刻々と変化をしながらマトリクス LED に表示が行われる。この状態を NORMAL モ
　ード という。

	時間表示			[ xx:xx:xx ]

・このように、RTC（リアルタイムクロック）モジュールの初期設定がされると、エラーフラグがクリアされるとともに、
　年月日(曜日)、時分秒が本機をプログラミングしたときの設定値、 "2021/01/01(FRI)"、"00：00：00" にされるため、
　スイッチ操作による手順で現在の年月日、時分秒に設定をし直す必要がある。

・その手順の説明の前に、本機における表示モードを先に説明をしておく。（このときのモードの意味は上述の 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)エラーが起きるようである。しかし、その４秒後以降には正常な通信が行われて、エラ
　ーメッセージは消滅してしまうので、あまり問題はないものと思う。 

#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 LL 出力		(16) RC0: MAX7219 DIN 出力
;	  (6) RC4: コロン LED LU 出力		(15) RC1: MAX7219 LOAD 出力
;	  (7) RC3: SW5(SIGNAL) スイッチ入力	(14) RC2: MAX7219 CLK 出力
;	  (8) RC6: コロン LED RU 出力		(13) RB4: DS3231 SDA 入出力
;	  (9) RC7: コロン LED RL 出力		(12) RB5: DHT22 DATA
;	 (10) RB7: Bz 出力			(11) RB6: DS3231 SCL 出力

;==========================================================================

	list		p=pic16f690		;デバイス情報
	include		p16f690.inc		;インクルードファイル
	errorlevel	-302			;Eliminate bank warning

;==========================================================================
;		コンフィギュレーションの設定
;==========================================================================
 
	__config 	_CP_OFF & _CPD_OFF & _BOREN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

;==========================================================================
;		定数の定義と変数のレジスタ割付け
;==========================================================================

		radix	dec

ver_no		equ	h'101'		;バージョン番号: 1.01

_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 スイッチ	;┘

f_rah		equ	65536 - 1136	;ラ (880.00 Hz)
f_doh		equ	65536 - 1911	;ド (523.26 Hz)  at 8MHz
f_ra		equ	65536 - 2273	;ラ (440.00 Hz)
f_so		equ	65536 - 2551	;ソ (392.00 Hz)
f_mi		equ	65536 - 3034	;ミ (329.63 Hz)
f_do		equ	65536 - 3822	;ド (261.63 Hz)
f_do_		equ	65536 - 7644	;ド (130.82 Hz)
po_tim		equ	100		;音長(ms)
pi_tim		equ	100		;音長
bu_tim		equ	100		;音長
buu_tim		equ	250		;音長

		cblock  h'20'		;Bank0
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:対象の位置のデータ変更
sig_flg					;時報音出力フラグ, bit0:予報音, :bit1:正報音, bit7:出力許可
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)

; (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' - 3
w_save					;W レジスタの退避用
s_save					;STATUS レジスタの退避用
f_save					;FSR レジスタの退避用
		endc

		cblock  h'a0'		;Bank1
; (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 x 6 = 48) バイトを使用
		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'		;割り込みベクタ
		goto	interrupt

;==========================================================================
;		サブルーチンファイルのインクルード
;==========================================================================

#define 	TRISX	TRISB		;PORTB で I2C を行う場合、
#define 	PORTX	PORTB		;
#define 	_not_wait		;Fast 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
		bcf	STATUS,RP1
		bcf	STATUS,RP0	;バンク 0

		movlw	h'20'
		movwf	bcd_yh		;年(上位2桁) BCD カウンタ ***

		clrf	STATUS		;STATUS クリア
	 	clrf	INTCON		;INTCON クリア

		; 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	h'70'		;CLOCK=8MHz
		movwf	OSCCON

		; OPTION_REG の設定

		movlw	b'00001000'	;bit7=0: プルアップ有効
					;bit6=0: INTピンの立ち下がりエッジで割り込み
					;bit5=0: タイマー０クロックソース選択 = 内部クロック（FOSC / 4）
					;bit4=0: タイマー０エッジ選択 = low-to-high
					;bit3=1: タイマー０でプリスケーラを使用しない
					;bit2-0=000: プリスケーラのスケール値 
		movwf	OPTION_REG

		; 割り込みの設定

		bcf	PIE1,TMR1IE	;TMR1IE: タイマー１割り込みを禁止
		bcf	STATUS,RP0	;バンク 0

		movlw	b'00000001'	;bit7-6: 
					;bit5-4=00: プリスケーラのスケール値 1:1
					;bit3=0: 専用の発振器を使う場合に指定
					;bit2=0: 外部入力クロック指定時に有効
					;bit1=0: 内部クロックを使う
					;bit0=1: タイマー１を動作
		movwf	T1CON		;T1CON に設定

	;;	bcf	INTCON,T0IE	;T0IE: タイマー０割り込みを禁止
		bcf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止
		bsf	INTCON,PEIE	;PEIE: 周辺機器割り込みを許可
		bsf	INTCON,GIE	;GIE:  グローバル割り込みを許可

;--------------------------------------------------------------------------

		; ドットマトリクス LED のデモ表示

		movlw	b'11110010'	;bit1:maxLOAD="H", bit2:maxCLK="L"
		movwf	PORTC		;MAX7219 制御の初期値

		call	max_led_init	;マトリクス LED モジュールの初期化
		call	buzzer_pipo	;"ピポッ" ブザー音出力

		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movlw	h'05'		;11/32 ..... 強調表示のため少し多めに
		movwf	reg_data
		call	max_led_send

		call	demo1_display	;LED のドット点灯移行デモ-1
		call	demo2_display	;LED のドット点灯移行デモ-2

		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movlw	h'00'		;1/32 ...... 最小値でもかなり明るい 
		movwf	reg_data
		call	max_led_send
		call	led_1s_off	;LED を 1 秒間消灯

		; バージョン番号の表示

		clrf	mod_cnt		;モードNo表示時間カウンタの初期設定
	 	clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		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	dxled_display	;ドットマトリクス LED の表示（3 秒間）

		call	wait_1sec	;1 秒 ウェイト
		call	wait_1sec	;1 秒 ウェイト
		call	wait_1sec	;1 秒 ウェイト
		movlw	h'f0'		;
		iorwf	PORTC,F		;"Period" 消灯

		; ドットマトリクス LED の９～０表示テスト

		movlw	10		;
		movwf	mlpcnt2		;ループカウンタ2 にセット

dxtst01		movlw	fd_buff		;フォントデータ格納バッファの先頭アドレス
		movwf	FSR		;間接アドレスに設定
		decf	mlpcnt2,W	;表示文字
		call	font_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_send	;同一データ 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 秒間消灯

;--------------------------------------------------------------------------

		; I2C RTC（DS3231）モジュールのチェック

rtcinit01	Rtc_Read_M	cont_stat,1	;0Fh: Control/Status 読み出し

		bsf	STATUS,RP0	;バンク 1
		movf	cont_stat,W
		bcf	STATUS,RP0	;バンク 0
		movwf	work3
		btfss	work3,7		;OSF = 1 か？
		goto	rtcinit03	;No

;		[ Error DS3231 ]	;DS3231 RTC エラーメッセージ

		bcf	STATUS,RP0	;バンク 0
		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	dxled_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

		; 各変数の初期設定

rtcinit03	clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		clrf	mod_flg		;表示モードフラグの初期設定
		clrf	mod_cnt		;モードNo表示時間カウンタの初期設定
		clrf	time_flg	;時間表示モードフラグ bit1=0:24H/1:12H, bit0=0:am/1:pm
		movlw	b'10000000'
		movwf	sig_flg		;時報音出力許可フラグ = ON
		Rtc_Read_M  seconds,7	;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter

		clrf	int_flg		;外部割り込みフラグの初期設定
		bsf	INTCON,INTE	;INTE: 外部(RA2/INT)割り込みを禁止解除
		goto	main

;==========================================================================
;		ドットマトリクス LED のデモ表示
;==========================================================================

;		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	max_byte_send	;レジスタアドレス
		movf	segment,W	;Segment = X
		call	max_byte_send	;レジスタデータ
		movf	nop_cnt,W
		call	no_operation
		bsf	PORTC,maxLOAD	;maxLOAD="H"

		call	wait_10ms	;10 m秒 ウェイトルーチン

 		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movf	nop_cnt,W
		sublw	5
		call	no_operation
		movf	digit,W		;Digit = X
		call	max_byte_send	;レジスタアドレス
		clrw			;Segment = クリア
		call	max_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	max_byte_send
		clrw
		call	max_byte_send
		decfsz	mlpcnt1,F	;ループカウンタ1 - 1 = 0 か？
		goto	nop01		;No

nop02		return

;==========================================================================
;		MAX7219 レジスタの基本制御
;==========================================================================

		; マトリクス LED モジュールの初期化

max_led_init
		movlw	h'0f'		;ディスプレイテストレジスタ
		movwf	reg_addr
		movlw	h'00'		;通常動作
		movwf	reg_data
		call	max_led_send

		movlw	h'09'		;デコードモードレジスタ
		movwf	reg_addr
		movlw	h'00'		;デコードなし
		movwf	reg_data
		call	max_led_send

		movlw	h'0a'		;輝度レジスタ
		movwf	reg_addr
		movlw	h'00'		;1/32 (minimum)
		movwf	reg_data
		call	max_led_send

		movlw	h'0b'		;スキャン制限レジスタ
		movwf	reg_addr
		movlw	h'07'		;スキャン対象 8桁
		movwf	reg_data
		call	max_led_send

		movlw	h'0c'		;シャットダウンレジスタ
		movwf	reg_addr
		movlw	h'01'		;通常動作
		movwf	reg_data
		call	max_led_send

		call	digit_reg_clr	;全 Digit レジスタのクリア
		return		

;--------------------------------------------------------------------------

;		同一データ MAX7219 x 6個分の制御

max_led_send
		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movlw	6		;
		movwf	mlpcnt1		;ループカウンタにセット

maxsend01	movf	reg_addr,W	;レジスタアドレス
		call	max_byte_send
		movf	reg_data,W	;レジスタデータ
		call	max_byte_send

		decfsz	mlpcnt1,F	;6個分送信した か？
		goto	maxsend01	;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
		movlw	h'08'		;Digit レジスタ数
		movwf	mlpcnt2		;ループカウンタ2 にセット

dclr01		bcf	PORTC,maxLOAD	;maxLOAD="L"
		movlw	h'06'		;6個分の制御
		movwf	mlpcnt1		;ループカウンタ1 にセット

dclr02		movf	mlpcnt2,W	;Digit X
		call	max_byte_send	;レジスタアドレス
		clrw			;Segment クリア
		call	max_byte_send	;レジスタデータ
		decfsz	mlpcnt1,F	;ループカウンタ1 - 1 = 0 か？
		goto	dclr02

		bsf	PORTC,maxLOAD	;maxLOAD="H"
		decfsz	mlpcnt2,F	;ループカウンタ2 - 1 = 0 か？
		goto	dclr01

		return

;--------------------------------------------------------------------------

;		LED を 1 秒間消灯

led_1s_off
		clrf	bcd_ss		;秒 BCD カウンタの初期設定
		movlw	h'0c'		;シャットダウンレジスタ
		movwf	reg_addr
		clrf	reg_data	;シャットダウン（LED 消灯）
		call	max_led_send
		clrf	bcd_ss		;秒 BCD カウンタの初期設定

		call	wait_1sec	;1 秒 ウェイト

		movlw	h'0c'		;シャットダウンレジスタ
		movwf	reg_addr
		movlw	h'01'		;通常動作
		movwf	reg_data
		call	max_led_send
		return		

;==========================================================================
;==========================================================================
;			メイン・ルーチン
;==========================================================================
;==========================================================================

;	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	main04		;No

		btfss	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = ON（１秒周期） か？
		goto	main04		;No

main01		Rtc_Read_M  seconds,7	;RTC DS3231 から年月日、時分秒を読み出し
		call	buffer_to_counter

	;;	btfss	int_flg,1	;DHT22 からデータ読み出し要求フラグ = ON（２秒周期） か？
		btfss	int_flg,3	;DHT22 からデータ読み出し要求フラグ = ON（４秒周期） か？, （変更）*
		goto	main03		;No

main02		call	dht22_measure	;DHT22 から温度、湿度を読み出し
		movlw	h'c0'
		andwf	time_cnt,W
		btfsc	STATUS,Z	;読み出しエラーがあった か？
		goto	main03		;No
					;読み出しエラーの表示
		call	dht22_err_display
		clrf	time_cnt	;初期設定
		bcf	int_flg,3	;DHT22 からデータ読み出し要求フラグ = OFF
		btfss	int_flg,3	;DHT22 からデータ読み出し要求フラグ = ON（４秒周期） か？
		goto	$ - 1		;No
		goto	main02

		; 各表示モードの処理

main03		bcf	mod_flg,7	;表示変更フラグ = OFF
		movf	mod_flg,W
		movwf	wk_order
		btfsc	STATUS,Z	;mod_flg = 0 か？
		call	time_display	;Yes. 時分秒の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 1 か？
		call	date_display	;Yes. 年月日の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 2 か？
		call	temp_display	;Yes. 温度の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 3 か？
		call	humi_display	;Yes. 湿度の表示

		decf	wk_order,F
		btfsc	STATUS,Z	;mod_flg = 4 か？
		call	auto_display	;Yes. オートの表示

		bcf	int_flg,0	;RTC DS3231 からデータ読み出し要求フラグ = OFF
		bcf	int_flg,3	;DHT22 からデータ読み出し要求フラグ = OFF

		call	time_signal	;時報音出力コントロール	

		; 各スイッチの ON／OFF 状態のチェック

main04		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
		goto	main

;--------------------------------------------------------------------------
;		時分秒をマトリクス 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

;--------------------------------------------------------------------------
;		年月日（曜日）をマトリクス 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	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"

;--------------------------------------------------------------------------
;		温度をマトリクス 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	bindec16c_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

;--------------------------------------------------------------------------
;		湿度をマトリクス LED モジュールに表示
;--------------------------------------------------------------------------

humi_display
		movf	humidity_h,W	;湿度上位 8 bit
		movwf	data_h
		movf	humidity_l,W	;湿度下位 8 bit
		movwf	data_l
		call	bindec16c_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

;--------------------------------------------------------------------------
;		オートモード時のマトリクス 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	buzzer_bubuu	;"ブッブー" ブザー音出力
		clrf	tbl_type	;フォントデータテーブルの種類 = 0 を指定
		return

;--------------------------------------------------------------------------
;		バッファと BCD カウンタ間のデータ移動
;--------------------------------------------------------------------------

		; バッファからカウンタへコピー

buffer_to_counter
		bsf	STATUS,RP0	;バンク 1
		movf	seconds,W	;Seconds
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_ss		;秒 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movf	minutes,W	;Minutes
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_mm		;分 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movf	hours,W		;Hours
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_hh		;時 BCD カウンタ

		bsf	STATUS,RP0	;バンク 1
		movf	day,W		;Day
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_ww		;曜日 BCD カウンタ

		bsf	STATUS,RP0	;バンク 1
		movf	date,W		;Date
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_dd		;日 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movlw	h'1f'		;
		andwf	month,W		;Month
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_nn		;月 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movf	year,W		;Year
		bcf	STATUS,RP0	;バンク 0
		movwf	bcd_yy		;年 BCD カウンタ
		return

;--------------------------------------------------------------------------

		; カウンタからバッファへコピー

counter_to_buffer
		bcf	STATUS,RP0	;バンク 0
		movf	bcd_ss,W	;秒 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	seconds		;Seconds
		bcf	STATUS,RP0	;バンク 0
		movf	bcd_mm,W	;分 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	minutes		;Minutes
		bcf	STATUS,RP0	;バンク 0
		movf	bcd_hh,W	;時 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	hours		;Hours

		bcf	STATUS,RP0	;バンク 0
		movf	bcd_ww,W	;曜日 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	day		;Day

		bcf	STATUS,RP0	;バンク 0
		movf	bcd_dd,W	;日 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	date		;Date
		bcf	STATUS,RP0	;バンク 0
		movf	bcd_nn,W	;月 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	month		;Month
		bcf	STATUS,RP0	;バンク 0
		movf	bcd_yy,W	;年 BCD カウンタ
		bsf	STATUS,RP0	;バンク 1
		movwf	year		;Year
		bcf	STATUS,RP0	;バンク 0
		return


;==========================================================================
;	  各スイッチのメイン・ルーチンでの処理と SET モードでの処理
;==========================================================================
;--------------------------------------------------------------------------
;		MODE / SET スイッチの処理
;--------------------------------------------------------------------------

;	(main) → (mode_switch) → (date_display) → (dxled_display) → (font_read6_buff) → (font_read_buff) 
;	       (1)              (2)               (3)                (4)                  (5)
;
;	       → (font_read) → (interrupt)
;	       (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	time_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	;フォントデータテーブルの種類 = 1 を指定

		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	dxled_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	date_display	;年月日の表示
		goto	modsw07

modsw06		call	time_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_switch
		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 スイッチの処理
;--------------------------------------------------------------------------

up_switch
		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

;--------------------------------------------------------------------------
;		DOWN スイッチの処理
;--------------------------------------------------------------------------

down_switch
		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

;--------------------------------------------------------------------------
;		BACK スイッチの処理
;--------------------------------------------------------------------------

back_switch
		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
		movwf	tg_point	;最大値 tg_point = 5 に設定

baksw01		btfss	PORTA,_swBAK	;BACK スイッチ = OFF か？
		goto	$ - 1		;No

		call	wait_30ms	;チャッタリング吸収
		return

;--------------------------------------------------------------------------
;		UP / TIME MODE スイッチの処理
;--------------------------------------------------------------------------

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 スイッチの処理
;--------------------------------------------------------------------------

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. 無視

		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

;--------------------------------------------------------------------------
;		SIGNAL スイッチの処理
;--------------------------------------------------------------------------

;出力:		sig_flg: 時報音出力フラグ ( bit0:予報音, bit1:正報音, bit7:出力許可 )
;			 本プログラムでは bit0, bit1 のフラグは使用しない

signal_switch
		call	wait_30ms	;チャッタリング吸収
		btfsc	PORTC,_swSIG	;再度 SIGNAL スイッチ = ON か？
		goto	sigsw03		;No

		movlw	b'10000000'
		xorwf	sig_flg,F	;時報音出力許可フラグの更新

		btfss	sig_flg,7	;時報音出力許可フラグ = ON か？
		goto	sigsw02		;No. 禁止

		movlw	3		;Yes. 許可
		movwf	lp_cnt1		;ループカウンタ

sigsw01		call	buzzer_pi	;"ピッ" ブザー音出力
		call	wait_30ms
		decfsz	lp_cnt1,F	;ループカウンタ - 1 = 0 か？
		goto	sigsw01		;No
		goto	sigsw03

sigsw02		call	buzzer_buu	;"ブー" ブザー音出力

sigsw03		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 カウンタのインクリメント
;--------------------------------------------------------------------------

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 カウンタのデクリメント
;--------------------------------------------------------------------------

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 カウンタのデクリメント
;--------------------------------------------------------------------------

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 インクリメント

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

;--------------------------------------------------------------------------
;		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

;--------------------------------------------------------------------------
;		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
		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	sig_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	sig_flg,0	;予報音フラグのセット ... 本プログラムではフラグは使用しない
		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	sig_flg,1	;正報音フラグのセット ... 本プログラムではフラグは使用しない

ts102		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

		; "ピッ" ブザー音出力
buzzer_pi
		Sound_M		f_so, pi_tim
		return

		; "ポッ" ブザー音出力
buzzer_po
		Sound_M		f_doh, po_tim
		return

		; "ピポッ" ブザー音出力 (230 mS)
buzzer_pipo
		call	buzzer_pi	;"ピッ" ブザー音出力
		call	wait_30ms
		call	buzzer_po	;"ポッ" ブザー音出力
		return

		; "ブッ" ブザー音出力
buzzer_bu
		Sound_M		f_do, bu_tim
		return

		; "ブー" ブザー音出力
buzzer_buu
		Sound_M		f_do, buu_tim
		return

		; "ブッブー" ブザー音出力 (450 mS)
buzzer_bubuu
		call	buzzer_bu	;"ブッ" ブザー音出力
		call	wait_100ms
		call	buzzer_buu	;"ブー" ブザー音出力
		return

		; ブザー音出力コントロール
buzzer_control
		bsf	STATUS,RP0	;バンク 1
		bsf	PIE1,TMR1IE	;タイマー１割り込みを許可
		bcf	STATUS,RP0	;バンク 0

		call	wait_xxms	;入力 W: 音長（ループカウンタ）

		bsf	STATUS,RP0	;バンク 1
		bcf	PIE1,TMR1IE	;タイマー１割り込みを禁止
		bcf	STATUS,RP0	;バンク 0
		return

;==========================================================================
;		ウェイト・ルーチン (8 MHz)
;==========================================================================

		; 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
w1s01		movwf	wt3cnt

w1s02		call	wait_100ms
		decfsz	wt3cnt,F
		goto	w1s02
		return

;==========================================================================
;		割り込み処理
;==========================================================================

interrupt
		; レジスタの保存

		movwf	w_save		;W レジスタの保存
		swapf	STATUS,W
		movwf	s_save		;STATUS レジスタの保存
		movf	FSR,W
		movwf	f_save		;FSR レジスタの保存

		bcf	STATUS,RP0	;バンク 0
		btfsc	INTCON,INTF	;外部(RA2/INT)割り込み か？
		goto	ra2_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

;---------------- タイマー１割り込み処理 ----------------------------------

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	f_save,W
		movwf	FSR		;FSR レジスタの復帰
		swapf	s_save,W
		movwf	STATUS		;STATUS レジスタの復帰
		swapf	w_save,F
		swapf	w_save,W	;W レジスタの復帰

		retfie

;==========================================================================
;		ドットマトリクス LED ６桁分の表示
;==========================================================================

dxled_display
		call	font_read6_buff	;文字フォントデータの６桁分の読み出し

		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
		movlw	h'00'		;h'00'
		btfsc	STATUS,Z	;ループカウンタ = mod_flg + 1 か？
		movlw	h'ff'		;Yes. h'ff'
		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	max_byte_send	;レジスタアドレス
		movf	INDF,W		;バッファから読み出し
		call	max_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
		; RL,  RU,  LL,  LU,  SW5, CLK, LOAD,DIN
		;(LU,  LL,  RU,  RL の方が良かった)

		movlw	h'07'
		andwf	PORTC,F		;下位 3bit だけをそのまま残す

		btfss	dspdigit,1	;表示桁指定フラグ.1 ("Colon") = ON か？
		goto	dxdsp06		;No

		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'd0'		;am指定, :("Colon")右列上下 + 左列上側 LED点灯,  (RL, RU, xx, LU)
		btfss	time_flg,1	;pm表示 か？
		goto	dxdsp08		;No

		movlw	h'e0'		;pm指定, :("Colon")右列上下 + 左列下側 LED点灯,  (RL, RU, LL, xx)
		goto	dxdsp08

dxdsp05		movlw	h'f0'		;:("Colon")指定,  (RL, RU, LL, LU)
		btfss	int_flg,1	;12時間表示時の AM/PM 表示点滅タイミング
		goto	dxdsp08		;No

		movlw	h'e0'		;am指定, :("Colon")左列上側 LED点滅,  (RL, RU, LL, xx)
		btfss	time_flg,0	;pm表示 か？
		goto	dxdsp08		;No

		movlw	h'd0'		;pm指定, :("Colon")左列下側 LED点滅,  (RL, RU, xx, LU)
		goto	dxdsp08

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'20'		; 左. ("Period")指定,  (xx, xx, LL, xx)
;		btfss	dspdigit,3	;表示桁指定フラグ.3 ("SH") = ON か？
;		goto	dxdsp08		;No

		movlw	h'80'		; 右 .("Period")指定,  (RL, xx, xx, xx)
		btfss	dspdigit,6	;表示桁指定フラグ.6 ("HL") = ON か？
		goto	dxdsp08		;No.                                    ... 気温(__ xx.x℃), 湿度(__ xx.x％)

dxdsp07		movlw	h'a0'		; 両..("Period")指定,  (RL, xx, LL, xx) ... 年月日(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	btfss	dspdigit,2	;"SL" 桁 = 1 か？
		goto	fr6buf11	;No

		movf	temp_ss,W
		call	font_read_buff	;１文字フォントデータパタンの読み出しとビット列変換
		goto	fr6buf12

fr6buf11	call	zero_clear	;ゼロクリア

fr6buf12	return

;--------------------------------------------------------------------------

		; ゼロクリア

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 のビット列並びを逆に変換してバッファへ格納 )
;--------------------------------------------------------------------------

;	  入力:	　             W: 表示文字データ (h'x0'～h'x9', h'xa'～h'xf')
;			tbl_type: フォントデータテーブルの種類 (0/1/2)

;	  出力:	 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	frbuf03

frbuf01		decf	tbl_type,W
		btfss	STATUS,Z	;フォントデータテーブルの種類 = 1 か？
		goto	frbuf02		;No

		movlw	high font_data_tbl_1
		movwf	addr_high	;文字フォントデータの先頭 high アドレス
		movlw	low font_data_tbl_1
		goto	frbuf03

frbuf02		movlw	high font_data_tbl_2
		movwf	addr_high	;文字フォントデータの先頭 high アドレス
		movlw	low font_data_tbl_2

frbuf03		addwf	addr_low,F	;文字フォントデータの先頭 low アドレス
		btfsc	STATUS,C	;オーバーフローした場合は
		incf	addr_high,F	;文字フォントデータ high アドレスの更新

		movlw	8		;
		movwf	lp_cnt2		;ループカウンタ2（digit カウンタ）

frbuf04		call	font_read	;文字フォントデータの読み出し
		movwf	work1		;反転前のビット列

		movlw	high $		;この場所の high アドレスを
		movwf	PCLATH		;PCLATH に設定
		movlw	8		;
		movwf	lp_cnt1		;ループカウンタ1（segment カウンタ）	

frbuf05		rlf	work1,F		;C bit を出力
		rrf	work2,F		;C bit を入力
		decfsz	lp_cnt1,F	;ループカウンタ1 - 1 = 0 か？
		goto	frbuf05		;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	frbuf04		;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'

;==========================================================================
;		EEPROM エリア
;==========================================================================

		org	h'2100'

eep_st		de	"Copyright (C) 2021 by M.Yamamoto"

		de	h'ff'

;==========================================================================

		end			;プログラムの終了
