;------------------------------------------------------------------------------
; 高度計
;------------------------------------------------------------------------------
; バージョン履歴
; 2024-01-13 Ver.0.62	バグがあったdiv24,div32を変更、PC-98フォントを切り替えられるように持ってきた
; 2024-01-13 Ver.0.61a	集約 mov_P_MCL_to_MATH020100, baro2hpa, baro2inch, store_INDF_inc_FSR
; 2021-06-02 Ver.0.61	文字列最適化、BAROモードの表示幅に36時間を追加。
; 2019-09-07 Ver.0.60	バックライトの設定粒度を変更。
; 2019-09-07 Ver.0.59	BAROモードの表示幅に18時間を追加。
; 2018-08-23 Ver.0.58	スリープから復帰した時にグラフにダミー線を挿入するようにした。
; 2018-08-23 Ver.0.57a	プログラムメモリを空けた
; 2018-08-19 Ver.0.57	グラフに中間軸ガイドを付けた
; 2018-08-18 Ver.0.56	スリープ復帰時にグラフ履歴を初期化しないようにした。
; 2018-08-18 Ver.0.56a	プログラムメモリを空けた
; 2018-08-18 Ver.0.55	BAROモードの表示幅に8時間を追加。
; 2018-03-21 Ver.0.54	BAROモードの表示幅に72/96時間を追加。DUTY_TABLEをページ0に移動。
;			バックライトのPWM値を変更。
;			プログラムメモリの残量が0になった。
; 2015-11-05 Ver.0.53	sub16で下位の桁下がり時に上位桁を「インクリメント」していたので、オフセットが正しく計算されていなかった。(グラフの1024hPa付近が正しく表示されない)
; 2015-11-01 Ver.0.52	GOTO standbyする時にRPを0に戻し忘れていたため、センサがスタンバイに入らずしばらくしたらウェイクアップしていた。
; 2015-11-01 Ver.0.51	グラフ画面に時間スパンの表示を付けた。
;			puts5で0x3A以上が来たらそれ以降をputs8に切り替えるようにした。
;			プログラム領域を空けるため、クロックインジケータ削除、重複部分のサブルーチン化。もう無理
; 2015-10-18 Ver.0.50	VSIの平均を取らない時にVSI_P1フラグをリセットするのを忘れていて、平均有りから無しに切り替えた時にVSIが停止する事があった。
; 2015-10-18 Ver.0.49	VSIWIDEを新設してWIDE側の除算値を変更できるようにした。設定画面は設けない。
; 2015-10-18 Ver.0.48	VSIゲージのノーマル側の反応が悪いので2で割らずにそのまま表示させた。
;			VSIゲージのゼロ点を表示させた。使っていない8ドットフォントを削除。
; 2015-10-17 Ver.0.47	使っていない16ドットフォントを削除。
;			VSIキャリブレーションのカウンタを実装。
; 2015-10-17 Ver.0.46	VSIゲージが完成しすべての作業が終了。残り8ワード。
; 2015-10-16 Ver.0.45	VSIゲージ用に設定メニューとフラグを追加。メモリ最適化。残り16+65ワード。
; 2015-10-16 Ver.0.44	(安定版)バックライトの周波数を上げた方がちらつきが少なくなるため変更。
; 2015-10-16 Ver.0.43	完成
; 2015-10-15 Ver.0.42	OSR,INTERVAL,CONTRAST,BACKLIGHT,CALの変数を設定表示画面の順番に並べた。
;			CAL_VSIの表示数値の計算が間違っていた。	CAL,STの送信をサブ化した。
;			数値の設定部分の数値変更処理が完成。
; 2015-10-14 Ver.0.41	フラグの設定部分が完成。
;			lcd_contrastをページ1に戻す。メニューの使っていない分岐部分を削除。残り160ワード。
; 2015-10-13 Ver.0.40A	0.40の問題点を修正。
; 2015-10-13 Ver.0.40	VSIゲージ,puts16の反転表示廃止。BAROグラフ48時間用インターバル追加。
;			lcd_contrastとstandbyをページ0の空き領域に移動。残り253ワード。
; 2015-10-12 Ver.0.39	設定画面のスクロール、スリープ、モード変更が完成。残り190ワード。
; 2015-10-11 Ver.0.38	設定画面表示が完成。残り300ワード。
; 2015-10-10 Ver.0.37	キャリブレーションの値以外の表示が完成。メモリが10%しか残っていない。
; 2015-10-10 Ver.0.36	フラグタイプのメニュー表示が完成。数値タイプはまだ項目名しか表示されない。
; 2015-10-10 Ver.0.35	ページ1のコード領域が少ないため記号のフォントを削除。8ドット以外の反転表示も削除する?	
; 2015-10-10 Ver.0.34A	分岐コード最適化。
; 2015-10-09 Ver.0.34	気温の軸ガイドが完成したが、小数表示のため正しいのかよく解らない。
;			ALTモードでも気温のグラフとレンジが動くようにした。
; 2015-10-07 Ver.0.33	気温のグラフを作成。
;			データ取得ルーチンをモジュール化せずに単純にフラグチェックでアドレスを切り替えるようにしたら25ワードも空きができた。
; 2015-10-07 Ver.0.32	気圧の軸ガイドが完成。
; 2015-10-06 Ver.0.31	気圧のグラフ作成、軸ガイドは途中で保留。
; 2015-10-04 Ver.0.30	高度の軸ガイドを作成。
; 2015-10-03 Ver.0.29	lcd_backlight,lcd_contrastをページ1に移動。再度高度グラフを実装。オフセットの部分もうまく動いてるようだ。
; 2015-10-03 Ver.0.28	少し修正、8x5ドットフォント実装。fifo_writeをページ1に移動。いったんグラフを除去。
; 2015-09-28 Ver.0.27	キー短押しでビューを順番に変更するようにした。
; 2015-09-26 Ver.0.26	高度計のオフセット表示ができた。センタリング補正も働くようにした。
; 2015-09-26 Ver.0.25	グラフの圧力用履歴を2バイト化、温度用をページ1に移動。イベントキューサイズを20バイトに縮小。
;			ALT絶対値グラフと軸ラベル完成。8dotの@を16の複合文字に変更。
; 2015-09-07 Ver.0.24	基板を作って組立。
;			スリープモード実装。スリープはYES/NOでダイアル位置を電流消費の低い角度に意図的に持ってくるよう工夫すること。
;			いろいろ触ってるうちに動かなくなった。
; 2015-09-06 Ver.0.23	高度計のグラフができた。軸ガイドは要検討。
; 2015-09-06 Ver.0.22	ビュー0を統合
; 2015-09-05 Ver.0.21	サブルーチンの配置変更。変数の配置変更。
;			システム初期化とモード切り替え用の初期化を分離して、全てページ1に置く。
;			気圧センサのコントロール専用関数の見直し。
;			数値の文字列化部分を共通化。format_x
;			MIN/MAXはいったん廃止。
; 2015-09-03 Ver.0.20	グラフ描画が完成。データ取得はフラグで取得方法を切り替えるか…
; 2015-08-31 Ver.0.19	VSIの表示を若干修正、8MHz/3Vでも問題なく動く。
; 2015-08-30 Ver.0.18	高度計、VSI、QNH変更、VSI1秒誤差補正、VSI2秒平均
; 2015-08-26 Ver.0.17	機能を盛り込みすぎて訳が分からなくなってるので、とりあえず基本機能に絞る。
;			EEPROM連続書き込み化、qnh_to_string、16ドットフォントを7バイト化、システムリセットをページ1に移動。
; 2015-08-22 Ver.0.16	反転フォント、I2C連続読み込み、設定初期化、スイッチ長押し、文字列テーブル取得を実装。
; 2015-08-20 Ver.0.15	Ver.0.14で作ったルーチンの役割修正。MIN/MAXで使えるように引数を変更した。
; 2015-08-19 Ver.0.14	表示用文字列生成ルーチンを作った。乗除算が多いのでかなり負荷が高い。
; 2015-08-17 Ver.0.13	PORTBの変化割り込みを正しく動くよう、エンコーダの変化検出とLCDの駆動ルーチンでPORTBを読まないようにした。
;			割り込み時は高クロックに移行するようにした。
; 2015-08-16 Ver.0.12	FIFOのサイズが小さすぎて高度計割り込みを取りこぼして停止する事があった。
;			1回転で30回割り込みが発生するので、0xA0-0xEFの80バイトをFIFOに割り当てた。
; 2015-08-15 Ver.0.11	乗除算ルーチンを実装。
; 2015-08-15 Ver.0.10	割り込みでPORTBのフラグリセットとポート状態の読み込み順が逆だったので、割り込みが2回かかっていた。
; 2015-08-14 Ver.0.09	fifo_readのIRPの扱いが間違っていた。
;			高度計の駆動に成功。気圧温度と差分を読み出し、16進表示ができた。
;			全割り込みとイベントキューが正しく動作し、イベント処理時の高クロック動作も正常に動作した。
;			データシートの誤りを発見した。SRC_DRDYのクリアはSTATUSを読む必要はない。
;			オーバーサンプリング128で動作させると、計測時間中は結構な電流が流れる。
; 2015-08-13 Ver.0.08	液晶のsceはきちんと処理しないと最後の受信バイトが表示されないことが分かった。
; 2015-08-13 Ver.0.07	I2Cが動くようになった。
; 2015-08-09 Ver.0.06	bin2hex作成
; 2015-08-08 Ver.0.05	文字列が表示できるようになった。
;			ぱうフォントを移植した。手作業なので疲れた。
;			LCDのTCを変えても見た目には全く変化が無かった。
; 2015-07-25 Ver.0.04	テスト用プログラムをバラして作り直し。LCD初期化成功。
;			割り込み処理をイベントドリブンで実行できるように変更中。
; 2015-07-24 Ver.0.03	LCDテスト。
; 2015-07-20 Ver.0.02	Ver.0.01を組み込めるように変更。
; 2015-07-18 Ver.0.01	3種類の割り込み実装が終了。
;			SLEEP中はTMR0(キー割り込み)が使えないことを確認。
;			PWMを実装。ロータリーエンコーダでバックライトの明るさを変えられるようになった。
; 2015-07-16 Ver.0.00	16F88版作成開始。
;
;------------------------------------------------------------------------------
; IRP,RP1,RP0を切り替える所で◆ RP=, ● IRP=をコメントに置く
; PCLATHを切り替える所で■ PCLATHをコメントに置く
; サブルーチンからの戻りの時、
;  RP1,RP0は0に戻してリターンする。
;  IRP,PCLATH,LCDモードは戻さずにリターンする。
; ルーチン呼び出しの時もRP=0を基本として記述している。
;------------------------------------------------------------------------------
; デバイス	PIC16F88
; 動作周波数	内蔵4MHz(3V駆動のため公式に8MHzは使えないが、実際は動く)
;------------------------------------------------------------------------------
	LIST		P=PIC16F88,R=DEC,N=0
	INCLUDE		"P16F88.INC"
	ERRORLEVEL	0,-302,-306,-307
	__CONFIG _CONFIG1, 0x2F10	; FOSC : INTRC_RA6=IO
					; WDTE : Disable
					; PWRTE: Enable
					; MCLRE: RA5=IO
					; BODEN: Disable
					; LVP  : RB3=IO
					; CPD  : Not Protect
					; WRT  : Protection off
					; DEBUG: Disable
					; CCPMX: CCP1=RB3
					; CP   : Not Protect
	__CONFIG _CONFIG2, 0x3FFC	; FCMEN: Disable
					; IESO : Disable

	#define	FONT 0			; 0:PAW 1:PC-98
;------------------------------------------------------------------------------
; 変数宣言 ALT->BARO->TEMPの順に並べる
;------------------------------------------------------------------------------
; 設定データ EEPROMにも同じレイアウトで並べる
MODE_CFG	EQU	0x20		; モードの設定
VIEW0		EQU	0		; ビュー数値 0-3
VIEW1		EQU	1
MODE		EQU	2		; 0=Alt  1=Baro

ALT_CFG		EQU	0x21		; 高度計の設定
ALT_SUBDISP	EQU	0		; 0=OFF  1=ON
ALT_GTYPE	EQU	1		; 0=DOT  1=BAR
ALT_UNIT	EQU	2		; 0=ft   1=m
VSI_UNIT	EQU	3		; 0=ft/m 1=m/s
QNH_UNIT	EQU	4		; 0=in   1=hPa
VSI_AVG		EQU	5		; 0=Direct 1=Average
VSI_RANGE	EQU	6		; 0=NARROW 1=WIDE
ALT_YTYPE	EQU	7		; 0=Float  1=Fix

BARO_CFG	EQU	0x22		; 気圧計の設定
BARO_SUBDISP	EQU	0		; 0=OFF  1=ON
BARO_GTYPE	EQU	1		; 0=DOT  1=BAR
BARO_UNIT	EQU	2		; 0=hPa  1=in
BARO_RESERVED	EQU	7		; 必ず0にする

TEMP_CFG	EQU	0x23		;温度計の設定
TEMP_UNIT	EQU	0		; 0=C    1=F
TEMP_GTYPE	EQU	1		; 0=DOT  1=BAR
TEMP_RESERVED	EQU	7		; 必ず0にする

ALT_RANGE	EQU	0x24		; x=0-7 メートル/2^x
BARO_RANGE	EQU	0x25		; x=0-2
TEMP_RANGE	EQU	0x26		; x=0-2
QNH_MSB		EQU	0x27		; QNH_UNITにより入れる値が変わる
QNH_LSB		EQU	0x28
ALT_INTERVAL	EQU	0x29		; グラフインターバル
ALT_OSR		EQU	0x2A
BARO_INTERVAL	EQU	0x2B
BARO_OSR	EQU	0x2C
BACKLIGHT	EQU	0x2D		; バックライト光量インデックス(0-3)
CONTRAST	EQU	0x2E		; コントラスト値(0-7)
CAL_ALT		EQU	0x2F
CAL_BARO	EQU	0x30
CAL_TEMP	EQU	0x31
CAL_VSI		EQU	0x32
VSIWIDE		EQU	0x33		; VSIレンジをWIDEにした時の除算値
;空き 0x34-0x3B
MATH30		EQU	0x3C
MATH31		EQU	0x3D
MATH32		EQU	0x3E
MATH33		EQU	0x3F

; 気圧計
P_MSB		EQU	0x40		; 気圧計取得データ
P_CSB		EQU	0x41		; リアルタイム値、デルタ、最小、最大はこの並びで取得する
P_LSB		EQU	0x42
T_MSB		EQU	0x43
T_LSB		EQU	0x44
P0_MSB		EQU	0x45		; VSI平均値用過去のデータ0
P0_CSB		EQU	0x46
P0_LSB		EQU	0x47
P1_MSB		EQU	0x48		; VSI平均値用過去のデータ1
P1_CSB		EQU	0x49
P1_LSB		EQU	0x4A

; LCD表示用変数
LCD_X		EQU	0x4B		; LCD表示位置(0-83)
LCD_Y		EQU	0x4C		; LCD表示位置(0-5)

; I2C用変数
I2CDATA		EQU	0x4D		; I2Cで読み書きするデータ

; イベントキューFIFO用変数
READPTR		EQU	0x4E		; FIFOリードポインタ
WRITEPTR	EQU	0x4F		; FIFOライトポインタ
USEDSIZE	EQU	0x50		; FIFO使用サイズ
READDATA	EQU	0x51		; 読み込みデータ作業領域
WRITEDATA	EQU	0x52		; 書き込みデータ作業領域

; EEPROM用変数
_EEADDR		EQU	0x53
_EEDATA		EQU	0x54

; グラフ用変数
GRAPHPTR	EQU	0x55		; グラフ履歴の書き込み読み出し位置
OFFSET_L	EQU	0x56		; グラフオフセット
OFFSET_M	EQU	0x57		; グラフオフセット
INT_COUNT	EQU	0x58		; インターバル減算カウンタ

; 設定メニュー用変数
MENUROW		EQU	0x59		; メニューカーソル位置
MENUPOSITION	EQU	0x5A		; メニュー表示位置 上4bit=メニュー階層 下4bit=メニュー表示開始行
BEF_ROW		EQU	0x5B		; サブメニューへ入る前の位置
BEF_POSITION	EQU	0x5C

VS		EQU	0x5D		; VSIゲージ用の縦速度情報
;空き 0x5E-0x5F

; フラグ
FLAG1		EQU	0x60
FIFO_EMPTY	EQU	0		; 1=EMPTY
FIFO_FULL	EQU	1		; 1=FULL
I2C_NAK		EQU	2		; 0=ACK 1=NAK
I2C_RW		EQU	3		; デバイスアドレス指定時の0=WRITE 1=READ
NEG_FONT	EQU	4		; 1=白黒反転フォント
MATH_SIGN	EQU	5		; 0=+ 1=-
VSI		EQU	6		; VSI用に単位を抑制する
VSI_P1		EQU	7		; VSIの過去データをP0とP1のどちらに書くか

FLAG2		EQU	0x61
GRAPHTYPE	EQU	0		; グラフのタイプ指示
GRAPH_DRAW	EQU	1		; グラフ再描画指示(共用)
OFFSET_UPDATE	EQU	1		; オフセットアップデート指示(共用)
OFFSET_INIT	EQU	2		; オフセット初期化指示
YGUIDE		EQU	3		; 軸ガイド指示
CALIB		EQU	4		; キャリブレーション用表示
EDIT_VALUE	EQU	5		; 設定モードのダイアルが項目の選択か編集かの切り替え
VSI_SIGN	EQU	6		; VSIゲージ用のマイナスフラグ
HOLD_GRAPH	EQU	7		; スリープから復帰時にグラフクリアを抑制するフラグ

CALCOUNT_L	EQU	0x62
CALCOUNT_M	EQU	0x63

; 四則演算用変数
MATH00		EQU	0x64		; LSB
MATH01		EQU	0x65		;  :
MATH02		EQU	0x66		;  :
MATH03		EQU	0x67		;  :
MATH04		EQU	0x68		;  :
MATH05		EQU	0x69		; MSB
MATH20		EQU	MATH04
MATH21		EQU	MATH05
MATH22		EQU	0x6A
MATH23		EQU	0x6B
MATH10		EQU	0x6C
MATH11		EQU	0x6D
MATH12		EQU	0x6E
MATH13		EQU	0x6F

; 一時変数
TMP00		EQU	0x70
TMP01		EQU	0x71
TMP02		EQU	0x72
TMP03		EQU	0x73
TMP10		EQU	0x74		; 文字表示,PWM関連で使用
TMP11		EQU	0x75
TMP12		EQU	0x76
TMP13		EQU	0x77
TMP20		EQU	0x78		; LCD,I2Cで使用
TMP21		EQU	0x79
TMP22		EQU	0x7A
TMP23		EQU	0x7B

; 割り込みの退避用
W_		EQU	0x7C
STATUS_		EQU	0x7D
PCLATH_		EQU	0x7E
FSR_		EQU	0x7F

; バッファ関係
FIFOBUF		EQU	0x0A0		; 0x0A0-0x0EF 20イベント分
TEMPBUF		EQU	0x0B4		; 0x0B4-0x0EF 気温履歴バッファ60バイト
STRING		EQU	0x110		; 0x110-0x11F 文字バッファ16文字分
;空き					  0x120-0x133
PRESSBUF_LSB	EQU	0x134		; 0x134-0x16F 気圧履歴リングバッファ60バイト
FONTCACHE	EQU	0x190		; 0x190-0x197 16dotフォントの下半分のキャッシュ8ドット分
;空き					  0x198-0x1B3
PRESSBUF_MSB	EQU	0x1B4		; 0x1B4-0x1EF 気温履歴リングバッファ60バイト

;------------------------------------------------------------------------------
; 定数宣言
;------------------------------------------------------------------------------
I2C_DEVADDR	EQU	0xC0
FIFO_SIZE	EQU	20		; イベントキューFIFOのサイズ
HISTORY_SIZE	EQU	60		; 履歴リングのサイズ
NULL		EQU	0
OFFSET_MARGIN	EQU	4
;------------------------------------------------------------------------------
; ポート割り当て
;------------------------------------------------------------------------------
; PORTA
LED_CLOCK	EQU	0		; OUT デバッグ用 クロックインジケータ
;		EQU	1		; OUT 空き(H出力)
;		EQU	2		; OUT 空き(H出力)
LCD_RES		EQU	3		; OUT /RESET
ENC_SW		EQU	4		; IN  T0CKI
ENC_B		EQU	5		; IN
I2C_SCL		EQU	6		; I/O ソフト制御
I2C_SDA		EQU	7		; I/O ソフト制御

; PORTB
ENC_A		EQU	0		; IN  INT
;		EQU	1		; IN  SPI IN(未接続、外部でプルダウン)
;		EQU	2		; OUT SPI OUT
;		EQU	3		; OUT PWM(吐き出し)
;		EQU	4		; OUT SPI CLK
LCD_DC		EQU	5		; OUT 0=CMD 1=DATA
LCD_SCE		EQU	6		; OUT /ENABLE
ALT_INT		EQU	7		; IN  ポート変化割り込み

;------------------------------------------------------------------------------
; MPL3115A2 レジスタ名テーブル
; B=起動時に書き込み
; C=設定変更時に書き込み
;------------------------------------------------------------------------------
STATUS_00	EQU	0x00		;    DR_STATUS or F_STATUSのエイリアス
OUT_P_MSB	EQU	0x01		;    FIFOが有効の時はF_DATAのエイリアス
OUT_P_CSB	EQU	0x02		;    FIFOが有効の時は無効
OUT_P_LSB	EQU	0x03		;    FIFOが有効の時は無効
OUT_T_MSB	EQU	0x04		;    FIFOが有効の時は無効
OUT_T_LSB	EQU	0x05		;    FIFOが有効の時は無効

DR_STATUS	EQU	0x06		;    データイベント、データ上書きフラグ
OUT_P_DELTA_MSB	EQU	0x07		;    最終サンプルの差分値
OUT_P_DELTA_CSB	EQU	0x08		;    VSIに使う
OUT_P_DELTA_LSB	EQU	0x09
OUT_T_DELTA_MSB	EQU	0x0A
OUT_T_DELTA_LSB	EQU	0x0B

WHO_AM_I	EQU	0x0C		;    デバイスID、用途不明
F_STATUS	EQU	0x0D		;    FIFOオーバーフロー、ウォーターマークフラグ、FIFOサンプル数カウンタ
F_DATA		EQU	0x0E		;    FIFOデータ
F_SETUP		EQU	0x0F		;    FIFOモード、ウォーターマーク閾値設定
TIME_DLY	EQU	0x10		;    内容不明
SYSMOD		EQU	0x11		;    システムモード読み出し
INT_SOURCE	EQU	0x12		;    割り込み要因フラグ
PT_DATA_CFG	EQU	0x13		; B  データイベント有効化フラグ
BAR_IN_MSB	EQU	0x14		; BC 高度計規正値
BAR_IN_LSB	EQU	0x15
P_TGT_MSB	EQU	0x16		;    高度スレッショルド
P_TGT_LSB	EQU	0x17
T_TGT		EQU	0x18		;    温度スレッショルド
P_WND_MSB	EQU	0x19		;    高度範囲
P_WND_LSB	EQU	0x1A
T_WND		EQU	0x1B		;    温度範囲
P_MIN_MSB	EQU	0x1C		; BC 最低気圧
P_MIN_CSB	EQU	0x1D
P_MIN_LSB	EQU	0x1E
T_MIN_MSB	EQU	0x1F		; BC 最低温度
T_MIN_LSB	EQU	0x20
P_MAX_MSB	EQU	0x21		; BC 最高気圧
P_MAX_CSB	EQU	0x22
P_MAX_LSB	EQU	0x23
T_MAX_MSB	EQU	0x24		; BC 最高温度
T_MAX_LSB	EQU	0x25
CTRL_REG1	EQU	0x26		; BC システムモード、ワンショット、ソフトリセット、オーバーサンプリング、RAWモード、高度/気圧切り替え
CTRL_REG2	EQU	0x27		; BC 計測周期、アラーム源選択、？
CTRL_REG3	EQU	0x28		;    割り込み信号設定
CTRL_REG4	EQU	0x29		; B  割り込み有効フラグ
CTRL_REG5	EQU	0x2A		;    割り込み信号ルーティング
OFF_P		EQU	0x2B		; BC 気圧オフセット
OFF_T		EQU	0x2C		; BC 温度オフセット
OFF_H		EQU	0x2D		; BC 高度オフセット

;------------------------------------------------------------------------------
; EEPROMアドレスと初期値
;------------------------------------------------------------------------------
EE_MODE_CFG		EQU	0x00
EE_ALT_CFG		EQU	0x01
EE_BARO_CFG		EQU	0x02
EE_TEMP_CFG		EQU	0x03
EE_ALT_RANGE		EQU	0x04
EE_BARO_RANGE		EQU	0x05
EE_TEMP_RANGE		EQU	0x06
EE_QNH_MSB		EQU	0x07
EE_QNH_LSB		EQU	0x08
EE_ALT_INTERVAL		EQU	0x09
EE_ALT_OSR		EQU	0x0A
EE_BARO_INTERVAL	EQU	0x0B
EE_BARO_OSR		EQU	0x0C
EE_BACKLIGHT		EQU	0x0D
EE_CONTRAST		EQU	0x0E
EE_CAL_ALT		EQU	0x0F
EE_CAL_BARO		EQU	0x10
EE_CAL_TEMP		EQU	0x11
EE_CAL_VSI		EQU	0x12
EE_VSIWIDE		EQU	0x13
EE_END			EQU	0x14

DEF_MODE_CFG		EQU	0
DEF_ALT_CFG		EQU	0x0F
DEF_BARO_CFG		EQU	1
DEF_TEMP_CFG		EQU	0
DEF_ALT_RANGE		EQU	0
DEF_BARO_RANGE		EQU	0
DEF_TEMP_RANGE		EQU	0
DEF_QNH_MSB		EQU	0x0B	; 0BB0=29.92in C5E4=1013.20hPa
DEF_QNH_LSB		EQU	0xB0
DEF_ALT_INTERVAL	EQU	0
DEF_ALT_OSR		EQU	7
DEF_BARO_INTERVAL	EQU	0
DEF_BARO_OSR		EQU	7
DEF_BACKLIGHT		EQU	9
DEF_CONTRAST		EQU	5
;DEF_CAL_ALT		EQU	0
;DEF_CAL_BARO		EQU	0
;DEF_CAL_TEMP		EQU	0
;DEF_CAL_VSI		EQU	0
DEF_CAL_ALT		EQU	8	; +8m
DEF_CAL_BARO		EQU	0xFE	; -0.08hPa
DEF_CAL_TEMP		EQU	0x0A	; +0.75
DEF_CAL_VSI		EQU	13	; 269 AltモードINT=1sec 4分16秒(256秒)間にカウントする値
DEF_VSIWIDE		EQU	4	; 1=±1.44m/283ft(0.06*24) 4=±5.76m/1134ft
;------------------------------------------------------------------------------
; 電源ON
;------------------------------------------------------------------------------
	ORG	0
	BSF	PCLATH,3		; ■ PCLATH
	GOTO	system_reset
;DEBUG	EQU	0
;------------------------------------------------------------------------------
procKEY_LONG				; キー長押し(空きメモリ節約)
	BSF	PCLATH,3		; ■ PCLATH
	GOTO	CONFIGURATION
;------------------------------------------------------------------------------
; 割り込みを処理し、イベントキューにIDを書き込む。
; ID=0 エンコーダのスイッチ 短押し
; ID=1 エンコーダのスイッチ 長押し(長押し判定は割り込みの外で行う)
; ID=2 エンコーダCCW
; ID=3 エンコーダCW
; ID=4 高度計センサ
;------------------------------------------------------------------------------
	ORG	4
	MOVWF	W_			; Wセーブ
	SWAPF	STATUS,W		; STATUSセーブ
	MOVWF	STATUS_
	MOVF	PCLATH,W		; PCLATHセーブ
	MOVWF	PCLATH_
	MOVF	FSR,W			; FSRセーブ
	MOVWF	FSR_

	CLRF	STATUS			; ◆ RP=0, IRP=0
	CLRF	PCLATH			; ■ PCLATH
	CALL	clock_high		; 無条件で高クロックに切り替える
					; RETFIE後イベント待ちループの場合は、次のメインループで低クロックに戻る。
	BSF	PCLATH,3		; ■ PCLATH
	GOTO	INTERRUPT
;------------------------------------------------------------------------------
; ■■■■■■■■■■■■■■■■ メインループ ■■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
MAINLOOP
	CALL	event_wait
	CLRF	PCLATH			; ■ PCLATH
	MOVF	TMP20,W			; イベント番号で分岐
	ADDWF	PCL,F
	 GOTO	procKEY_SHORT		; 0
	 GOTO	procKEY_LONG		; 1
	 GOTO	procDIAL_DECR		; 2
	 GOTO	procDIAL_INCR		; 3
	 GOTO	procSENSOR		; 4
;------------------------------------------------------------------------------
procKEY_SHORT				; キー短押し
	MOVF	MODE_CFG,W
	ANDLW	3			; MODEをマスク
	MOVWF	TMP00			; 上限チェック
	MOVLW	2			; 最大は2
	SUBWF	TMP00,W
	INCF	MODE_CFG,F
	MOVLW	4
	BTFSC	STATUS,C
	 ANDWF	MODE_CFG,F		; 0>1>0または0>1>2>0となるように循環させる

	MOVLW	MODE_CFG		; EEPROM保存
	MOVWF	FSR
	MOVLW	EE_MODE_CFG
	MOVWF	_EEADDR
	MOVLW	1
	CALL	write_ee_data
FORCE_REDRAW
	CALL	lcd_cls			; 画面クリア
	MOVF	MODE_CFG,W		; ALT-0の時はQNH表示
	BTFSC	STATUS,Z
	 CALL	disp_qnh
	BSF	FLAG2,OFFSET_INIT
	BSF	FLAG2,GRAPH_DRAW
	GOTO	VIEW_REDRAW
;------------------------------------------------------------------------------
procDIAL_DECR				; ダイアルマイナス
	MOVF	MODE_CFG,W		; モード+ビュー番号で分岐
	ADDWF	PCL,F
	 GOTO	QNH_DECR		; 0 --
	 GOTO	RANGE_INCR		; 1 縮小
	 GOTO	RANGE_INCR		; 2 縮小
	 GOTO	MAINLOOP		; 3 無効
	 GOTO	MAINLOOP		; 4
	 GOTO	RANGE_INCR		; 5 縮小
	 GOTO	RANGE_INCR		; 6 縮小  7は省略
;------------------------------------------------------------------------------
procDIAL_INCR				; ダイアルプラス
	MOVF	MODE_CFG,W		; モード+ビュー番号で分岐
	ADDWF	PCL,F
	 GOTO	QNH_INCR		; 0 ++
	 GOTO	RANGE_DECR		; 1 拡大
	 GOTO	RANGE_DECR		; 2 拡大
	 GOTO	MAINLOOP		; 3 無効
	 GOTO	MAINLOOP		; 4
	 GOTO	RANGE_DECR		; 5 拡大
	 GOTO	RANGE_DECR		; 6 拡大   7は省略
;------------------------------------------------------------------------------
procSENSOR				; 計測
	CALL	retrieve
VIEW_REDRAW
	CLRF	PCLATH			; ■ PCLATH
	MOVF	MODE_CFG,W
	ADDWF	PCL,F
	 GOTO	ALT_0			; 0 高度・VSI
	 GOTO	ALT_1			; 1 高度グラフ
	 GOTO	BARO_2			; 2 気温グラフ
	 GOTO	ALT_0			; 3 無効、密度高度の予定
	 GOTO	BARO_0			; 4 気圧・気温計
	 GOTO	BARO_1			; 5 気圧グラフ
	 GOTO	BARO_2			; 6 気温グラフ   7は省略
;------------------------------------------------------------------------------
retrieve				; 計測データの取得
	BCF	FLAG1,I2C_RW		; Get P,T
	CALL	i2c_start
	MOVLW	OUT_P_MSB
	CALL	i2c_send
	BSF	FLAG1,I2C_RW
	CALL	i2c_start
	BCF	STATUS,IRP		; ● IRP=0
	MOVLW	P_MSB
	MOVWF	FSR
	MOVLW	5
	BTFSC	MODE_CFG,MODE
	 GOTO	HISTORY_UPDATE

	CALL	i2c_multi_recv		; 取得
	BCF	FLAG1,I2C_RW		; 高度計の時はVSIを取得
	CALL	i2c_start
	MOVLW	OUT_P_DELTA_MSB
	CALL	i2c_send
	BSF	FLAG1,I2C_RW
	CALL	i2c_start
	MOVLW	0x80
	BTFSC	ALT_CFG,VSI_AVG		; VSIの平均フラグがセットされている時は、VSI_P1フラグを反転
	 XORWF	FLAG1,F
	BTFSS	ALT_CFG,VSI_AVG		; VSIの平均フラグがセットされていない時は、VSI_P1フラグを毎回リセット
	 BCF	FLAG1,VSI_P1
	MOVLW	P0_MSB
	BTFSC	FLAG1,VSI_P1		; VSIをP0とP1の交互に書き込む
	 MOVLW	P1_MSB
	MOVWF	FSR
	MOVLW	3
HISTORY_UPDATE
	CALL	i2c_multi_recv		; 取得
	CALL	i2c_stop
	DECF	INT_COUNT,F
	BTFSS	STATUS,Z
	 RETURN				; グラフ更新が無い場合はリターン

	MOVLW	HIGH ALT_INTERVAL_TABLE
	MOVWF	PCLATH			; ■ PCLATH
	MOVF	ALT_INTERVAL,W
	BTFSC	MODE_CFG,MODE
	 MOVF	BARO_INTERVAL,W

	BTFSS	MODE_CFG,MODE
	 CALL	get_alt_interval
	BTFSC	MODE_CFG,MODE
	 CALL	get_baro_interval
	MOVWF	INT_COUNT		; カウンタリロード
	BSF	FLAG2,GRAPH_DRAW
	CLRF	PCLATH			; ■ PCLATH
HISTORY_DUMMY
	INCF	GRAPHPTR,F
	MOVLW	HISTORY_SIZE
	SUBWF	GRAPHPTR,W
	BTFSC	STATUS,C		; ポインタオフセットがロールオーバーしたなら
	 CLRF	GRAPHPTR		; ポインタを頭に戻す

	BTFSC	MODE_CFG,MODE		; モードに応じて履歴を更新
	 GOTO	HISTORY_BARO
HISTORY_ALT				; 高度は1m刻み、負の値は0mとして記録する。
	MOVF	P_CSB,W			; 小数点以下(P_LSB)は記録しない。
	BTFSC	P_MSB,7
	 CLRW
	MOVWF	TMP00			; TMP00はLSB
	MOVF	P_MSB,W
	BTFSC	P_MSB,7
	 CLRW
	MOVWF	TMP01			; TMP01はMSB
	GOTO	HISTORY_TEMP

HISTORY_BARO				; 気圧は25Pa刻み
	RLF	P_LSB,W
	MOVWF	MATH02
	RLF	P_CSB,W
	MOVWF	MATH00
	RLF	P_MSB,W			; 全体を2ビット左にずらしてQ18.2の18bit部分だけ抽出(1Pa以下を捨てる)
	MOVWF	MATH01
	RLF	MATH02,F
	RLF	MATH00,F
	RLF	MATH01,F
	RLF	MATH02,W
	ANDLW	3
	MOVWF	MATH02
	CLRF	MATH12
	CLRF	MATH11
	MOVLW	25
	MOVWF	MATH10
	CALL	div24			; 25で割る 101325/25=4053
	MOVF	MATH00,W		; LSB
	MOVWF	TMP00
	MOVF	MATH01,W		; MSB
	MOVWF	TMP01
HISTORY_TEMP
	MOVF	T_MSB,W			; 気温は0.25℃刻み、-13.75℃(0)-0(55)-50℃(255)で記録する。
	MOVWF	TMP02
	MOVF	T_LSB,W
	MOVWF	TMP03
	RLF	TMP03,F
	RLF	TMP02,F
	RLF	TMP03,F
	RLF	TMP02,F
	MOVLW	201			; 上限、下限チェック
	SUBWF	TMP02,W
	BTFSC	T_MSB,7
	 GOTO	HISTORY_TEMP_NEG
HISTORY_TEMP_POS			; 50度を超えていたら50度として記録
	MOVLW	200
	BTFSC	STATUS,C
	 MOVWF	TMP02
	GOTO	HISTORY_WRITE
HISTORY_TEMP_NEG			; -13.75度以下なら-13.75度として記録
	MOVLW	201
	BTFSS	STATUS,C
	 MOVWF	TMP02
HISTORY_WRITE
	MOVLW	55
	ADDWF	TMP02,F
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW PRESSBUF_LSB
	ADDWF	GRAPHPTR,W
	MOVWF	FSR
	MOVF	TMP00,W			; TMP00をLSBエリアへ
	MOVWF	INDF
	BSF	FSR,7
	MOVF	TMP01,W			; TMP01をMSBエリアへ
	MOVWF	INDF
	BCF	STATUS,IRP		; ● IRP=0
	MOVF	TMP02,W			; TMP02を気温エリアへ
	MOVWF	INDF
	RETURN
;------------------------------------------------------------------------------
ALT_0					; 高度・VSI
ALT_0_FEET_MAIN				; 高度(ft)
	BTFSC	ALT_CFG,ALT_UNIT
	 GOTO	ALT_0_FEET_SUB
	CLRF	LCD_Y
	MOVLW	24
	GOTO	ALT_0_FEET
ALT_0_FEET_SUB
	BTFSS	ALT_CFG,ALT_SUBDISP
	 GOTO	ALT_0_METER_MAIN
	MOVLW	2
	MOVWF	LCD_Y
	MOVLW	42
ALT_0_FEET
	CALL	mov_P_MCL_to_MATH020100
	CALL	alt2feet
	BTFSS	ALT_CFG,ALT_UNIT
	 CALL	puts16
	BTFSC	ALT_CFG,ALT_UNIT
	 CALL	puts8

ALT_0_METER_MAIN			; 高度(m)
	BTFSS	ALT_CFG,ALT_UNIT
	 GOTO	ALT_0_METER_SUB
	CLRF	LCD_Y
	MOVLW	24
	GOTO	ALT_0_METER
ALT_0_METER_SUB
	BTFSS	ALT_CFG,ALT_SUBDISP
	 GOTO	ALT_0_VSI
	MOVLW	2
	MOVWF	LCD_Y
	MOVLW	42
ALT_0_METER
	CALL	mov_P_MCL_to_MATH020100
	CALL	alt2meter
	BTFSC	ALT_CFG,ALT_UNIT
	 CALL	puts16
	BTFSS	ALT_CFG,ALT_UNIT
	 CALL	puts8

ALT_0_VSI				; VSI
	MOVF	P0_LSB,W
	MOVWF	MATH00
	MOVF	P0_CSB,W
	MOVWF	MATH01
	MOVF	P0_MSB,W
	MOVWF	MATH02
	BTFSS	ALT_CFG,VSI_AVG		; 平均は必要?
	 GOTO	ALT_0_VSI_NOAVG

	MOVF	P1_LSB,W		; 2回の履歴の平均を取る
	ADDWF	MATH00,F		; LSB
	BCF	STATUS,Z
	BTFSC	STATUS,C
	 INCF	MATH01,F
	BTFSC	STATUS,Z
	 INCF	MATH02,F
	MOVF	P1_CSB,W		; CSB
	ADDWF	MATH01,F
	BTFSC	STATUS,C
	 INCF	MATH02,F
	MOVF	P1_MSB,W		; MSB
	ADDWF	MATH02,F

	BCF	STATUS,C		; 符号付き/2
	BTFSC	MATH02,7
	 BSF	STATUS,C
	RRF	MATH02,F
	RRF	MATH01,F
	RRF	MATH00,F
ALT_0_VSI_NOAVG
	SWAPF	MATH00,W		; VSを保存しておく
	ANDLW	0x0F
	MOVWF	VS
	SWAPF	MATH01,W
	ANDLW	0xF0
	IORWF	VS,F
	BCF	FLAG2,VSI_SIGN
	BTFSC	MATH02,7
	 BSF	FLAG2,VSI_SIGN
	COMF	VS,W
	ADDLW	1
	BTFSC	FLAG2,VSI_SIGN
	 MOVWF	VS

	BSF	FLAG1,VSI
	MOVLW	3
	MOVWF	LCD_Y
	BTFSC	ALT_CFG,VSI_UNIT
	 GOTO	ALT_0_MPS
	MOVLW	24
	MOVWF	LCD_X

	CALL	altx100			; 符号判定
	CLRF	MATH12			; 分単位なのでALTx100_1の代わりに6000倍する
	MOVLW	0x17			; * 6000 (0x1770)
	MOVWF	MATH11
	MOVLW	0x70
	MOVWF	MATH10
	CALL	mul24
	CALL	altx100_2

	CALL	vsi_compensation
	CALL	alt2feet_for_fpm
	CALL	puts16

	MOVLW	HIGH txt_ft
	MOVWF	TMP21
	MOVLW	LOW txt_ft
	MOVWF	TMP20
	CALL	getstr
	MOVLW	66
	MOVWF	LCD_X
	CALL	puts8

	MOVLW	HIGH txt__m
	MOVWF	TMP21
	MOVLW	LOW txt__m
	GOTO	ALT_0_VSIDISP

ALT_0_MPS
	MOVLW	16
	MOVWF	LCD_X
	CALL	altx100
	CALL	altx100_1
	CALL	altx100_2
	CALL	vsi_compensation
	CALL	alt2meter_for_mps
	CALL	puts16

	MOVLW	HIGH txt_m
	MOVWF	TMP21
	MOVLW	LOW txt_m
	MOVWF	TMP20
	CALL	getstr
	MOVLW	72
	MOVWF	LCD_X
	CALL	puts8

	MOVLW	HIGH txt__s
	MOVWF	TMP21
	MOVLW	LOW txt__s
ALT_0_VSIDISP
	MOVWF	TMP20
	CALL	getstr
	INCF	LCD_Y,F			; =4
	CALL	puts8
	BCF	FLAG1,VSI
	BSF	PCLATH,3		; ■ PCLATH
	CALL	vsi_gauge
	CLRF	PCLATH			; ■ PCLATH
	GOTO	MAINLOOP

vsi_compensation
	CLRF	MATH12			; VSI 1秒誤差補正
	MOVLW	1
	BTFSC	CAL_VSI,7		; 補正値の7ビット目が1ならば、
	 CLRW				; 1.0以下として扱う。
	MOVWF	MATH11
	MOVF	CAL_VSI,W
	MOVWF	MATH10
	CALL	mul24			; *Q8.8
	RETURN

mov_P_MCL_to_MATH020100
	MOVWF	LCD_X
	MOVF	P_MSB,W
	MOVWF	MATH02
	MOVF	P_CSB,W
	MOVWF	MATH01
	MOVF	P_LSB,W
	MOVWF	MATH00
	RETURN
;------------------------------------------------------------------------------
ALT_1					; 高度グラフ
	CLRF	LCD_Y
	MOVLW	42
	CALL	mov_P_MCL_to_MATH020100
	BTFSC	ALT_CFG,ALT_UNIT
	 CALL	alt2meter
	BTFSS	ALT_CFG,ALT_UNIT
	 CALL	alt2feet
	CALL	puts8
	BTFSS	FLAG2,GRAPH_DRAW
	 GOTO	MAINLOOP

	CALL	GUIDE_COMMON
ALT1_YGUIDE
	INCF	ALT_RANGE,W		; 2^RANGE計算
	CALL	exp24
	CLRF	MATH10
	MOVF	TMP02,W
	ADDWF	OFFSET_L,W		; (TMP02 + OFFSET) * RANGE
	MOVWF	MATH11
	MOVF	OFFSET_M,W
	BTFSC	STATUS,C
	 INCF	OFFSET_M,W
	MOVWF	MATH12
ALT1_YGUIDE1
	CALL	mul24
	CLRF	LCD_X
	BTFSC	ALT_CFG,ALT_UNIT
	 GOTO	ALT1_Y_M
	CALL	alt2feet
	CALL	puts5
	GOTO	ALT1_YGUIDE2
ALT1_Y_M
	CALL	alt2meter
	CALL	puts8
ALT1_YGUIDE2
	CALL	GUIDE_COMMON2
	DECFSZ	TMP01,F
	 GOTO	ALT1_YGUIDE

DISP_INTERVAL
	BTFSC	MODE_CFG,MODE
	 GOTO	BARO_INT
	MOVLW	HIGH ALT_INTERVAL_TABLE
	MOVWF	PCLATH			; ■ PCLATH
	MOVF	ALT_INTERVAL,W
	CALL	get_alt_interval
	MOVWF	MATH00
	CLRF	PCLATH			; ■ PCLATH
	GOTO	INT_COMMON
BARO_INT
	MOVLW	HIGH BARO_INTERVAL_TABLE
	MOVWF	PCLATH			; ■ PCLATH
	MOVF	BARO_INTERVAL,W
	CALL	get_baro_interval
	MOVWF	MATH10
	MOVF	BARO_INTERVAL,W
	CALL	get_baro_st
	CLRF	PCLATH			; ■ PCLATH
	ADDLW	1
	CALL	exp24
	CALL	mul8
	MOVLW	60
	MOVWF	MATH10
	CLRF	MATH11
	CALL	div16
INT_COMMON
	CALL	set_strptr
	CALL	format_xx
	BTFSC	MODE_CFG,MODE
	 GOTO	INT_HR
	MOVLW	'm'
	CALL	store_INDF_inc_FSR
	MOVLW	'i'
	CALL	store_INDF_inc_FSR
	MOVLW	'n'
	MOVWF	INDF
	GOTO	INT_COMMON2
INT_HR
	MOVLW	'h'
	MOVWF	INDF
INT_COMMON2
	INCF	FSR,F
	CALL	HPA2STR2		; NULL終端、ゼロ置換
	CLRF	LCD_Y
	CALL	puts5
	BCF	FLAG2,YGUIDE
	GOTO	MAINLOOP

GUIDE_COMMON
	CALL	graph

	BSF	FLAG2,YGUIDE		; 軸ガイド
	MOVLW	3
	MOVWF	TMP01
	CLRF	TMP02
	MOVLW	5
	MOVWF	LCD_Y
	RETURN	

GUIDE_COMMON2
	MOVLW	20
	ADDWF	TMP02,F
	DECF	LCD_Y,F
	DECF	LCD_Y,F
	RETURN	

;------------------------------------------------------------------------------
BARO_0					; 気圧・気温計
BARO_0_HPA_MAIN				; 気圧(hPa)
	BTFSC	BARO_CFG,BARO_UNIT
	 GOTO	BARO_0_HPA_SUB
	CLRF	LCD_Y
	MOVLW	2
	GOTO	BARO_0_HPA
BARO_0_HPA_SUB
	BTFSS	BARO_CFG,BARO_SUBDISP
	 GOTO	BARO_0_INCH_MAIN
	MOVLW	2
	MOVWF	LCD_Y
	MOVLW	24
BARO_0_HPA
	MOVWF	LCD_X
	CALL	baro2hpa
	BTFSS	BARO_CFG,BARO_UNIT
	 CALL	puts16
	BTFSC	BARO_CFG,BARO_UNIT
	 CALL	puts8

BARO_0_INCH_MAIN
	BTFSS	BARO_CFG,BARO_UNIT	; 気圧(in)
	 GOTO	BARO_0_INCH_SUB
	CLRF	LCD_Y
	MOVLW	18
	GOTO	BARO_0_INCH
BARO_0_INCH_SUB
	BTFSS	BARO_CFG,BARO_SUBDISP
	 GOTO	BARO_0_CELSIUS_MAIN
	MOVLW	2
	MOVWF	LCD_Y
	MOVLW	42
BARO_0_INCH
	MOVWF	LCD_X
	CALL	baro2inch
	BTFSC	BARO_CFG,BARO_UNIT
	 CALL	puts16
	BTFSS	BARO_CFG,BARO_UNIT
	 CALL	puts8

BARO_0_CELSIUS_MAIN			; 気温(摂氏)
	BTFSC	TEMP_CFG,TEMP_UNIT
	 GOTO	BARO_0_CELSIUS_SUB
	MOVLW	3
	MOVWF	LCD_Y
	MOVLW	10
	GOTO	BARO_0_CELSIUS
BARO_0_CELSIUS_SUB
	BTFSS	BARO_CFG,BARO_SUBDISP
	 GOTO	BARO_0_FAHRENHEIT_MAIN
	MOVLW	5
	MOVWF	LCD_Y
	MOVLW	36
BARO_0_CELSIUS
	MOVWF	LCD_X
	MOVF	T_MSB,W
	MOVWF	MATH01
	MOVF	T_LSB,W
	MOVWF	MATH00
	CALL	temp2celsius
	BTFSS	TEMP_CFG,TEMP_UNIT
	 CALL	puts16
	BTFSC	TEMP_CFG,TEMP_UNIT
	 CALL	puts8

BARO_0_FAHRENHEIT_MAIN			; 気温(華氏)
	BTFSS	TEMP_CFG,TEMP_UNIT
	 GOTO	BARO_0_FAHRENHEIT_SUB
	MOVLW	3
	MOVWF	LCD_Y
	MOVLW	10
	GOTO	BARO_0_FAHRENHEIT
BARO_0_FAHRENHEIT_SUB
	BTFSS	BARO_CFG,BARO_SUBDISP
	 GOTO	BARO_0_END
	MOVLW	5
	MOVWF	LCD_Y
	MOVLW	36
BARO_0_FAHRENHEIT
	MOVWF	LCD_X
	MOVF	T_MSB,W
	MOVWF	MATH01
	MOVF	T_LSB,W
	MOVWF	MATH00
	CALL	temp2fahrenheit
	BTFSC	TEMP_CFG,TEMP_UNIT
	 CALL	puts16
	BTFSS	TEMP_CFG,TEMP_UNIT
	 CALL	puts8
BARO_0_END
	GOTO	MAINLOOP

;------------------------------------------------------------------------------
BARO_1					; 気圧グラフ
	CLRF	LCD_Y
	BTFSC	BARO_CFG,BARO_UNIT
	 GOTO	BARO_1_INCH
BARO_1_HPA
	CALL	baro2hpa
	MOVLW	24
	GOTO	BARO1_GRAPH
BARO_1_INCH
	CALL	baro2inch
	MOVLW	42
BARO1_GRAPH
	MOVWF	LCD_X
	CALL	puts8
	BTFSS	FLAG2,GRAPH_DRAW
	 GOTO	MAINLOOP

	CALL	GUIDE_COMMON
BARO1_YGUIDE
	INCF	BARO_RANGE,W		; 25 << RANGE 計算
	MOVWF	TMP03			; 25,50,100のどれかになる
	MOVLW	25
	MOVWF	MATH00
BARO1_YGUIDE1
	DECF	TMP03,F
	BTFSC	STATUS,Z
	 GOTO	BARO1_YGUIDE2
	BCF	STATUS,C
	RLF	MATH00,F
	GOTO	BARO1_YGUIDE1
BARO1_YGUIDE2
	CLRF	MATH01
	MOVF	TMP02,W
	ADDWF	OFFSET_L,W		; (TMP02 + OFFSET) * RANGE
	MOVWF	MATH10
	MOVF	OFFSET_M,W
	BTFSC	STATUS,C
	 INCF	OFFSET_M,W
	MOVWF	MATH11
BARO1_YGUIDE3
	CALL	mul16
	CLRF	LCD_X
	BTFSC	BARO_CFG,BARO_UNIT
	 GOTO	BARO1_Y_IN
	CALL	hpa2str
	CALL	puts8
	GOTO	BARO1_YGUIDE4
BARO1_Y_IN
	MOVF	MATH02,W
	MOVWF	MATH03
	MOVF	MATH01,W
	MOVWF	MATH02
	MOVF	MATH00,W
	MOVWF	MATH01
	CLRF	MATH00
	CALL	convert_hpa2inch
	CALL	inch2str
	CALL	puts5
BARO1_YGUIDE4
	CALL	GUIDE_COMMON2
	DECFSZ	TMP01,F
	 GOTO	BARO1_YGUIDE
	GOTO	DISP_INTERVAL
;------------------------------------------------------------------------------
BARO_2					; 気温グラフ
	MOVLW	36
	MOVWF	LCD_X
	CLRF	LCD_Y
	MOVF	T_MSB,W
	MOVWF	MATH01
	MOVF	T_LSB,W
	MOVWF	MATH00
	BTFSS	TEMP_CFG,TEMP_UNIT
	 CALL	temp2celsius
	BTFSC	TEMP_CFG,TEMP_UNIT
	 CALL	temp2fahrenheit
	CALL	puts8
	BTFSS	FLAG2,GRAPH_DRAW
	 GOTO	MAINLOOP

	CALL	GUIDE_COMMON
BARO2_YGUIDE
	INCF	TEMP_RANGE,W		; 2^RANGE計算
	CALL	exp24
	CLRF	MATH10
	MOVF	TMP02,W			; (TMP02 + OFFSET) * RANGE
	ADDWF	OFFSET_L,W
	MOVWF	MATH11
	CLRF	MATH12
	BTFSC	STATUS,C
	 INCF	MATH12,F
BARO2_YGUIDE1
	CALL	mul24
	MOVLW	55
	SUBWF	MATH01,F
	MOVLW	1
	BTFSS	STATUS,C
	 SUBWF	MATH02,F
	MOVLW	3
	BTFSS	STATUS,C
	 MOVWF	MATH02
	RRF	MATH02,F
	RRF	MATH01,F
	RRF	MATH00,F
	RRF	MATH02,F
	RRF	MATH01,F
	RRF	MATH00,F
	CLRF	LCD_X
	BTFSS	TEMP_CFG,TEMP_UNIT
	 CALL	temp2celsius
	BTFSC	TEMP_CFG,TEMP_UNIT
	 CALL	temp2fahrenheit
	CALL	puts5
	CALL	GUIDE_COMMON2
	DECFSZ	TMP01,F
	 GOTO	BARO2_YGUIDE
	GOTO	DISP_INTERVAL
	
;------------------------------------------------------------------------------
; QNH変更、EEPROMセーブ、画面表示
;------------------------------------------------------------------------------
QNH_DECR
	MOVF	QNH_MSB,W		; 下限チェック
	BTFSS	STATUS,Z
	 GOTO	QNH_DECR1
	MOVF	QNH_LSB,W
	BTFSC	STATUS,Z
	 GOTO	MAINLOOP
QNH_DECR1
	MOVLW	1
	SUBWF	QNH_LSB,F
	BTFSS	STATUS,C
	 DECF	QNH_MSB,F
QNH_CHANGE
	BCF	STATUS,IRP
	MOVLW	QNH_MSB
	MOVWF	FSR
	MOVLW	EE_QNH_MSB
	MOVWF	_EEADDR
	MOVLW	2
	CALL	write_ee_data
	CALL	send_QNH
	CALL	disp_qnh
	GOTO	MAINLOOP

QNH_INCR
	MOVLW	0x0F			; 上限チェック
	BTFSC	ALT_CFG,QNH_UNIT	; Max=38.70in(0x0F1E)、131,070Pa(0xFFFF)
	 MOVLW	0xFF
	SUBWF	QNH_MSB,W
	BTFSS	STATUS,C
	 GOTO	QNH_INCR1
	MOVLW	0x1E
	BTFSC	ALT_CFG,QNH_UNIT
	 MOVLW	0xFF
	SUBWF	QNH_LSB,W
	BTFSC	STATUS,C
	 GOTO	MAINLOOP
QNH_INCR1
	MOVLW	1
	ADDWF	QNH_LSB,F
	BTFSC	STATUS,C
	 INCF	QNH_MSB,F
	GOTO	QNH_CHANGE

;------------------------------------------------------------------------------
; グラフレンジ変更、EEPROMセーブ、グラフ再描画
;------------------------------------------------------------------------------
RANGE_DECR
	CALL	load_range
	MOVF	INDF,W			; 下限チェック
	BTFSC	STATUS,Z
	 GOTO	RANGE_NOCHANGE		; 既にゼロ、MAINLOOPに戻してもいいかも
	DECF	INDF,F
RANGE_CHANGE
	MOVLW	EE_ALT_RANGE
	BTFSC	MODE_CFG,MODE		; BARO-1or2
	 MOVLW	EE_BARO_RANGE
	BTFSC	MODE_CFG,VIEW1		; ALT-2,BARO-2
	 MOVLW	EE_TEMP_RANGE
	MOVWF	_EEADDR
	MOVLW	1
	CALL	write_ee_data
RANGE_NOCHANGE
	BSF	FLAG2,OFFSET_INIT
	BSF	FLAG2,GRAPH_DRAW
	GOTO	VIEW_REDRAW

RANGE_INCR
	CALL	load_range
	DECF	MODE_CFG,W
	MOVLW	7			; 上限チェック 7 or 2
	BTFSS	STATUS,Z
	 MOVLW	2
	SUBWF	INDF,W
	BTFSC	STATUS,C
	 GOTO	RANGE_NOCHANGE		; 既に上限、MAINLOOPに戻してもいいかも
	INCF	INDF,F
	GOTO	RANGE_CHANGE

load_range
	BCF	STATUS,IRP		; ● IRP=0
	MOVLW	ALT_RANGE
	BTFSC	MODE_CFG,MODE		; BARO-1or2
	 MOVLW	BARO_RANGE
	BTFSC	MODE_CFG,VIEW1		; ALT-2,BARO-2
	 MOVLW	TEMP_RANGE
	MOVWF	FSR
	RETURN
;------------------------------------------------------------------------------
disp_qnh				; QNH表示
	CALL	qnh_to_string
	MOVLW	27
	BTFSC	ALT_CFG,QNH_UNIT
	 MOVLW	18
	MOVWF	LCD_X
	MOVLW	5
	MOVWF	LCD_Y
	CALL	puts8
	RETURN
;------------------------------------------------------------------------------
; 汎用グラフ作成
;
; 引数
;	GRAPHPTR	データポインタ
;
; 戻り値
;	OFFSET_L	ドットオフセット
;	OFFSET_M
;
; 使用変数
;	TMP00,01,02,03,MATH00,01,10,11,20,21,LCD_X,LCD_Y
;------------------------------------------------------------------------------
graph
	BCF	STATUS,IRP		; ● IRP=0
	MOVLW	ALT_CFG			; グラフタイプ判定
	BTFSC	MODE_CFG,MODE		; BARO-1or2
	 MOVLW	BARO_CFG
	BTFSC	MODE_CFG,VIEW1		; ALT-2,BARO-2
	 MOVLW	TEMP_CFG
	MOVWF	FSR
	BCF	FLAG2,GRAPHTYPE
	BTFSC	INDF,ALT_GTYPE
	 BSF	FLAG2,GRAPHTYPE

	BTFSC	FLAG2,OFFSET_INIT	; オフセット初期化の場合オフセットの更新をしない
	 BCF	FLAG2,OFFSET_UPDATE
	BTFSC	INDF,ALT_YTYPE		; ALTモードで絶対表示の場合はオフセットの更新をしない
	 BCF	FLAG2,OFFSET_UPDATE

	MOVLW	HISTORY_SIZE		; TMP00=60回ループカウンタ
	MOVWF	TMP00
	MOVF	GRAPHPTR,W		; TMP01=データポインタ
	MOVWF	TMP01
	MOVLW	83
	MOVWF	LCD_X

	BTFSS	MODE_CFG,VIEW1
	 BSF	STATUS,IRP		; ● IRP=1
GRAPH_X					; Xループ グラフデータ取得
	MOVLW	LOW PRESSBUF_LSB
	BTFSC	MODE_CFG,VIEW1
	 MOVLW	TEMPBUF
	ADDWF	TMP01,W
	MOVWF	FSR
	MOVF	INDF,W			; LSB
	MOVWF	MATH00
	BSF	FSR,7
	MOVF	INDF,W			; MSB
	MOVWF	MATH01
	INCF	ALT_RANGE,W		; ビットシフトで割り算
	BTFSC	MODE_CFG,MODE
	 INCF	BARO_RANGE,W
	BTFSC	MODE_CFG,VIEW1
	 INCF	TEMP_RANGE,W
	MOVWF	TMP03
RETR_PRESS_1
	DECF	TMP03,F
	BTFSC	STATUS,Z
	 GOTO	RETR_PRESS_2		; break
	BCF	STATUS,C
	BTFSS	MODE_CFG,VIEW1
	 RRF	MATH01,F
	RRF	MATH00,F
	GOTO	RETR_PRESS_1
RETR_PRESS_2
	BTFSC	MODE_CFG,VIEW1
	 CLRF	MATH01
	BTFSC	MODE_CFG,VIEW1		; ALT-2,BARO-2
	 GOTO	OFFSET_CHECK		; 気温は無条件で相対値モード
	BTFSS	MODE_CFG,MODE
	 BTFSS	ALT_CFG,ALT_YTYPE
	GOTO	OFFSET_CHECK		; 相対値モードの時
	CLRF	OFFSET_L		; 絶対値モードの時
	CLRF	OFFSET_M		; オフセットは強制的にゼロにする
	GOTO	RETURN_VALUE

OFFSET_CHECK				; データ取得後に表示範囲を逸脱していないかチェック
	BTFSC	FLAG2,OFFSET_INIT	; オフセットの初期化が指示されている場合は初期化を優先して行う
	 GOTO	OFFSET_INITIALIZE
	BTFSS	FLAG2,OFFSET_UPDATE	; オフセットの更新指示が無い場合そのままリターン
	 GOTO	RETURN_VALUE
	BCF	FLAG2,OFFSET_UPDATE	; オフセットの更新は一番新しいデータ処理時のみ実行される

	MOVF	OFFSET_L,W		; 実際の値から(オフセット + OFFSET_MARGIN)を引いて0以下になる時はOFFSET_LESS
	MOVWF	MATH10			; OFFSET = OFFSET + OFFSET_MARGIN
	MOVF	OFFSET_M,W
	MOVWF	MATH11
	MOVLW	OFFSET_MARGIN
	MOVWF	MATH20
	CLRF	MATH21
	CALL	add16
	MOVF	MATH00,W		; 実際の値が破壊されないように作業用の変数で計算する
	MOVWF	MATH20			; VALUE = VALUE - OFFSET
	MOVF	MATH01,W
	MOVWF	MATH21
	CALL	sub16	
	BTFSS	STATUS,C
	 GOTO	OFFSET_LESS
	CLRF	MATH11			; さらに(表示範囲-マージン)を引いて0以上になる場合OFFSET_GRATER
	MOVLW	39-(OFFSET_MARGIN*2-1)
	MOVWF	MATH10
	CALL	sub16
	BTFSS	STATUS,C
	 GOTO	RETURN_VALUE
OFFSET_GRATER				; オフセットが小さすぎて表示範囲を上回るとき
	MOVLW	39-(OFFSET_MARGIN*2)+OFFSET_MARGIN
	GOTO	OFFSET_CALC
OFFSET_LESS				; オフセットが大きすぎて表示範囲を下回るとき
	MOVLW	OFFSET_MARGIN		; オフセット = 実際の値 - OFFSET_MARGIN とする
	GOTO	OFFSET_CALC
	
OFFSET_INITIALIZE			; オフセットの初期化
	BCF	FLAG2,OFFSET_INIT	; オフセットは実際の値-20とし、20ドット目(50%)に初期ドットを持ってくる
	MOVLW	20			; オフセット = 実際の数 - 20
OFFSET_CALC
	MOVWF	MATH10
	CLRF	MATH11
	MOVF	MATH00,W		; 実際の値が破壊されないように作業用の変数で計算する
	MOVWF	MATH20
	MOVF	MATH01,W
	MOVWF	MATH21
	CALL	sub16
	MOVF	MATH20,W
	MOVWF	OFFSET_L
	MOVF	MATH21,W
	MOVWF	OFFSET_M
	BTFSC	STATUS,C		; ただしオフセットが0を下回るときはオフセット=0とする
	 GOTO	RETURN_VALUE
	CLRF	OFFSET_M
	CLRF	OFFSET_L
RETURN_VALUE
	MOVF	OFFSET_L,W		; オフセットを引く
	SUBWF	MATH00,F
	MOVF	OFFSET_M,W
	BTFSS	STATUS,C
	 INCF	OFFSET_M,W
	SUBWF	MATH01,F
	BTFSC	STATUS,C
	 GOTO	RETURN_VALUE_1
	CLRF	MATH00			; マイナスになった時=0
	CLRF	MATH01
RETURN_VALUE_1
	MOVLW	39			; 39以上か?
	MOVF	MATH01,F
	BTFSS	STATUS,Z
	 MOVWF	MATH00
	SUBWF	MATH00,W
	MOVLW	39			; 39以上なら39にセット
	BTFSC	STATUS,C
	 MOVWF	MATH00			; 戻り値
GRAPH_RETR_RETURN			; MATH00にデータが入って戻ってくる
	MOVF	MATH00,W
	SUBLW	47
	MOVWF	MATH00
	RLF	MATH00,W		; ドット部分3bitと行部分5bitを分離する
	ANDLW	0xF0
	MOVWF	MATH01
	SWAPF	MATH01,F		; MATH01は行部分
	MOVLW	7
	ANDWF	MATH00,F		; MATH00はドット部分
	MOVLW	1			; 1行目へ移動し、アドレスの自動インクリメントを縦方向に変更。
	MOVWF	LCD_Y
	CALL	lcd_locate
	MOVLW	B'00100010'		; Function Set(Power_On, V_addr, Basic_Inst)
	CALL	lcd_command
GRAPH_Y					; Yループ
	MOVF	MATH01,W		; ドットのある行はLCDの表示行と同じか?
	SUBWF	LCD_Y,W
	BTFSC	STATUS,Z
	 GOTO	DOT_SHIFT		; 同じならドットの処理へ
	CLRW				; 違うなら空白ドット
	BTFSS	FLAG2,GRAPHTYPE
	 GOTO	DOT_DISP
	BTFSC	STATUS,C		; ただし、バー表示でドット行より下の場合は塗りつぶす
	 MOVLW	0xFF
	GOTO	DOT_DISP
DOT_SHIFT
	INCF	MATH00,F		; ドットの位置によって点の位置をシフトしていく
	CLRW
	BTFSC	FLAG2,GRAPHTYPE		; ただし、バー表示では塗りつぶしでシフトする
	 MOVLW	0xFF
	MOVWF	TMP02			; TMP02=描画パターン
	BSF	STATUS,C		; ドットの種
DOT_SHIFT_LP				; ドット位置回数分シフトループ
	RLF	TMP02,F
	BTFSC	FLAG2,GRAPHTYPE
	 BCF	STATUS,C
	DECFSZ	MATH00,F
	 GOTO	DOT_SHIFT_LP
	MOVF	TMP02,W
DOT_DISP
	CALL	lcd_data
	INCF	LCD_Y,F			; 行をインクリメント
	MOVLW	6
	SUBWF	LCD_Y,W
	BTFSS	STATUS,Z
	 GOTO	GRAPH_Y			; Yループ閉
	DECF	LCD_X,F			; 新しいものから古いものに向かって左向きに描画
	MOVLW	1
	SUBWF	TMP01,W
	BTFSS	STATUS,C		; ポインタがロールオーバーしたなら
	 MOVLW	HISTORY_SIZE-1
	MOVWF	TMP01			; ポインタを修正
	DECFSZ	TMP00,F
	 GOTO	GRAPH_X			; Xループ閉じ
	RETURN
;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■■ 算術演算ルーチン ■■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; 24bit べき乗
;
; 引数
;	W	乗数(0〜7)
;
; 戻り値
;	MATH00	LSB
;	MATH01	   (0)
;	MATH02	MSB(0)
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
exp24
	MOVWF	MATH01
	CLRF	MATH00
	BSF	STATUS,C		; 種
EXP_LOOP
	RLF	MATH00,F
	BCF	STATUS,C
	DECFSZ	MATH01,F
	 GOTO	EXP_LOOP
	CLRF	MATH01
	CLRF	MATH02
	RETURN
;------------------------------------------------------------------------------
; 16bit 足し算 MATH1 = MATH1 + MATH2
;
; 引数
;	MATH10	LSB 足される数
;	MATH11	MSB
;	MATH20	LSB 足す数(非破壊)
;	MATH21	MSB
;
; 戻り値
;	MATH10	LSB 和
;	MATH11	MSB
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
add16
	MOVF	MATH20,W
	ADDWF	MATH10,F
	MOVF	MATH21,W
	BTFSC	STATUS,C
	 INCF	MATH21,W		; 桁上がりした+1を含めて加算するとCフラグも使えるようになる
	ADDWF	MATH11,F
	RETURN

;------------------------------------------------------------------------------
; 16bit 引き算 MATH2 = MATH2 - MATH1
;
; 引数
;	MATH20	LSB 引かれる数
;	MATH21	MSB
;	MATH10	LSB 引く数(非破壊)
;	MATH11	MSB
;
; 戻り値
;	MATH20	LSB 差
;	MATH21	MSB
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
sub16
	MOVF	MATH10,W
	SUBWF	MATH20,F
	MOVF	MATH11,W
	BTFSS	STATUS,C
	 INCF	MATH11,W		; 桁落ちした-1を含めて減算するとZ,C両方のフラグが使える
	SUBWF	MATH21,F
	RETURN

;------------------------------------------------------------------------------
; 8bit 掛け算 http://elm-chan.org/docs/avrlib/mul08.txt
;
; 引数
;	MATH00	掛けられる数
;	MATH10	掛ける数(非破壊)
;
; 戻り値
;	MATH00	LSB 積
;	MATH01	MSB
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
mul8
	CLRF	MATH01			; sub	var11,var11	initialize variables
	MOVLW	9			; ldi	lc,9		lc = 9;
	MOVWF	TMP20
	BCF	STATUS,C
MUL8_1					; ---- calcurating loop
	BTFSS	STATUS,C		; brcc	PC+2
	 GOTO	MUL8_2
	MOVF	MATH10,W		; add	var11,var20
	ADDWF	MATH01,F
MUL8_2
	RRF	MATH01,F		; ror	var11
	RRF	MATH00,F		; ror	var10
	DECFSZ	TMP20,F			; dec	lc		if (--lc > 0)
	 GOTO	MUL8_1			; brne	PC-5		  continue loop;
	RETURN

;------------------------------------------------------------------------------
; 16bit 掛け算 http://elm-chan.org/docs/avrlib/mul16.txt
;
; 引数
;	MATH00	LSB 掛けられる数
;	MATH01	MSB
;	MATH10	LSB 掛ける数(非破壊)
;	MATH11	MSB
;
; 戻り値
;	MATH00	LSB 積
;	MATH01
;	MATH02
;	MATH03	MSB
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
mul16
	CLRF	MATH03			; sub	var13,var13	initialize variables
	CLRF	MATH02			; sub	var12,var12
	MOVLW	17			; ldi	lc,17		lc = 17;
	MOVWF	TMP20
	BCF	STATUS,C
MUL16_1					; ---- calcurating loop
	BTFSS	STATUS,C		; brcc	PC+3
	 GOTO	MUL16_2
	MOVF	MATH10,W		; add	var12,var20
	ADDWF	MATH02,F
	MOVF	MATH11,W		; adc	var13,var21
	BTFSC	STATUS,C		;  Cフラグを足す
	 INCF	MATH11,W
	ADDWF	MATH03,F
MUL16_2
	RRF	MATH03,F		; ror	var13
	RRF	MATH02,F		; ror	var12
	RRF	MATH01,F		; ror	var11
	RRF	MATH00,F		; ror	var10
	DECFSZ	TMP20,F
	 GOTO	MUL16_1
	RETURN

;------------------------------------------------------------------------------
; 24bit 掛け算
;
; 引数
;	MATH00	LSB 掛けられる数
;	MATH01
;	MATH02	MSB
;	MATH10	LSB 掛ける数(非破壊)
;	MATH11
;	MATH12	MSB
;
; 戻り値
;	MATH00	LSB 積
;	MATH01
;	MATH02
;	MATH03
;	MATH04		(MATH20と共用)
;	MATH05	MSB	(MATH21と共用)
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
mul24
	CLRF	MATH05
	CLRF	MATH04
	CLRF	MATH03
	MOVLW	25
	MOVWF	TMP20
	BCF	STATUS,C
MUL24_1
	BTFSS	STATUS,C
	 GOTO	MUL24_2
	MOVF	MATH10,W
	ADDWF	MATH03,F
	MOVF	MATH11,W
	BTFSC	STATUS,C
	 INCF	MATH11,W
	ADDWF	MATH04,F
	MOVF	MATH12,W
	BTFSC	STATUS,C
	 INCF	MATH12,W
	ADDWF	MATH05,F
MUL24_2
	RRF	MATH05,F
	RRF	MATH04,F
	RRF	MATH03,F
	RRF	MATH02,F
	RRF	MATH01,F
	RRF	MATH00,F
	DECFSZ	TMP20,F
	 GOTO	MUL24_1
	RETURN

;------------------------------------------------------------------------------
; 8bit 割り算 http://elm-chan.org/docs/avrlib/div08.txt
;
; 引数
;	MATH00	割られる数(0x00..0xff)
;	MATH10	割る数(0x01..0x7f)(非破壊)
;
; 戻り値
;	MATH00	商
;	MATH20	余り
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
div8
	CLRF	MATH20			; clr	mod		initialize variables
	MOVLW	8			; ldi	lc,8		mod = 0;
	MOVWF	TMP20			;			lc = 8;
DIV8_1					; ---- calcurating loop
	BCF	STATUS,C		; lsl	var1		var1 = var1 << 1;
	RLF	MATH00,F
	RLF	MATH20,F		; rol	mod		mod = mod << 1 + carry;
	MOVF	MATH10,W		; cp	mod,var2	if (mod < var2) {
	SUBWF	MATH20,W
	BTFSS	STATUS,C
	 GOTO	DIV8_2			; brcs	PC+3		} else {
	INCF	MATH00,F		; inc	var1		  var1++;
	MOVWF	MATH20			; sub	mod,var2	  mod -= var2;
DIV8_2					;			}
	DECFSZ	TMP20,F			; dec	lc		if (--lc > 0)
	 GOTO	DIV8_1			; brne	PC-7		  continue loop;
	RETURN

;------------------------------------------------------------------------------
; 16bit 割り算 http://elm-chan.org/docs/avrlib/div16.txt
;
; 引数
;	MATH00	LSB 割られる数(0x0000..0xffff)
;	MATH01	MSB
;	MATH10	LSB 割る数(0x0001..0x7fff)(非破壊)
;	MATH11	MSB
;
; 戻り値
;	MATH00	LSB 商
;	MATH01	MSB
;	MATH20	LSB 余り
;	MATH21	MSB
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
div16
	CLRF	MATH20		; clr	mod0		initialize variables
	CLRF	MATH21		; clr	mod1		mod = 0;
	MOVLW	16		; ldi	lc,16		lc = 16;
	MOVWF	TMP20
DIV16_1					;---- calcurating loop
	BCF	STATUS,C	; lsl	var10		var1 = var1 << 1;
	RLF	MATH00,F
	RLF	MATH01,F	; rol	var11
	RLF	MATH20,F	; rol	mod0		mod = mod << 1 + carry;
	RLF	MATH21,F	; rol	mod1
	MOVF	MATH10,W	; cp	mod0,var20	if (mod < var2) {
	SUBWF	MATH20,W
	MOVF	MATH11,W
	BTFSS	STATUS,C	; cpc	mod1,var21
	 INCF	MATH11,W	;  Cフラグを足す
	SUBWF	MATH21,W
	BTFSS	STATUS,C
	 GOTO	DIV16_2		; brcs	PC+4		} else {
	INCF	MATH00,F	; inc	var10		  var1++;
	MOVF	MATH10,W	; sub	mod0,var20	  mod -= var2;
	SUBWF	MATH20,F
	MOVF	MATH11,W	; sbc	mod1,var21
	BTFSS	STATUS,C	;  Cフラグを足す
	 INCF	MATH11,W
	SUBWF	MATH21,F
DIV16_2					;			}
	DECFSZ	TMP20,F		; dec	lc		if (--lc > 0)
	 GOTO	DIV16_1		; brne	PC-11		  continue loop;
	RETURN
;------------------------------------------------------------------------------
; 24bit 割り算 http://www.piclist.com/techref/microchip/math/div/24by24tn.htm
;
; 引数
;	MATH00	LSB 割られる数
;	MATH01
;	MATH02	MSB
;	MATH10	LSB 割る数(非破壊)
;	MATH11
;	MATH12	MSB
;
; 戻り値
;	MATH00	LSB 商
;	MATH01
;	MATH02	MSB
;	MATH20	LSB 余り
;	MATH21
;	MATH22	MSB
;
; 使用変数
;	TMP20,MATH30-32
;------------------------------------------------------------------------------
BCount		EQU	TMP20
nratorL		EQU	MATH00	; Numerator / Result
nratorM		EQU	MATH01
nratorH		EQU	MATH02
denomL		EQU	MATH10	; Denominator
denomM		EQU	MATH11
denomH		EQU	MATH12
remainL		EQU	MATH20	; Remainder
remainM		EQU	MATH21
remainH		EQU	MATH22
shiftL		EQU	MATH30	; Temporary
shiftM		EQU	MATH31
shiftH		EQU	MATH32

div24
	MOVLW	24		; set decimal 24 loop count
	MOVWF	BCount
	MOVF	nratorH,W	; copy Numerator into Shift Holding ram registers
	MOVWF	shiftH
	MOVF	nratorM,W
	MOVWF	shiftM
	MOVF	nratorL,W
	MOVWF	shiftL
	CLRF	nratorH		;  clear final Answer Numerator Ram locations
	CLRF	nratorM
	CLRF	nratorL
	
	CLRF	remainH		;  clear final Answer Remainder Ram locations
	CLRF	remainM
	CLRF	remainL
DLOOP24
	BCF	STATUS,C	; bit clear Carry Flag in STATUS register
	RLF	shiftL,F	; Shift numerator(dividend) Left to move
	RLF	shiftM,F	; next bit to remainder
	RLF	shiftH,F	; and shift in next bit of result

	RLF	remainL,F	; shift carry (next Dividend bit) into remainder
	RLF	remainM,F
	RLF	remainH,F

	MOVF	denomH,W
	SUBWF	remainH,W	; subtract divsor(denomH) from(newly shifted left) Remainder HIGH byte.
	BTFSS	STATUS,Z
	 GOTO	NOCHK24		; skip if result was ZERO from good subtraction result

	MOVF	denomM,W
	SUBWF	remainM,W	; subtract divsor(denomM) from(newly shifted left) Remainder MIDDLE byte.
	BTFSS	STATUS,Z
	 GOTO	NOCHK24		; skip if result was ZERO from good subtraction result
	
	MOVF	denomL,W
	SUBWF	remainL,W	; subtract divsor(denomL) from(newly shifted left) Remainder LOW byte.
NOCHK24
	BTFSS	STATUS,C	;  Carry SET? then denom is larger than reemainder
	 GOTO	NOGO24

	MOVF	denomL,W			 
	SUBWF	remainL,F	; Subtract denominator from remainder value in Low Byte
	BTFSC	STATUS,C	; Carry Set? Then execute fixup code for when a borrow is generated
	 GOTO	NODEC_remainM24	; when no borrow bit is needed from the higher byte positions.
	DECF	remainM,F	; Decrement to Borrow from Middle Byte, because carry was SET.
	COMF	remainM,W	; Check if rollover from Borrow occurred. remainM value went from 0 to 0xFF
	BTFSC	STATUS,Z
	 DECF	remainH,F	; ZERO bit set, yes rollover, so Decrement to Borrow from High Byte, too!
NODEC_remainM24
	MOVF	denomM,W
	SUBWF	remainM,F	; Subtract denominator from remainder value in Middle Byte
	BTFSS	STATUS,C
	 DECF	remainH,F	; Decrement High Byte, to borrow 1 bit
	MOVF	denomH,W   		 
	SUBWF	remainH,F	; Subtract denominator from remainder value in High Byte
	BSF	STATUS,C	; set CARRY bit to rotate in Numerator Result next.
NOGO24
	RLF	nratorL,F	; rotate Numerator result left 1 bit
	RLF	nratorM,F
	RLF	nratorH,F
	DECFSZ	BCount,F	; decrement the Loop Bit Counter
	 GOTO	DLOOP24
	RETURN
;------------------------------------------------------------------------------
; 32bit 割り算 http://www.piclist.com/techref/microchip/math/div/24by24tn.htmから変形
;
; 引数
;	MATH00	LSB 割られる数
;	MATH01
;	MATH02
;	MATH03	MSB
;	MATH10	LSB 割る数(非破壊)
;	MATH11
;	MATH12
;	MATH13	MSB
;
; 戻り値
;	MATH00	LSB 商
;	MATH01
;	MATH02
;	MATH03	MSB
;	MATH20	LSB 余り
;	MATH21
;	MATH22
;	MATH23	MSB
;
; 使用変数
;	TMP20,MATH30-33
;------------------------------------------------------------------------------
nratorHH	EQU	MATH03
denomHH		EQU	MATH13
remainHH	EQU	MATH23
shiftHH		EQU	MATH33

div32
	MOVLW	32		; set decimal 32 loop count
	MOVWF	BCount
	MOVF	nratorHH,W	; copy Numerator into Shift Holding ram registers
	MOVWF	shiftHH
	MOVF	nratorH,W	; copy Numerator into Shift Holding ram registers
	MOVWF	shiftH
	MOVF	nratorM,W
	MOVWF	shiftM
	MOVF	nratorL,W
	MOVWF	shiftL
	CLRF	nratorHH		;  clear final Answer Numerator Ram locations
	CLRF	nratorH
	CLRF	nratorM
	CLRF	nratorL
	
	CLRF	remainHH		;  clear final Answer Remainder Ram locations
	CLRF	remainH
	CLRF	remainM
	CLRF	remainL
DLOOP32
	BCF	STATUS,C	; bit clear Carry Flag in STATUS register
	RLF	shiftL,F	; Shift numerator(dividend) Left to move
	RLF	shiftM,F	; next bit to remainder
	RLF	shiftH,F
	RLF	shiftHH,F	; and shift in next bit of result

	RLF	remainL,F	; shift carry (next Dividend bit) into remainder
	RLF	remainM,F
	RLF	remainH,F
	RLF	remainHH,F

	MOVF	denomHH,W
	SUBWF	remainHH,W	; subtract divsor(denomHH) from(newly shifted left) Remainder HIGH HIGH byte.
	BTFSS	STATUS,Z
	 GOTO	NOCHK32		; skip if result was ZERO from good subtraction result

	MOVF	denomH,W
	SUBWF	remainH,W	; subtract divsor(denomH) from(newly shifted left) Remainder HIGH byte.
	BTFSS	STATUS,Z
	 GOTO	NOCHK32		; skip if result was ZERO from good subtraction result

	MOVF	denomM,W
	SUBWF	remainM,W	; subtract divsor(denomM) from(newly shifted left) Remainder MIDDLE byte.
	BTFSS	STATUS,Z
	 GOTO	NOCHK32		; skip if result was ZERO from good subtraction result
	
	MOVF	denomL,W
	SUBWF	remainL,W	; subtract divsor(denomL) from(newly shifted left) Remainder LOW byte.
NOCHK32
	BTFSS	STATUS,C	;  Carry SET? then denom is larger than reemainder
	 GOTO	NOGO32

	MOVF	denomL,W			 
	SUBWF	remainL,F	; Subtract denominator from remainder value in Low Byte
	BTFSC	STATUS,C	; Carry Set? Then execute fixup code for when a borrow is generated
	 GOTO	NODEC_remainM32	; when no borrow bit is needed from the higher byte positions.

	DECF	remainM,F	; Decrement to Borrow from Middle Byte, because carry was SET.
	COMF	remainM,W	; Check if rollover from Borrow occurred. remainM value went from 0 to 0xFF
	BTFSS	STATUS,Z
	 GOTO	NODEC_remainM32

	DECF	remainH,F	; ZERO bit set, yes rollover, so Decrement to Borrow from High Byte, too!
	COMF	remainH,W	; Check if rollover from Borrow occurred. remainH value went from 0 to 0xFF
	BTFSC	STATUS,Z
	 DECF	remainHH,F	; ZERO bit set, yes rollover, so Decrement to Borrow from High High Byte, too!
NODEC_remainM32
	MOVF	denomM,W			 
	SUBWF	remainM,F	; Subtract denominator from remainder value in Middle Byte
	BTFSC	STATUS,C	; Carry Set? Then execute fixup code for when a borrow is generated
	 GOTO	NODEC_remainH32	; when no borrow bit is needed from the higher byte positions.

	DECF	remainH,F	; Decrement to Borrow from High Byte, because carry was SET.
	COMF	remainH,W	; Check if rollover from Borrow occurred. remainH value went from 0 to 0xFF
	BTFSC	STATUS,Z
	 DECF	remainHH,F	; ZERO bit set, yes rollover, so Decrement to Borrow from High High Byte, too!
NODEC_remainH32
	MOVF	denomH,W
	SUBWF	remainH,F	; Subtract denominator from remainder value in High Byte
	BTFSS	STATUS,C
	 DECF	remainHH,F	; Decrement High High Byte, to borrow 1 bit
	MOVF	denomHH,W   		 
	SUBWF	remainHH,F	; Subtract denominator from remainder value in High High Byte
	BSF	STATUS,C	; set CARRY bit to rotate in Numerator Result next.
NOGO32
	RLF	nratorL,F	; rotate Numerator result left 1 bit
	RLF	nratorM,F
	RLF	nratorH,F
	RLF	nratorHH,F
	DECFSZ	BCount,F	; decrement the Loop Bit Counter
	 GOTO	DLOOP32
	RETURN
;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■ LCD駆動・文字表示関係 ■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; LCDコマンド・データ送信ルーチン
;
; 引数
;	W		書き込むデータ
;
; 戻り値
;	W		書き込んだデータ
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
lcd_command				; PORTBをBCF,BSFで変化させると状態変化割り込みが正しく働かなくなるので、MOVWFで値を直接書く。
	MOVWF	TMP20
	MOVLW	B'10000011'		; SCE=0,DC=0
	GOTO	LCD_TRANSMIT
lcd_data
	MOVWF	TMP20
	MOVLW	B'10100011'		; SCE=0,DC=1
LCD_TRANSMIT
	MOVWF	PORTB
	MOVF	TMP20,W
	MOVWF	SSPBUF
	BSF	STATUS,RP0		; ◆ RP=1
	BTFSS	SSPSTAT,BF
#IFNDEF DEBUG
	 GOTO	$-1
#ENDIF
#IFDEF DEBUG
	 NOP
#ENDIF
	BCF	STATUS,RP0		; ◆ RP=0
	MOVLW	B'11000011'		; SCE=1,DC=0
	MOVWF	PORTB
	MOVF	TMP20,W
	RETURN

;------------------------------------------------------------------------------
; LCD表示位置セットルーチン
;
; 引数
;	LCD_X, LCD_Y
;
; 戻り値
;	なし
;
; 使用変数
;	TMP20(lcd_command)
;------------------------------------------------------------------------------
lcd_locate
	MOVLW	B'00100000'		; Function Set(Power_On, H_addr, Basic_Inst)
	CALL	lcd_command
	MOVF	LCD_X,W
	IORLW	0x80
	CALL	lcd_command
	MOVF	LCD_Y,W
	IORLW	0x40
	CALL	lcd_command
	RETURN

;------------------------------------------------------------------------------
; LCD画面クリア
;
; 引数
;	なし
;
; 戻り値
;	なし
;
; 使用変数
;	TMP21,22, 20(lcd_command)
;------------------------------------------------------------------------------
lcd_cls
	CLRF	LCD_X
	CLRF	LCD_Y
	CALL	lcd_locate

	MOVLW	2
	MOVWF	TMP21
LCD_CLEAR_LOOPY
	MOVLW	252
	MOVWF	TMP22
	CLRW
LCD_CLEAR_LOOPX
	CALL	lcd_data
	DECFSZ	TMP22,F
	 GOTO	LCD_CLEAR_LOOPX
	DECFSZ	TMP21,F
	 GOTO	LCD_CLEAR_LOOPY
	RETURN

;------------------------------------------------------------------------------
; 8x5ドット文字列表示
;
; 引数
;	LCD_X	表示位置
;	LCD_Y	表示位置
;	STRING	文字列
;
; 戻り値
;	なし
;
; 使用変数
;	TMP10,11,12, 20(lcd_locate->lcd_command)
;------------------------------------------------------------------------------
puts5
	CALL	lcd_locate
	MOVLW	16			; 最大16文字ループ
	MOVWF	TMP10
	CALL	set_strptr
	MOVF	INDF,W			; NULLで終わっている場合はリターン
	BTFSC	STATUS,Z
	 GOTO	PUTS5_RETURN
PUTS5_LOOP
	BSF	STATUS,RP1		; ◆ RP=2
	MOVF	INDF,W
	SUBLW	0x2C			; 0x2C以下と0x3A以上は0x2F(スペース)に置換
	MOVF	INDF,W
	BTFSC	STATUS,C
	 MOVLW	0x2F
	MOVWF	INDF
	SUBLW	0x39
	BTFSS	STATUS,C
	 GOTO	PUTS8_LOOP

	MOVF	INDF,W
	ADDLW	0xD3			; オフセットを計算
	MOVWF	TMP11			; W-0x2D
	BCF	STATUS,C		; 2倍
	RLF	TMP11,W
	CLRF	TMP12

	ADDLW	LOW FONT5		; オフセットにベースアドレスを加算
	BTFSC	STATUS,C
	 INCF	TMP12,F
	MOVWF	EEADR
	MOVLW	HIGH FONT5
	ADDWF	TMP12,W
	MOVWF	EEADRH

	MOVLW	2			; 2バイト分ループ
	CALL	PUTS8_LOOP2
	INCF	FSR,F			; 次の文字へ
	MOVF	INDF,W			; NULLで終わっている場合はリターン
	BTFSC	STATUS,Z
	 GOTO	PUTS5_RETURN

	CLRW				; 次の文字がある場合は、1ドットのスペースを入れる
	BCF	STATUS,RP1		; ◆ RP=0
	BTFSC	FLAG1,NEG_FONT		; 反転文字チェック
	 XORLW	0xFF
	CALL	lcd_data		; 上位7ビット
	DECFSZ	TMP10,F
	 GOTO	PUTS5_LOOP
PUTS5_RETURN
	BCF	STATUS,RP1		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
; 8x6ドット文字列表示
;
; 引数
;	LCD_X	表示位置
;	LCD_Y	表示位置
;	STRING	文字列
;
; 戻り値
;	なし
;
; 使用変数
;	TMP10,11,12, 20(lcd_locate->lcd_command)
;------------------------------------------------------------------------------
puts8
	CALL	lcd_locate
	MOVLW	14			; 最大14文字ループ
	MOVWF	TMP10
	CALL	set_strptr
PUTS8_LOOP
	MOVF	INDF,W			; NULLで終わっている場合はリターン
	BTFSC	STATUS,Z
	 GOTO	PUTS8_RETURN

	BSF	STATUS,RP1		; ◆ RP=2
	CALL	char_replace		; 文字コードを書き換え
	ADDLW	0xDA			; オフセットを計算
	MOVWF	TMP11			; W-0x26
	CLRF	TMP12			; 文字データは7bitなので、2桁以上の桁上がりを考慮する必要はない。
	BCF	STATUS,C		; 3倍する
	RLF	TMP11,W
	ADDWF	TMP11,W
	BTFSC	STATUS,C
	 INCF	TMP12,F

	ADDLW	LOW FONT8		; オフセットにベースアドレスを加算
	BTFSC	STATUS,C
	 INCF	TMP12,F
	MOVWF	EEADR

	MOVLW	HIGH FONT8		; 3倍した時の上位を加算
	ADDWF	TMP12,W
	MOVWF	EEADRH

	MOVLW	3			; 3バイト分ループ
	CALL	PUTS8_LOOP2	
	INCF	FSR,F			; 次の文字へ
	DECFSZ	TMP10,F
	 GOTO	PUTS8_LOOP
PUTS8_RETURN
	BCF	STATUS,RP1		; ◆ RP=0
	RETURN

PUTS8_LOOP2
	MOVWF	TMP11
PUTS8_LOOP3
	BSF	STATUS,RP0		; ◆ RP=3
	BSF	EECON1,EEPGD
	BSF	EECON1,RD
	NOP
	NOP

	BCF	STATUS,RP0		; ◆ RP=2
	MOVF	EEDATA,W
	ANDLW	0x7F
	BCF	STATUS,RP1		; ◆ RP=0
	BTFSC	FLAG1,NEG_FONT		; 反転文字チェック
	 XORLW	0xFF
	CALL	lcd_data		; 下位7ビット

	BSF	STATUS,RP1		; ◆ RP=2
	RLF	EEDATA,W
	RLF	EEDATH,W
	ANDLW	0x7F
	BCF	STATUS,RP1		; ◆ RP=0
	BTFSC	FLAG1,NEG_FONT		; 反転文字チェック
	 XORLW	0xFF
	CALL	lcd_data		; 上位7ビット
	
	BSF	STATUS,RP1		; ◆ RP=2
	INCF	EEADR,F			; 次のビットマップデータへ
	BTFSC	STATUS,Z
	 INCF	EEADRH,F
	DECFSZ	TMP11,F
	 GOTO	PUTS8_LOOP3
	RETURN

;------------------------------------------------------------------------------
; 16x8ドット文字列表示
; 文字幅は7dot+空白1dotとなっており、空白部分はフォントデータに含まれていない。
;
; 引数
;	LCD_X	表示位置(破壊)
;	LCD_Y	表示位置
;	STRING	文字列
;
; 戻り値
;	なし
;
; 使用変数
;	TMP10,11,12, 20(lcd_locate->lcd_command)
;	MATH00,01,10,20(mul8)
;------------------------------------------------------------------------------
puts16
	MOVLW	10			; 最大10文字ループ
	MOVWF	TMP10
	CALL	set_strptr
PUTS16_LOW_LOOP				; 下位バイトを描画
	MOVF	INDF,W			; NULLで終わっている場合はリターン
	BTFSC	STATUS,Z
	 GOTO	PUTS16_RETURN

	BCF	STATUS,RP1		; ◆ RP=0
	CALL	lcd_locate		; 下位描画位置に移動

	MOVF	INDF,W			; オフセットを計算
	CALL	char_replace		; 文字コードを書き換え
	ADDLW	0xDA			; W-0x26
	MOVWF	MATH00
	MOVLW	7			; 7倍
	MOVWF	MATH10
	CALL	mul8
	MOVF	MATH00,W
	ADDLW	LOW  FONT16		; オフセットにベースアドレスを加算
	BTFSC	STATUS,C
	 INCF	MATH01,F
	BSF	STATUS,RP1		; ◆ RP=2
	MOVWF	EEADR
	BCF	STATUS,RP1		; ◆ RP=0
	MOVLW	HIGH FONT16		; 上位を加算
	ADDWF	MATH01,W
	BSF	STATUS,RP1		; ◆ RP=2
	MOVWF	EEADRH

	MOVF	FSR,W			; 文字列ポインタを退避
	MOVWF	TMP12
	MOVLW	LOW FONTCACHE		; フォントのキャッシュ場所をポインタに設定
	MOVWF	FSR
	MOVLW	7			; 7バイト分ループ
	MOVWF	TMP11
PUTS16_LOW_LOOP2
	BSF	STATUS,RP0		; ◆ RP=3
	BSF	EECON1,EEPGD		; READ
	BSF	EECON1,RD
	NOP
	NOP

	BCF	STATUS,RP0		; ◆ RP=2
	RLF	EEDATA,W		; フォントデータは7bitなのでシフトして8bitデータとして使う
	ANDLW	0xFE
	BCF	STATUS,RP1		; ◆ RP=0
	CALL	lcd_data

	BSF	STATUS,RP1		; ◆ RP=2
	RLF	EEDATA,W		; 上位7bitをキャッシュする
	RLF	EEDATH,W
	MOVWF	INDF
	INCF	FSR,F			; キャッシュのポインタ+1
	
	INCF	EEADR,F			; 次のビットマップデータへ
	BTFSC	STATUS,Z
	 INCF	EEADRH,F
	DECFSZ	TMP11,F
	 GOTO	PUTS16_LOW_LOOP2

	BCF	STATUS,RP1		; ◆ RP=0
	CLRW				; 8バイト目の空白ドット
	CLRF	INDF
	CALL	lcd_data

	INCF	LCD_Y,F			; 上位バイトをキャッシュから描画
	CALL	lcd_locate		; 1行下に移動

	MOVLW	LOW FONTCACHE
	MOVWF	FSR
	MOVLW	8			; 8バイト分ループ
	MOVWF	TMP11
PUTS16_HIGH_LOOP
	MOVF	INDF,W
	CALL	lcd_data
	INCF	FSR,F
	DECFSZ	TMP11,F
	 GOTO	PUTS16_HIGH_LOOP
	
	INCF	TMP12,W			; 文字列ポインタ復帰、次の文字へ
	MOVWF	FSR
	MOVLW	8			; 次の文字の表示位置を計算しておく
	ADDWF	LCD_X,F
	DECF	LCD_Y,F

	DECFSZ	TMP10,F
	 GOTO	PUTS16_LOW_LOOP
PUTS16_RETURN
	BCF	STATUS,RP1		; ◆ RP=0
	RETURN

char_replace				; フォント削減対応
	SUBLW	0x60			; 61以上は-6
	MOVLW	6
	BTFSS	STATUS,C
	 SUBWF	INDF,F
	MOVF	INDF,W			; 41以上は-6
	SUBLW	0x40
	MOVLW	6
	BTFSS	STATUS,C
	 SUBWF	INDF,F
	MOVF	INDF,W			; 26未満は26
	SUBLW	0x26
	MOVF	INDF,W
	BTFSC	STATUS,C
	 MOVLW	0x26
	MOVWF	INDF			; INDFとWに文字が入って戻る
	RETURN
;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■■■■ I2C関係 ■■■■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; スタートコンディション・デバイスアドレス・RWフラグ送信
; 端子にHを出力する時はTRISに1を、Lを出力する時はTRISを0にセットする。
; PORTは常に0がセットされている。
;
; 引数
;	I2C_DEVADDR	デバイスアドレス
;	I2C_RW		0=WRITE 1=READ
;
; 戻り値
;	なし
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
i2c_start				; スタートコンディション・デバイスアドレス・RWフラグ送信
	BSF	STATUS,RP0		; ◆ RP=1
	MOVLW	B'11000000'		; SDA=H SCL=H
	IORWF	TRISA,F
	BCF	TRISA,I2C_SDA		; SDA=L SCL=H
	BCF	TRISA,I2C_SCL		; SDA=L SCL=L
	BCF	STATUS,RP0		; ◆ RP=0

	MOVLW	I2C_DEVADDR
	BTFSC	FLAG1,I2C_RW
	 ADDLW	1
	CALL	i2c_send		; NAKチェックは行わない
	RETURN

;------------------------------------------------------------------------------
; ストップコンディション送信
;------------------------------------------------------------------------------
i2c_stop
	BSF	STATUS,RP0		; ◆ RP=1
	MOVLW	B'00111111'		; SDA=L SCL=L
	ANDWF	TRISA,F
	BSF	TRISA,I2C_SCL		; SDA=L SCL=H
	BSF	TRISA,I2C_SDA		; SDA=H SCL=H
	BCF	STATUS,RP0		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
; I2C送信ルーチン
; 事前にスタートコンディションとアドレス指定を済ませておくこと。
;
; 引数
;	W		送信データ
;
; 戻り値
;	I2C_NAK
;
; 使用変数
;	TMP20,21
;------------------------------------------------------------------------------
i2c_send				; データを8ビット分送信しACKを受信する
	MOVWF	TMP21
	MOVLW	8
	MOVWF	TMP20
	BSF	STATUS,RP0		; ◆ RP=1
SEND_DATA_LOOP
	RLF	TMP21,F			; 左シフトでCフラグへ送る
	BTFSC	STATUS,C
	 GOTO	SEND_DATA_H
SEND_DATA_L
	BCF	TRISA,I2C_SDA
	GOTO	SEND_DATA_CLK
SEND_DATA_H
	BSF	TRISA,I2C_SDA
SEND_DATA_CLK				; クロック送信
	BSF	TRISA,I2C_SCL		; SCL=H
	BCF	TRISA,I2C_SCL		; SCL=L
	DECFSZ	TMP20,F
	 GOTO	SEND_DATA_LOOP
RECV_ACK				; ACKを受信してフラグをセット
	BSF	TRISA,I2C_SDA		; SDAを開放(=H)
	BSF	TRISA,I2C_SCL		; SCL=H アクノリッジビット受信
	BCF	STATUS,RP0		; ◆ RP=0
	BCF	FLAG1,I2C_NAK		; とりあえずフラグをクリア(=ACK)
	BTFSC	PORTA,I2C_SDA		; NAKの場合はフラグをセット
	 BSF	FLAG1,I2C_NAK
	BSF	STATUS,RP0		; ◆ RP=1
	BCF	TRISA,I2C_SCL		; SCL=L
	BCF	STATUS,RP0		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
; I2C受信ルーチン
; 事前にスタートコンディション、アドレス指定、読み出しスタートを済ませておくこと。
;
; 引数
;	I2CDATA		受信データ
;	I2C_NAK		受信後に送信するACKフラグ
;
; 戻り値
;	なし
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
i2c_recv
	BSF	STATUS,RP0		; ◆ RP=1
	BSF	TRISA,I2C_SDA		; SDAを開放(=H)
	MOVLW	8
	MOVWF	TMP20
RECV_DATA_LOOP
	BSF	STATUS,RP0		; ◆ RP=1
	BSF	TRISA,I2C_SCL		; SCL=H
	BCF	STATUS,RP0		; ◆ RP=0
	RLF	PORTA,W			; Cフラグを通してビットを受信
	RLF	I2CDATA,F
	BSF	STATUS,RP0		; ◆ RP=1
	BCF	TRISA,I2C_SCL		; SCL=L
	DECFSZ	TMP20,F
	 GOTO	RECV_DATA_LOOP

	BCF	STATUS,RP0		; ◆ RP=0
	BTFSC	FLAG1,I2C_NAK
	 GOTO	SEND_NAK
SEND_ACK				; 受信モード時のACK送信
	BSF	STATUS,RP0		; ◆ RP=1
	BCF	TRISA,I2C_SDA		; SDAをドライブ(=L)
	BSF	TRISA,I2C_SCL		; SCL=H アクノリッジビット送信
	BCF	TRISA,I2C_SCL		; SCL=L
	BCF	STATUS,RP0		; ◆ RP=0
	RETURN

SEND_NAK				; 受信モード時のNAK送信
	BSF	STATUS,RP0		; ◆ RP=1
	BSF	TRISA,I2C_SDA		; SDAを開放(=H)
	BSF	TRISA,I2C_SCL		; SCL=H アクノリッジビット送信
	BCF	TRISA,I2C_SCL		; SCL=L
	BCF	STATUS,RP0		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
; I2C連続受信ルーチン
; 事前にスタートコンディション、アドレス指定、読み出しスタートを済ませておくこと。
; 指定のバイト数を受信する。
; ストップコンディションを送信するのを忘れないこと。
;
; 引数
;	W		受信バイト数
;	FSR,IRP		受信データを保存するバッファアドレス
;
; 戻り値
;	なし
;
; 使用変数
;	TMP21, 20(i2c_recv)
;------------------------------------------------------------------------------
i2c_multi_recv
	MOVWF	TMP21
I2C_MULTI_RECV_LOOP
	BSF	FLAG1,I2C_NAK
	DECFSZ	TMP21,W			; 最終バイト以外はACK状態にする
	 BCF	FLAG1,I2C_NAK
	CALL	i2c_recv
	MOVF	I2CDATA,W
	CALL	store_INDF_inc_FSR
	DECFSZ	TMP21,F
	 GOTO 	I2C_MULTI_RECV_LOOP
	RETURN

;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■ MPL3115A2コントロール ■■■■■■■■■■■■■
;------------------------------------------------------------------------------
send_QNH				; 高度計規正値を送信する Use TMP10,11
	BTFSC	ALT_CFG,QNH_UNIT
	 GOTO	SEND_QNH_HPA
SEND_QNH_IN
	CALL	convert_inch2hpa
SEND_QNH
	BCF	FLAG1,I2C_RW
	CALL	i2c_start
	MOVLW	BAR_IN_MSB
	CALL	i2c_send
	MOVF	TMP11,W
	CALL	i2c_send
	MOVF	TMP10,W
	GOTO	SEND_AND_STOP
SEND_QNH_HPA
	MOVF	QNH_MSB,W
	MOVWF	TMP11
	MOVF	QNH_LSB,W
	MOVWF	TMP10
	GOTO	SEND_QNH

send_STANDBY
	BCF	FLAG1,I2C_RW		; WRITE
	CALL	i2c_start
	MOVLW	CTRL_REG1
	CALL	i2c_send
	CLRW				; Force STANDBY
	CALL	i2c_send

	BCF	FLAG1,I2C_RW		; WRITE
	CALL	i2c_start		; ダミー読み込みを行い、INT_SOURCEの割り込みフラグを戻しておく。
	MOVLW	OUT_P_MSB		; 全てのデータを読むわけではないので、DR_STATUSは0に戻らない。
	CALL	i2c_send
	BSF	FLAG1,I2C_RW		; READ
	CALL	i2c_start
	BSF	FLAG1,I2C_NAK
	CALL	i2c_recv
	CALL	i2c_stop
	RETURN

send_ACTIVE				; 一度スタンバイにしてからアクティブにすること
	BCF	FLAG1,I2C_RW		; WRITE
	CALL	i2c_start
	MOVLW	CTRL_REG1
	CALL	i2c_send
	MOVF	ALT_OSR,W		; OSR
	BTFSC	MODE_CFG,MODE
	 MOVF	BARO_OSR,W
	MOVWF	TMP00
	RLF	TMP00,F
	RLF	TMP00,F
	RLF	TMP00,F
	MOVLW	B'00111000'
	ANDWF	TMP00,F
	MOVLW	B'10000001'		; OSR | ALT+SBYB
	BTFSC	MODE_CFG,MODE
	 MOVLW	B'00000001'
	IORWF	TMP00,W
	GOTO	SEND_AND_STOP

SEND_AND_STOP
	CALL	i2c_send
	CALL	i2c_stop
	RETURN	

;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■■ データEEPROM関係 ■■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; EEPROM データ書き込み
; 引数
;	FSR,IRP	読み出しアドレス
;	_EEADDR	書き込みアドレス
;	W	書き込みバイト数
;
; 戻り値
;	なし
;
; 使用変数
;	TMP00,01
;------------------------------------------------------------------------------
write_ee_data
	MOVWF	TMP00
	MOVF	_EEADDR,W
	BSF	STATUS,RP1		; ◆ RP=2
	MOVWF	EEADR
WRITE_EE_LOOP
	MOVF	INDF,W
	MOVWF	EEDATA

	BSF	STATUS,RP0		; ◆ RP=3
	BCF	EECON1,EEPGD
	BSF	EECON1,WREN
	SWAPF	INTCON,W
	MOVWF	TMP01
	BCF	INTCON,GIE
	MOVLW	0x55
	MOVWF	EECON2
	MOVLW	0xAA
	MOVWF	EECON2
	BSF	EECON1,WR
	BTFSC	EECON1,WR
	 GOTO	$-1			; 書き込み待ち
	BCF	EECON1,WREN
	SWAPF	TMP01,W
	MOVWF	INTCON
	BCF	STATUS,RP0		; ◆ RP=2
	INCF	FSR,F
	INCF	EEADR,F
	DECFSZ	TMP00,F
	 GOTO	WRITE_EE_LOOP
	BCF	STATUS,RP1		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
; EEPROM データ読み出し
; 引数
;	W	アドレス
;
; 戻り値
;	_EEDATA,W データ
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
read_ee_data
	BSF	STATUS,RP1		; ◆ RP=2
	MOVWF	EEADR
	BSF	STATUS,RP0		; ◆ RP=3
	BCF	EECON1,EEPGD
	BSF	EECON1,RD
	BCF	STATUS,RP0		; ◆ RP=2
	MOVF	EEDATA,W
	MOVWF	_EEDATA
	BCF	STATUS,RP1		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■■■ クロック関係 ■■■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; クロック変更ルーチン、クロックとPWMを変更する
;
; 引数
;	なし
;
; 戻り値
;	なし
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
clock_high
	BSF	STATUS,RP0		; ◆ RP=1
;	MOVLW	B'01100000'		; OSC=INT_4MHz
	MOVLW	B'01110000'		; OSC=INT_8MHz 3Vでも動く
	MOVWF	OSCCON
	MOVLW	B'00000110'		; TIMER2=ON、プリスケーラ=16
	GOTO	CLOCK_COMMON

clock_low
	BSF	STATUS,RP0		; ◆ RP=1
	CLRF	OSCCON			; OSC=INT_31,250Hz
	MOVLW	B'00000100'		; TIMER2=ON、プリスケーラ=1
CLOCK_COMMON
	BCF	STATUS,RP0		; ◆ RP=0
	MOVWF	T2CON
	RETURN

;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■ イベントキュー用FIFO ■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; 書き込みはページ1に移動
;------------------------------------------------------------------------------
; FIFO読み出し
;	バッファが空の場合は、エンプティフラグをセットしてリターンする。
;
; 引数
;	なし
;
; 戻り値
;	W			読み出したデータ
;	FIFO_EMPTY		FIFOバッファエンプティフラグ
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
fifo_read
	MOVF	USEDSIZE,W
	BTFSS	STATUS,Z		; バッファエンプティチェック
	 GOTO	FIFO_READ1
	BSF	FLAG1,FIFO_EMPTY	; 空フラグを立ててリターン
	RETURN
FIFO_READ1
	BCF	FLAG1,FIFO_EMPTY	; 空フラグOFF
	BCF	STATUS,IRP		; ● IRP=0
	MOVF	READPTR,W		; バッファを間接アクセス
	MOVWF	FSR
	MOVF	INDF,W
	MOVWF	READDATA
	DECF	USEDSIZE,F		; FIFOのデータ数を-1(呼び出し時にチェックをしているので、マイナスになることはない)
	INCF	READPTR,F		; 読み出しポインタをインクリメント

	MOVLW	LOW FIFOBUF		; ポインタのロールオーバーのチェック
	ADDLW	FIFO_SIZE
	SUBWF	READPTR,W
	BTFSS	STATUS,Z
	 GOTO	FIFO_READ2		; そのままリターン
	MOVLW	LOW FIFOBUF		; ロールオーバーしていたならば、先頭位置に移動
	MOVWF	READPTR
FIFO_READ2
	MOVF	READDATA,W		; Wに読み込みデータを入れてリターン
	RETURN

;------------------------------------------------------------------------------
; イベントキューの読み出しとボタンの長押し判定
;
; 引数
;	なし
;
; 戻り値
;	TMP20			イベントID
;
; 使用変数
;	TMP21,22
;------------------------------------------------------------------------------
event_wait
	CALL	clock_low
EVENT_WAIT_LOOP
	CALL	fifo_read
	BTFSC	FLAG1,FIFO_EMPTY
	 GOTO	EVENT_WAIT_LOOP
	
	MOVWF	TMP20
	MOVF	TMP20,W
	BTFSS	STATUS,Z		; ゼロならキー入力と判断し、長押し判定を行う。
	 GOTO	EVENT_WAIT_RETURN

	BCF	INTCON,GIE		; 長押し判定中はクロックが変化しないように割り込みを禁止する。
	CALL	clock_low		; 省電力のためにクロックを落とす
	MOVLW	4			; 長押し判定時間は500ms
	MOVWF	TMP21
LONGTAP1
	MOVLW	192
	MOVWF	TMP22
LONGTAP2
	BTFSC	PORTA,ENC_SW
	 GOTO	EVENT_WAIT_RETURN
	DECFSZ	TMP22,F
	 GOTO	LONGTAP2
	DECFSZ	TMP21,F
	 GOTO	LONGTAP1
	INCF	TMP20,F			; 最後までカウントしたら長押しイベントを返す
EVENT_WAIT_RETURN
	CALL	clock_high
	BSF	INTCON,GIE
	RETURN

;------------------------------------------------------------------------------
;■■■■■■■■■■■■■■■■■ データ変換 ■■■■■■■■■■■■■■■■
;------------------------------------------------------------------------------
; 気圧データをhPa文字列に変換 xxxx.xxhPa
;
; 引数
;	MATH01		P_MSBの値
;	MATH00		P_CSBの値
;	MATH02		P_LSBの値
;
; 戻り値
;	STRING	表示文字列(NULLで終端)
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
baro2hpa
	MOVF	P_MSB,W			; MSB->CSB	集約
	MOVWF	MATH01
	MOVF	P_CSB,W			; CSB->LSB
	MOVWF	MATH00
	MOVF	P_LSB,W			; LSB->MSB
	MOVWF	MATH02

	RLF	MATH02,F		; 全体を2ビット左にずらしてQ18.2の18bit部分だけ抽出(0.1Pa以下を捨てる)
	RLF	MATH00,F		; 結果数値 = 101325
	RLF	MATH01,F
	RLF	MATH02,F
	RLF	MATH00,F
	RLF	MATH01,F
	RLF	MATH02,W
	ANDLW	0x03
	MOVWF	MATH02
hpa2str
	CALL	set_strptr
	BTFSC	FLAG2,YGUIDE
	 GOTO	HPA2STR_GUIDE
	CALL	format_xxxx_xx		; 1013.25
hpa_unit
	MOVLW	'h'
	CALL	store_INDF_inc_FSR
	MOVLW	'P'
	CALL	store_INDF_inc_FSR
	MOVLW	'a'
	CALL	store_INDF_inc_FSR
HPA2STR2
	CLRF	INDF			; null

	MOVLW	1
	CALL	zero_replace
	RETURN
HPA2STR_GUIDE
	CALL	format_xxxx		; 1013
	GOTO	HPA2STR2
;------------------------------------------------------------------------------
; 気圧データをin文字列に変換 xx.xxin
;
; 引数
;	MATH02		P_MSBの値
;	MATH01		P_CSBの値
;	MATH03		P_LSBの値
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
baro2inch
	MOVF	P_MSB,W			; MSB->CSB	集約
	MOVWF	MATH02
	MOVF	P_CSB,W			; CSB->LSB
	MOVWF	MATH01
	MOVF	P_LSB,W			; LSB->MSB
	MOVWF	MATH03

	CALL	convert_baro2inch
inch2str
	CALL	set_strptr
	CALL	format_xx_xx		; 29.92
	BTFSC	FLAG2,YGUIDE
	 GOTO	INCH2STR2
	MOVLW	'i'
	CALL	store_INDF_inc_FSR
	MOVLW	'n'
	CALL	store_INDF_inc_FSR
INCH2STR2
	CLRF	INDF			; null
	RETURN

convert_baro2inch			; QNHのhPa->in変換にも使うので、サブ化しておく。
;	MOVF	P_MSB,W			; MSB->CSB
;	MOVWF	MATH02
;	MOVF	P_CSB,W			; CSB->LSB
;	MOVWF	MATH01
;	MOVF	P_LSB,W			; LSB->MSB
;	MOVWF	MATH03
;	CALL	convert_baro2inch
;または
;	CLRF	MATH00
;	BCF	STATUS,C		; hPaは2倍してから変換
;	RLF	QNH_LSB,W		; 小数点の位置に注意
;	MOVWF	MATH01
;	RLF	QNH_MSB,W
;	MOVWF	MATH02
;	CLRW	MATH03
;	RLF	MATH03,F
;	CALL	convert_hpa2inch
;	MOVF	MATH01,W
;	MOVWF	QNH_MSB
;	MOVF	MATH00,W
;	MOVWF	QNH_LSB

	RLF	MATH03,F		; 全体を2ビット左にずらしてQ18.2の18bit部分だけ抽出(0.1Pa以下を捨てる)
	RLF	MATH01,F		; 結果数値 = 101325
	RLF	MATH02,F		; 32bit割り算用にQ24.8形式に補正しておく(=256倍)
	RLF	MATH03,F
	RLF	MATH01,F
	RLF	MATH02,F
	RLF	MATH03,W
	ANDLW	0x03
	MOVWF	MATH03
	CLRF	MATH00
convert_hpa2inch
	CLRF	MATH13			; 近似値 = 101325 / 33.86328125
	CLRF	MATH12			; 理論値 = 101325 / 33.86389
	MOVLW	33
	MOVWF	MATH11			; 221 = 0.86328125 * 256
	MOVLW	221			; Q24.8 / Q24.8 = Q32として結果を得る
	MOVWF	MATH10			; 被除数、除数ともに256倍されているので普通の整数が得られる
	CALL	div32			; 結果数値=2992
	RETURN

convert_inch2hpa			; インチからPAに変換
	MOVF	QNH_MSB,W		; PA = QNH 2992 * 33.86328125 + 2
	MOVWF	MATH01			; +2とは理論値と近似値の差にQNHをかけた誤差
	MOVF	QNH_LSB,W		; QNH * (33.86389 - 33.86328125) = 1.7〜1.9
	MOVWF	MATH00
	MOVLW	33
	MOVWF	MATH11
	MOVLW	221
	MOVWF	MATH10
	CALL	mul16
	MOVLW	2
	ADDWF	MATH01,F
	BTFSC	STATUS,C
	 INCF	MATH02,F
	BTFSC	STATUS,Z
	 INCF	MATH03,F
	RRF	MATH03,F		; PAをBAR_IN数値に変換(/2)
	RRF	MATH02,F
	RRF	MATH01,W
	MOVWF	TMP10
	MOVF	MATH02,W
	MOVWF	TMP11
	RETURN
;------------------------------------------------------------------------------
; 高度計規正値を文字列に変換
;
; 引数
;	QNH_UNIT		QNHの単位
;	QNH_MSB,QNH_LSB		QNH
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
qnh_to_string
	BTFSC	ALT_CFG,QNH_UNIT
	 GOTO	QNH_TOSTR_HPA

	MOVF	QNH_MSB,W		; インチはそのまま文字列化
	MOVWF	MATH01
	MOVF	QNH_LSB,W
	MOVWF	MATH00
	GOTO	inch2str
QNH_TOSTR_HPA
	BCF	STATUS,C		; hPaは2倍してから文字列化
	RLF	QNH_LSB,W
	MOVWF	MATH00
	RLF	QNH_MSB,W
	MOVWF	MATH01
	CLRF	MATH02
	RLF	MATH02,F
	GOTO	hpa2str

;------------------------------------------------------------------------------
; 気温データを摂氏文字列に変換 sxx.xx°C
;
; 引数
;	MATH01		T_MSB, T_DELTA_MSBの値
;	MATH00		T_LSB, T_DELTA_LSBの値
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
temp2celsius
;	MOVF	T_MSB,W
;	MOVWF	MATH01
;	MOVF	T_LSB,W
;	MOVWF	MATH00
	CALL	tempx100

	CALL	set_strptr
	MOVLW	'0'			; 符号用のスペースを入れておく
	CALL	store_INDF_inc_FSR
	BTFSC	FLAG2,YGUIDE
	 GOTO	TEMP2CELCIUS_GUIDE
	CALL	format_xx_xx		; 29.92
	MOVLW	'\''			; °
	CALL	store_INDF_inc_FSR
	MOVLW	'C'
	CALL	store_INDF_inc_FSR
TEMP2CELCIUS2
	CLRF	INDF			; null
	MOVLW	2
	CALL	zero_replace
	BTFSC	FLAG1,MATH_SIGN		; +の時は符号を付けない
	 CALL	add_sign
	RETURN
TEMP2CELCIUS_GUIDE
	CALL	format_xx2		; 13
	CALL	dec_dot			; .
	CALL	dec_10			; 2
	GOTO	TEMP2CELCIUS2
;------------------------------------------------------------------------------
; 気温データを華氏文字列に変換 xxx.xx°F
; 負の摂氏を受け付けないので、DELTAの値を表示できない事に注意すること。
;
; 引数
;	MATH01		T_MSBの値
;	MATH00		T_LSBの値
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
temp2fahrenheit
;	MOVF	T_MSB,W
;	MOVWF	MATH01
;	MOVF	T_LSB,W
;	MOVWF	MATH00
	CALL	tempx100

	CLRF	MATH12			; F = C * 9 / 5 + 32
	CLRF	MATH11
	MOVLW	9
	MOVWF	MATH10
	CALL	mul24

	CLRF	MATH12
	CLRF	MATH11
	MOVLW	5
	MOVWF	MATH10
	CALL	div24

	BTFSC	FLAG1,MATH_SIGN		; 摂氏の正負で処理を分ける
	 GOTO	TEMP2F_MINUS
TEMP2F_PLUS
	MOVLW	0x80			; 摂氏が正の場合32を足す
	ADDWF	MATH00,F		; 0x0C80 = 3200
	BTFSC	STATUS,C
	 INCF	MATH01,F
	MOVLW	0x0C
	ADDWF	MATH01,F
	GOTO	TEMP2F_PRINT
TEMP2F_MINUS
	MOVF	MATH00,W		; 摂氏が負の数の場合32から引く
	SUBLW	0x80			; 華氏がマイナスに転じる摂氏17.78℃以下の時は
	MOVWF	MATH00			; 正しく表示できなくなる
	MOVF	MATH01,W
	BTFSS	STATUS,C
	 DECF	MATH01,W
	SUBLW	0x0C
	MOVWF	MATH01
TEMP2F_PRINT
	CALL	set_strptr
	BTFSC	FLAG2,YGUIDE
	 GOTO	TEMP2F_GUIDE
	CALL	format_xxx_xx		; 110.00
	MOVLW	'\''			; °
	CALL	store_INDF_inc_FSR
	MOVLW	'F'
	CALL	store_INDF_inc_FSR
TEMP2FAHRENHEIT2
	CLRF	INDF			; null
	MOVLW	2
	CALL	zero_replace
	RETURN
TEMP2F_GUIDE
	CALL	format_xxx2		; 013
	CALL	dec_dot			; .
	CALL	dec_10			; 2
	GOTO	TEMP2FAHRENHEIT2
;------------------------------------------------------------------------------
; 気温データを100倍する
;
; 引数
;	MATH01		T_MSB, T_DELTA_MSBの値
;	MATH00		T_LSB, T_DELTA_LSBの値
;
; 戻り値
;	MATH_SIGN	符号
;	MATH02		MSB
;	MATH01		CSB
;	MATH00		LSB
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
tempx100
;	MOVF	T_MSB,W
;	MOVWF	MATH01
;	MOVF	T_LSB,W
;	MOVWF	MATH00
	BCF	FLAG1,MATH_SIGN		; 符号判定
	BTFSC	MATH01,7
	 BSF	FLAG1,MATH_SIGN

	BTFSS	FLAG1,MATH_SIGN
	 GOTO	TEMPx100_1
	COMF	MATH01,F		; 負を正にする
	COMF	MATH00,W
	ADDLW	0x10			; 4bitオフセット有
	ANDLW	0xF0
	MOVWF	MATH00
	BTFSC	STATUS,Z
	 INCF	MATH01,F
TEMPx100_1
	CLRF	MATH11			; Q8.8 * Q16.0 = Q24.8
	MOVLW	100			;      * 100
	MOVWF	MATH10
	CALL	mul16

	MOVF	MATH01,W		; 小数点の位置が8bit目にあるので移動させる
	MOVWF	MATH00
	MOVF	MATH02,W
	MOVWF	MATH01
	MOVF	MATH03,W
	MOVWF	MATH02
	RETURN

;------------------------------------------------------------------------------
; 高度データをm文字列に変換 sxxxx.xm
;
; 引数
;	MATH02		P_MSB, P_DELTA_MSBの値
;	MATH01		P_CSB, P_DELTA_CSBの値
;	MATH00		P_LSB, P_DELTA_LSBの値
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
alt2meter
;	MOVF	P_MSB,W
;	MOVWF	MATH02
;	MOVF	P_CSB,W
;	MOVWF	MATH01
;	MOVF	P_LSB,W
;	MOVWF	MATH00
	CALL	altx100
	CALL	altx100_1
alt2meter_for_mps
	CALL	altx100_2
	CALL	set_strptr
	CALL	format_xxxx		; 1377
	BTFSC	FLAG2,YGUIDE
	 GOTO	ALT2METER_2
	BTFSC	FLAG2,CALIB
	 GOTO	ALT2METER_1
	CALL	dec_dot			; .
	CALL	dec_10			; 0
	BTFSC	FLAG1,VSI
	 CALL	dec_1			; 0
	BTFSC	FLAG1,VSI
	 GOTO	ALT2METER_2
ALT2METER_1
	MOVLW	'm'
	CALL	store_INDF_inc_FSR
ALT2METER_2
	CLRF	INDF			; null

	MOVLW	3
	CALL	zero_replace
	BTFSC	FLAG1,MATH_SIGN
	 CALL	add_sign
	RETURN

;------------------------------------------------------------------------------
; 高度データをft文字列に変換 sxxxxxft
;
; 引数
;	MATH02		P_MSB, P_DELTA_MSBの値
;	MATH01		P_CSB, P_DELTA_CSBの値
;	MATH00		P_LSB, P_DELTA_LSBの値
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP00,TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
alt2feet
;	MOVF	P_MSB,W
;	MOVWF	MATH02
;	MOVF	P_CSB,W
;	MOVWF	MATH01
;	MOVF	P_LSB,W
;	MOVWF	MATH00
	CALL	altx100
	CALL	altx100_1
alt2feet_for_fpm
	CALL	altx100_2
	CLRF	MATH12			; Q24.0 * Q3.5 = Q27.5
	CLRF	MATH11
	MOVLW	0x69			; 近似値 = m * 3.28125(011.01001)
	MOVWF	MATH10			; 理論値 = m * 3.2808399
	CALL	mul24

	MOVLW	5			; 5bit右シフト
	MOVWF	TMP00
	SWAPF	STATUS,W		; STATUSセーブ
	MOVWF	MATH10
ALT2FT_1
	SWAPF	MATH10,W		; Cフラグ(STATUS)リストア
	MOVWF	STATUS
	SWAPF	MATH10,W
	RRF	MATH03,F
	RRF	MATH02,F
	RRF	MATH01,F
	RRF	MATH00,F
	SWAPF	STATUS,W		; Cフラグ(STATUS)セーブ
	MOVWF	MATH10
	DECFSZ	TMP00,F
	 GOTO	ALT2FT_1
	MOVLW	B'00000111'		; 不要なCフラグをマスク
	ANDWF	MATH03,F		; Q22.0

	CALL	set_strptr
	CALL	dec_1000000		; 1
	CALL	format_xxxx		; 2345
	BTFSS	FLAG2,YGUIDE
	 BTFSC	FLAG1,VSI
	GOTO	ALT2FT_2
	MOVLW	'f'
	CALL	store_INDF_inc_FSR
	MOVLW	't'
	CALL	store_INDF_inc_FSR
ALT2FT_2
	CLRF	INDF			; null
	
	MOVLW	4
	CALL	zero_replace
	BTFSC	FLAG1,MATH_SIGN
	 CALL	add_sign
	RETURN

;------------------------------------------------------------------------------
; 高度データを100倍する
;
; 引数
;	MATH02		P_MSB, P_DELTA_MSBの値
;	MATH01		P_CSB, P_DELTA_CSBの値
;	MATH00		P_LSB, P_DELTA_LSBの値
;
; 戻り値
;	MATH_SIGN	符号
;	MATH02		MSB
;	MATH01		CSB
;	MATH00		LSB
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
altx100
;	MOVF	P_MSB,W
;	MOVWF	MATH02
;	MOVF	P_CSB,W
;	MOVWF	MATH01
;	MOVF	P_LSB,W
;	MOVWF	MATH00
	BCF	FLAG1,MATH_SIGN		; 符号判定
	BTFSC	MATH02,7
	 BSF	FLAG1,MATH_SIGN

	BTFSS	FLAG1,MATH_SIGN
	 RETURN
	COMF	MATH02,F		; 負を正にする
	COMF	MATH01,F
	COMF	MATH00,W
	ADDLW	0x10			; 4bitオフセット有
	ANDLW	0xF0
	MOVWF	MATH00
	BTFSC	STATUS,Z
	 INCF	MATH01,F
	BTFSC	STATUS,Z
	 INCF	MATH02,F
	RETURN
altx100_1
	CLRF	MATH12			; Q16.8 * Q24.0 = Q40.8
	CLRF	MATH11			;       * 100
	MOVLW	100
	MOVWF	MATH10
	CALL	mul24
	RETURN
altx100_2
	MOVF	MATH01,W		; 小数点の位置が8bit目にあるので移動させる
	MOVWF	MATH00
	MOVF	MATH02,W
	MOVWF	MATH01
	MOVF	MATH03,W
	MOVWF	MATH02
	RETURN

;------------------------------------------------------------------------------
; 10進文字列変換 各桁の数字をバッファに送る
;
; 引数
;	MATH02		MSB	表示する桁の数値
;	MATH01		CSB
;	MATH00		LSB
;
; 戻り値
;	MATH02		MSB	次の桁への余り
;	MATH01		CSB
;	MATH00		LSB
;
; 使用変数
;	TMP20(数値演算ルーチン内)
;------------------------------------------------------------------------------
dec_1000000
	MOVLW	0x0F			; 0x0F4240 = 1,000,000
	MOVWF	MATH12
	MOVLW	0x42
	MOVWF	MATH11
	MOVLW	0x40
dec_div24
	MOVWF	MATH10
	CALL	div24
	GOTO	dec_1
;------------------------------------------------------------------------------
dec_100000
	MOVLW	0x01			; 0x0186A0 = 100,000
	MOVWF	MATH12
	MOVLW	0x86
	MOVWF	MATH11
	MOVLW	0xA0
	GOTO	dec_div24
;------------------------------------------------------------------------------
dec_10000
	CLRF	MATH12			; 0x002710 = 10,000
	MOVLW	0x27
	MOVWF	MATH11
	MOVLW	0x10
	GOTO	dec_div24
;------------------------------------------------------------------------------
dec_1000
	MOVLW	0x03			; 0x03E8 = 1,000
	MOVWF	MATH11
	MOVLW	0xE8
dec_div16
	MOVWF	MATH10
	CALL	div16
	GOTO	dec_1
;------------------------------------------------------------------------------
dec_100
	CLRF	MATH11			; 100
	MOVLW	100
	GOTO	dec_div16
;------------------------------------------------------------------------------
dec_10
	MOVLW	10			; 10
	MOVWF	MATH10
	CALL	div8
	GOTO	dec_1
;------------------------------------------------------------------------------
dec_1
	MOVF	MATH00,W		; 文字化
	ADDLW	'0'
	MOVWF	INDF
	MOVF	MATH22,W		; 余り
	MOVWF	MATH02
	MOVF	MATH21,W
	MOVWF	MATH01
	MOVF	MATH20,W
	MOVWF	MATH00
dec_return
	INCF	FSR,F
	RETURN
;------------------------------------------------------------------------------
dec_dot					; ドット挿入
	MOVLW	'.'
	MOVWF	INDF
	GOTO	dec_return
;------------------------------------------------------------------------------
format_xxxx_xx
	CALL	dec_100000		; 1
format_xxx_xx
	CALL	dec_10000		; 0
format_xx_xx
	CALL	dec_1000		; 1
format_x_xx
	CALL	dec_100			; 3
	CALL	dec_dot			; .
	GOTO	format_xx

format_xxxx
	CALL	dec_100000		; 1
format_xxx2
	CALL	dec_10000		; 0
format_xx2
	CALL	dec_1000		; 1
	CALL	dec_100			; 3
	RETURN

format_xxx
	CALL	dec_100			; 0
format_xx
	CALL	dec_10			; 1
	CALL	dec_1			; 3
	RETURN
;------------------------------------------------------------------------------
; 頭からN文字の0を除去する
;
; 引数
;	W		N文字数
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
zero_replace
	MOVWF	TMP20
	CALL	set_strptr
ZERO_REPL_LOOP
	MOVLW	'0'			; 文字が0でなければそこで終了
	SUBWF	INDF,W
	BTFSS	STATUS,Z
	 RETURN
	MOVLW	' '			; 0ならばスペースに置換
	CALL	store_INDF_inc_FSR
	DECFSZ	TMP20,F
	 GOTO	ZERO_REPL_LOOP
	RETURN

;------------------------------------------------------------------------------
; 初めて文字が現れる手前のスペースに符号を入れる
;
; 引数
;	MATH_SIGN	符号
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
add_sign
	CALL	set_strptr
	MOVLW	' '			; 1文字目がスペースか?
	SUBWF	INDF,W
	BTFSS	STATUS,Z		; スペースじゃない時は符号を入れるスペースが無いのでリターン
	 RETURN	
ADD_SIGN_LOOP
	INCF	FSR,F
	MOVLW	' '			; 次の文字がスペース以外の文字か?
	SUBWF	INDF,W
	BTFSS	STATUS,Z
	 GOTO	ADD_SIGN_RETURN
	GOTO	ADD_SIGN_LOOP
ADD_SIGN_RETURN
	DECF	FSR,F			; 1文字戻って符号を入れる
	MOVLW	'+'
	BTFSC	FLAG1,MATH_SIGN
	 MOVLW	'-'
	MOVWF	INDF
	RETURN

;------------------------------------------------------------------------------
; プログラムEEPROMから文字列を読み込む
; 14文字以上の文字列はNULLでターミネートする。
; 15文字以上の文字列は15文字以降が読み出されない。
;
; 引数
;	TMP20		文字列アドレスLSB
;	TMP21		文字列アドレスMSB
;
; 戻り値
;	STRING		表示文字列(NULLで終端)
;
; 使用変数
;	TMP22
;------------------------------------------------------------------------------
getstr
	CALL	set_strptr
	MOVLW	14
	MOVWF	TMP22
	BSF	STATUS,RP1		; ◆ RP=2
GETSTR_LOOP
	MOVF	TMP21,W
	MOVWF	EEADRH
	MOVF	TMP20,W
	MOVWF	EEADR
	BSF	STATUS,RP0		; ◆ RP=3
	BSF	EECON1,EEPGD		; READ
	BSF	EECON1,RD
	NOP
	NOP

	BCF	STATUS,RP0		; ◆ RP=2
	RLF	EEDATA,W
	RLF	EEDATH,W
	ANDLW	0x7F
	BTFSC	STATUS,Z
	 GOTO	GETSTR_RETURN_1
	CALL	store_INDF_inc_FSR
	DECF	TMP22,F

	MOVF	EEDATA,W
	ANDLW	0x7F
	BTFSC	STATUS,Z
	 GOTO	GETSTR_RETURN_1
	CALL	store_INDF_inc_FSR

	INCF	TMP20,F
	BTFSC	STATUS,Z
	 INCF	TMP21,F	
	DECFSZ	TMP22,F			; 14文字カウントしてもNULLが来ない場合は終了
	 GOTO	GETSTR_LOOP
	GOTO	GETSTR_RETURN_2
GETSTR_RETURN_1
	CLRF	INDF			; null
GETSTR_RETURN_2
	BCF	STATUS,RP1		; ◆ RP=0
	RETURN

;------------------------------------------------------------------------------
; FSRに文字列ポインタの先頭をセットする
;------------------------------------------------------------------------------
set_strptr
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW STRING
	MOVWF	FSR
	RETURN
;------------------------------------------------------------------------------
store_INDF_inc_FSR
	MOVWF	INDF
	INCF	FSR,F
	RETURN
;------------------------------------------------------------------------------
; wait	高速クロック用ウエイト
; mwait	高速クロック用ミリ秒、低速クロック用ウエイト
;
; 引数
;	W		時間
;
; 戻り値
;	なし
;
; 使用変数
;	TMP20,21,22
;------------------------------------------------------------------------------
wait					; 高速で1あたり約100ms、最大25秒
	MOVWF	TMP20
WAIT_0
	MOVLW	130
	MOVWF	TMP21
MWAIT_1
	CLRF	TMP22
MWAIT_2
	DECFSZ	TMP22,F
	 GOTO	MWAIT_2
	DECFSZ	TMP21,F
	 GOTO	MWAIT_1
	DECFSZ	TMP20,F
	 GOTO	WAIT_0
	RETURN

;------------------------------------------------------------------------------
; スタンバイ
;------------------------------------------------------------------------------
standby
	CLRF	STATUS			; ◆ RP=0,IRP=0
	CALL	send_STANDBY		; センサスタンバイ
	CALL	lcd_cls
	MOVLW	LOW txt_going_to
	MOVWF	TMP20
	MOVLW	HIGH txt_going_to
	MOVWF	TMP21
	CALL	getstr
	CLRF	LCD_X
	MOVLW	1
	MOVWF	LCD_Y
	CALL	puts16
	MOVLW	LOW txt_SLEEP
	MOVWF	TMP20
	MOVLW	HIGH txt_SLEEP
	MOVWF	TMP21
	CALL	getstr
	MOVLW	44
	MOVWF	LCD_X
	MOVLW	3
	MOVWF	LCD_Y
	CALL	puts16
	MOVLW	15
	CALL	wait
	CLRF	CCPR1L			; バックライトOFF
	MOVLW	5			; PR2がロールオーバーするまではCCPR1Lが反映されないのでウエイトを入れる
	CALL	wait
	MOVLW	B'00100100'		; Function Set(Power_Off, H_addr, Basic_Inst)
	CALL	lcd_command
	MOVLW	0x7F
	MOVWF	P_MSB
	MOVWF	T_MSB
	MOVLW	0xFF
	MOVWF	P_CSB
	MOVWF	P_LSB
	MOVWF	T_LSB
	CALL	HISTORY_DUMMY
	SLEEP
	GOTO	0
;------------------------------------------------------------------------------
	ORG	0x0800
;------------------------------------------------------------------------------
; システムリセット
;------------------------------------------------------------------------------
system_reset
	CLRF	STATUS			; ◆ RP=0,● IRP=0
	MOVLW	B'00110111'		; LCD_RSTをリセット状態にしておく。
	MOVWF	PORTA			; SDA,SCLはプルアップしてるので、TRIS=1でH、TRIS=0でLとなる。
	MOVLW	B'11000011'		; PORTAはRMW命令を使うとbit6,7が1に書き換わるので注意。
	MOVWF	PORTB			; PORTBを読み込むと状態変化割り込みが動作しなくなるので注意。

	BSF	STATUS,RP0		; ◆ RP=1
	MOVLW	B'01100000'		; 起動直後はOSC=INT_4MHz
	MOVWF	OSCCON

	CLRF	ANSEL
	MOVLW	B'11110000'		; [7]I2C_SDA [6]I2C_SCL [5]ENC_B  [4]ENC_SW  [3]LCD_RST [2-1]空き(H出力) [0]クロックインジケータ
	MOVWF	TRISA
	MOVLW	B'10000011'		; [7]ALT_INT [6]LCD_SCE [5]LCD_DC [4]SPI_CLK [3]PWM     [2]SPI_OUT [1]SPI_IN(未接続、外部でプルダウン) [0]ENC_A
	MOVWF	TRISB			; ここからLCDのリセットが始まる。

	MOVLW	B'11111000'		; RBプルアップ=OFF
	MOVWF	OPTION_REG		; TMR0 SRC=RA4、エッジ=立ち下げ、プリスケーラ=WDT 1:1

	MOVLW	B'01000000'		; SPI CKE=1
	MOVWF	SSPSTAT

	MOVLW	8			; PWM周期 (8+1)*4*1/31250=868Hz
	MOVWF	PR2			;         (8+1)*4*16/4E6 =6944Hz

	BCF	STATUS,RP0		; ◆ RP=0
	MOVLW	B'00100000'		; SPI有効、CKP=0、マスターモード、クロック=OSC/4(7.813kHz or 1MHz)
	MOVWF	SSPCON

	CLRF	CCPR1L			; DUTY=0%
	MOVLW	B'00000100'		; TIMER2=ON、プリスケーラ=1
	MOVWF	T2CON
	MOVLW	B'00001100'		; CCP1=PWM、CCP1X:CCP1Y=0
	MOVWF	CCP1CON

ENC_INIT				; エンコーダの初期位置に合わせてINT0の割り込みエッジを変える。
	BTFSC	PORTB,ENC_A
	 GOTO	ENC_INIT1
	BSF	STATUS,RP0		; ◆ RP=1
	BSF	OPTION_REG,INTEDG	; 位置がLなら立ち上げエッジ
	GOTO	ENC_INIT2
ENC_INIT1
	BSF	STATUS,RP0		; ◆ RP=1
	BCF	OPTION_REG,INTEDG	; 位置がHなら立ち下げエッジ
ENC_INIT2
	BCF	STATUS,RP0		; ◆ RP=0

LCD_INIT
	MOVLW	B'00111111'		; LCDリセット終了
	MOVWF	PORTA
	MOVLW	B'00100001'		; Function Set(Power_On, H_addr, Ext_Inst)
	CLRF	PCLATH			; ■ PCLATH
	CALL	lcd_command
	MOVLW	B'00000100'		; Set Temp Ctl TC=0
	CALL	lcd_command
	MOVLW	B'00010011'		; Set BIAS 1:48
	CALL	lcd_command
	MOVLW	B'11000000'		; Set Contrast
	CALL	lcd_command
	MOVLW	B'00100000'		; Function Set(Power_On, H_addr, Basic_Inst)
	CALL	lcd_command
	MOVLW	B'00001100'		; Set Disp Normal_Mode
	CALL	lcd_command
	CALL	lcd_cls
	MOVLW	3			; Backlight
	MOVWF	BACKLIGHT
	BSF	PCLATH,3		; ■ PCLATH
	CALL	lcd_backlight
	BCF	FLAG1,NEG_FONT

GETCONFIG
	BTFSS	PORTA,ENC_SW		; スイッチが押された状態で起動したら、設定を初期化する。
	 CALL	factory_reset
	CALL	get_config
	CALL	lcd_backlight
	CALL	lcd_contrast

SHOW_TITLE
	MOVLW	HIGH txt_title
	MOVWF	TMP21
	MOVLW	LOW  txt_title
	MOVWF	TMP20
	CLRF	PCLATH			; ■ PCLATH
	CALL	getstr
	MOVLW	22
	MOVWF	LCD_X
	CLRF	LCD_Y
	CALL	puts16
	MOVLW	HIGH txt_version
	MOVWF	TMP21
	MOVLW	LOW  txt_version
	MOVWF	TMP20
	CALL	getstr
	MOVLW	30
	MOVWF	LCD_X
	MOVLW	3
	MOVWF	LCD_Y
	CALL	puts8
	MOVLW	20
	CALL	wait			; 2秒ウエイト

SENSOR_INIT				; 初回のみ必要なセンサの設定
	BCF	FLAG1,I2C_RW		; WRITE
	CALL	i2c_start
	MOVLW	PT_DATA_CFG		; イベントフラグ
	CALL	i2c_send
	MOVLW	0x07			; DREM | PDEFE | TDEFE
	CALL	i2c_send

	CALL	i2c_start
	MOVLW	CTRL_REG4		; 割り込み
	CALL	i2c_send
	MOVLW	0x80			; INT_EN_DRDY
	CALL	i2c_send

	BSF	PCLATH,3		; ■ PCLATH 戻りはPCLATH=0
	CALL	send_CALIB		; キャリブレーションデータやQNHはあらかじめ送信しておき、
	CALL	send_QNH		; モード変更では送信せずに設定値の変更で再送する。
	
	MOVLW	B'10111000'		; GIE=ON、TMR0=ENC_SW割り込み、INT=ENC_A割り込み、RBIOC[7]=高度計割り込み
	MOVWF	INTCON
	MOVLW	0xFF			; TMR0をあと1カウントで割り込みがかかる状態にしておく。
	MOVWF	TMR0
	
	BCF	FLAG2,HOLD_GRAPH
	BTFSS	STATUS,NOT_PD		; スリープ復帰の時はグラフクリアを抑制する
	 BSF	FLAG2,HOLD_GRAPH
	
;---------------------------------- 初期化完了 ----------------------------------
MODE_CHANGE				; モード切り替えで実行する内容
	BSF	PCLATH,3		; ■ PCLATH
	BTFSC	FLAG2,HOLD_GRAPH
	 GOTO	MODE_CHANGE_2
	CLRF	GRAPHPTR		; フラグクリア
	MOVLW	HISTORY_SIZE
	MOVWF	TMP00
	MOVLW	LOW PRESSBUF_LSB
	MOVWF	FSR
MODE_CHANGE_1
	BSF	STATUS,IRP		; ● IRP=1
	CLRF	INDF			; 0x134-
	BSF	FSR,7
	CLRF	INDF			; 0x1B4-
	BCF	STATUS,IRP		; ● IRP=0
	CLRF	INDF			; 0x0B4-
	BCF	FSR,7
	INCF	FSR,F
	DECFSZ	TMP00,F
	 GOTO	MODE_CHANGE_1

MODE_CHANGE_2
	CLRF	PCLATH			; ■ PCLATH
	CALL	send_STANDBY		; 計測停止
	CLRF	FLAG1
	CLRF	FLAG2
	MOVLW	LOW FIFOBUF		; FIFO初期化
	MOVWF	READPTR
	MOVWF	WRITEPTR
	CLRF	USEDSIZE

	CLRF	P1_MSB
	CLRF	P1_CSB
	CLRF	P1_LSB

SENSOR_ENABLE				; センサ有効化
	BSF	PCLATH,3		; ■ PCLATH
	CALL	send_ST
	CALL	send_ACTIVE		; REG1
	CALL	lcd_cls
	MOVF	MODE_CFG,W
	BTFSC	STATUS,Z		; 高度計ビュー0の時はQNH表示
	 CALL	disp_qnh
	BSF	FLAG2,OFFSET_INIT
	GOTO	MAINLOOP

;------------------------------------------------------------------------------
send_CALIB				; キャリブレーションデータ送信
	CLRF	PCLATH			; ■ PCLATH
	BCF	FLAG1,I2C_RW		; WRITE
	CALL	i2c_start
	MOVLW	OFF_P
	CALL	i2c_send
	MOVF	CAL_BARO,W
	CALL	i2c_send
	MOVF	CAL_TEMP,W
	CALL	i2c_send
	MOVF	CAL_ALT,W
	GOTO	SEND_AND_STOP

send_ST
	MOVLW	1			; 初回カウントでインターバルカウンタをリロードさせる
	MOVWF	INT_COUNT
	CLRF	PCLATH			; ■ PCLATH
	BCF	FLAG1,I2C_RW		; WRITE
	CALL	i2c_start
	MOVLW	CTRL_REG2		; ST
	CALL	i2c_send
	MOVLW	HIGH BARO_ST_TABLE
	MOVWF	PCLATH			; ■ PCLATH
	MOVF	BARO_INTERVAL,W
	CALL	get_baro_st		; BAROの時は設定値からSTを導く
	BTFSS	MODE_CFG,MODE
	 CLRW				; ALTの時は0
	CLRF	PCLATH			; ■ PCLATH
	GOTO	SEND_AND_STOP
;------------------------------------------------------------------------------
; 設定初期化
;
; 引数
;	なし
;
; 戻り値
;	なし
;
; 使用変数
;	TMP20,21
;------------------------------------------------------------------------------
factory_reset
	MOVLW	HIGH txt_reset	; 初期化メッセージ
	MOVWF	TMP21
	MOVLW	LOW  txt_reset
	MOVWF	TMP20
	CLRF	PCLATH			; ■ PCLATH
	CALL	getstr
	MOVLW	3
	MOVWF	LCD_X
	MOVLW	5
	MOVWF	LCD_Y
	CALL	puts8

	BSF	PCLATH,3		; ■ PCLATH プログラムメモリから初期設定を読み出してEEPROMに書く
	BSF	STATUS,RP1		; ◆ RP=2
	CLRF	TMP20			; 書き込むEEPROMアドレス
FACTORY_RESET_LOOP
	MOVF	TMP20,W		; プログラムメモリのオフセットを加算
	ADDLW	LOW FACTORY_DATA
	MOVWF	EEADR
	MOVLW	HIGH FACTORY_DATA
	BTFSC	STATUS,C
	 ADDLW	1
	MOVWF	EEADRH
	BSF	STATUS,RP0		; ◆ RP=3
	BSF	EECON1,EEPGD		; PGM READ
	BSF	EECON1,RD
	NOP
	NOP

	BCF	STATUS,RP0		; ◆ RP=2
	MOVF	TMP20,W			; 書き込むアドレス
	MOVWF	EEADR
	BSF	STATUS,RP0		; ◆ RP=3
	BCF	EECON1,EEPGD		; DAT WRITE
	BSF	EECON1,WREN
	MOVLW	0x55
	MOVWF	EECON2
	MOVLW	0xAA
	MOVWF	EECON2
	BSF	EECON1,WR
	BCF	EECON1,WREN
	BTFSC	EECON1,WR		; 書き込み待ち
	 GOTO	$-1

	BCF	STATUS,RP0		; ◆ RP=2
	INCF	TMP20,F
	MOVF	TMP20,W
	SUBLW	EE_END			; データの数だけループ
	BTFSS	STATUS,Z
	 GOTO	FACTORY_RESET_LOOP
	BCF	STATUS,RP1		; ◆ RP=0
	
	BSF	PCLATH,3		; ■ PCLATH 次に必ずget_configが来るので予めPCLATHをセットしておく
	RETURN

FACTORY_DATA				; 初期化データ
	DA	DEF_MODE_CFG
	DA	DEF_ALT_CFG
	DA	DEF_BARO_CFG
	DA	DEF_TEMP_CFG
	DA	DEF_ALT_RANGE
	DA	DEF_BARO_RANGE
	DA	DEF_TEMP_RANGE
	DA	DEF_QNH_MSB
	DA	DEF_QNH_LSB
	DA	DEF_ALT_INTERVAL
	DA	DEF_ALT_OSR
	DA	DEF_BARO_INTERVAL
	DA	DEF_BARO_OSR
	DA	DEF_BACKLIGHT
	DA	DEF_CONTRAST
	DA	DEF_CAL_ALT
	DA	DEF_CAL_BARO
	DA	DEF_CAL_TEMP
	DA	DEF_CAL_VSI
	DA	DEF_VSIWIDE
;------------------------------------------------------------------------------
; 設定値読み出し
;
; 引数
;	なし
;
; 戻り値
;	なし
;
; 使用変数
;	TMP20
;------------------------------------------------------------------------------
get_config
	CLRF	TMP20			; 読み出しEEPROMアドレス
	BCF	STATUS,IRP		; ● IRP=0
	MOVLW	MODE_CFG
	MOVWF	FSR			; 取得後に書き込む場所
GET_CONFIG_LOOP
	MOVF	TMP20,W
	CLRF	PCLATH			; ■ PCLATH
	CALL	read_ee_data
	MOVWF	INDF
	INCF	FSR,F
	INCF	TMP20,F
	MOVF	TMP20,W
	SUBLW	EE_END
	BSF	PCLATH,3		; ■ PCLATH
	BTFSS	STATUS,Z
	 GOTO	GET_CONFIG_LOOP
	RETURN
;------------------------------------------------------------------------------
; FIFO書き込み
;	バッファがいっぱいの場合は、データを書き込まずにフルフラグをセットしてリターンする。
;
; 引数
;	W		書き込むデータ(破壊)
;
; 戻り値
;	FIFO_FULL	FIFOバッファフルフラグ
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
fifo_write
	MOVWF	WRITEDATA		; Wに入っている書き込みデータを退避
	MOVLW	FIFO_SIZE		; バッファフルチェック
	SUBWF	USEDSIZE,W
	BTFSS	STATUS,Z
	 GOTO	FIFO_WRITE1
	BSF	FLAG1,FIFO_FULL		; フルフラグを立ててリターン
	RETURN
FIFO_WRITE1
	BCF	FLAG1,FIFO_FULL		; フルフラグOFF
	BCF	STATUS,IRP		; ● IRP=0
	MOVF	WRITEPTR,W		; バッファを間接アクセス
	MOVWF	FSR
	MOVF	WRITEDATA,W
	MOVWF	INDF
	INCF	USEDSIZE,F		; データ量を+1(呼び出し時にチェックをしているので、データ数オーバーになることはない)
	INCF	WRITEPTR,F
FIFO_WRITE2
	MOVLW	LOW FIFOBUF		; ポインタのロールオーバーのチェック
	ADDLW	FIFO_SIZE
	SUBWF	WRITEPTR,W
	BTFSS	STATUS,Z
	 RETURN				; そのままリターン
	MOVLW	LOW FIFOBUF		; ロールオーバーしていたならば、先頭位置に移動
	MOVWF	WRITEPTR
	RETURN

;------------------------------------------------------------------------------
; 割り込み処理
;------------------------------------------------------------------------------
INTERRUPT				; スイッチ入力
	BTFSS	INTCON,TMR0IF
	 GOTO	INT_INT0
	BCF	INTCON,TMR0IF		; フラグリセット
	MOVLW	0xFF			; カウンタを-1にセット
	MOVWF	TMR0
	MOVLW	0
	CALL	fifo_write

INT_INT0				; エンコーダA入力
	BTFSS	INTCON,INT0IF
	 GOTO	INT_RB
	BCF	INTCON,INT0IF		; フラグリセット
	BSF	STATUS,RP0		; ◆ RP=1
	MOVLW	B'01000000'		; 割り込みエッジを反転
	XORWF	OPTION_REG,F

	RRF	OPTION_REG,W		; エンコーダの増減を検出
	BCF	STATUS,RP0		; ◆ RP=0
	XORWF	PORTA,W			; PORTBを読むと状態変化割り込みが正しく働かなくなるので、トリガエッジで判断させる。
	ANDLW	0x20
	MOVLW	2			; −の時
	BTFSC	STATUS,Z
	 MOVLW	3			; ＋の時
	CALL	fifo_write

INT_RB					; 高度計割り込み入力
	BTFSS	INTCON,RBIF
	 GOTO	INT_RETURN
	MOVLW	4
	BTFSS	PORTB,ALT_INT		; 立ち上がり変化の時は無視する
	 CALL	fifo_write
	BCF	INTCON,RBIF		; フラグリセット

INT_RETURN
	MOVF	FSR_,W			; FSRリストア
	MOVWF	FSR
	MOVF	PCLATH_,W		; PCLATHリストア
	MOVWF	PCLATH
	SWAPF	STATUS_,W		; STATUSリストア
	MOVWF	STATUS
	SWAPF	W_,F			; Wリストア
	SWAPF	W_,W
	RETFIE

;------------------------------------------------------------------------------
; インターバルインデックステーブル
;------------------------------------------------------------------------------
get_alt_interval
	ADDWF	PCL,F
ALT_INTERVAL_TABLE
	 RETLW	1
	 RETLW	2
	 RETLW	3
	 RETLW	5
	 RETLW	10
	 RETLW	20
	 RETLW	30
	 RETLW	60

get_baro_interval
	ADDWF	PCL,F
BARO_INTERVAL_TABLE
	 RETLW	15	;   4s* 15=60s	1h
	 RETLW	15	;   8s* 15=120s	2h
	 RETLW	45	;   4s* 45=180s	3h
	 RETLW	15	;  16s* 15=240s	4h
	 RETLW	45	;   8s* 45=360s	6h
	 RETLW	15	;  32s* 15=480s	8h
	 RETLW	45	;  16s* 45=720s	12h
	 RETLW	135	;   8s*135=1080s 18h
	 RETLW	45	;  32s* 45=1440s 24h
	 RETLW	135	;  16s*135=2160s 36h
	 RETLW	45	;  64s* 45=2880s 48h
	 RETLW	135	;  32s*135=4320s 72h
	 RETLW	45	; 128s* 45=5760s 96h

get_baro_st
	ADDWF	PCL,F
BARO_ST_TABLE
	 RETLW	2	;   4s* 15=60s	1h
	 RETLW	3	;   8s* 15=120s	2h
	 RETLW	2	;   4s* 45=180s	3h
	 RETLW	4	;  16s* 15=240s	4h
	 RETLW	3	;   8s* 45=360s	6h
	 RETLW	5	;  32s* 15=480s	8h
	 RETLW	4	;  16s* 45=720s	12h
	 RETLW	3	;   8s*135=1080s 18h
	 RETLW	5	;  32s* 45=1440s 24h
	 RETLW	4	;  16s*135=2160s 36h
	 RETLW	6	;  64s* 45=2880s 48h
	 RETLW	5	;  32s*135=4320s 72h
	 RETLW	7	; 128s* 45=5760s 96h
;------------------------------------------------------------------------------
; 設定モードループ
;------------------------------------------------------------------------------
CONFIGURATION
	CLRF	MENUPOSITION
	CLRF	MENUROW
	BCF	FLAG2,EDIT_VALUE
CONFIGLOOP
	CALL	menu_display
CONFIG_NODISPLAY
	CLRF	PCLATH			; ■ PCLATH
	CALL	event_wait
	MOVF	MENUPOSITION,W
	ANDLW	15
	MOVWF	TMP00			; TMP00=表示開始行
	SWAPF	MENUPOSITION,W
	ANDLW	15
	MOVWF	TMP01			; TMP01=メニューツリー
	MOVF	MENUPOSITION,W
	ADDWF	MENUROW,W
	MOVWF	TMP02			; TMP02=選択しているメニュー
	MOVLW	HIGH (CFGEVENT_TABLE+1)
	MOVWF	PCLATH			; ■ PCLATH
	MOVF	TMP20,W
CFGEVENT_TABLE				; イベント番号で分岐
	ADDWF	PCL,F
	 GOTO	cfgKEY_SHORT		; 0
	 GOTO	cfgKEY_LONG		; 1
	 GOTO	cfgDIAL_DECR		; 2
	 GOTO	cfgDIAL_INCR		; 3
	 GOTO	cfgSENSOR		; 4
;------------------------------------------------------------------------------
cfgKEY_SHORT
	MOVF	TMP02,W
	BTFSS	STATUS,Z
	 GOTO	cfgKEY_SHORT_01
cfgKEY_SHORT_00				; SLEEPの時ダイアル位置をチェックしてスリープを拒否させる
	BSF	STATUS,RP0		; ◆ RP=1
	CLRF	PCLATH			; ■ PCLATH
	BTFSS	OPTION_REG,INTEDG
	 GOTO	standby
	BCF	STATUS,RP0		; ◆ RP=0
	GOTO	FORCE_REDRAW
cfgKEY_SHORT_01				; Return
	DECF	TMP02,W
	BTFSS	STATUS,Z
	 GOTO	cfgKEY_SHORT_ROOT
	MOVLW	4			; VIEWを0にリセットしてからモードを切り替える
	ANDWF	MODE_CFG,F
	MOVLW	MODE_CFG
	MOVWF	FSR
	MOVLW	4
	CALL	change_flag
	GOTO	MODE_CHANGE
cfgKEY_SHORT_ROOT			; 表示階層の変更
	MOVF	TMP01,W
	BTFSS	STATUS,Z
	 GOTO	cfgKEY_SHORT_BACK
	MOVF	MENUPOSITION,W		; 表示位置を保存
	MOVWF	BEF_POSITION
	MOVF	MENUROW,W
	MOVWF	BEF_ROW
	SWAPF	TMP02,W			; 項目番号からツリーに入る
	ADDLW	0xF0
	MOVWF	MENUPOSITION
	CLRF	MENUROW
	GOTO	CONFIGLOOP
cfgKEY_SHORT_BACK			; BACK位置ならば保存していた場所に戻る
	MOVF	TMP02,W
	ANDLW	0x0F
	BTFSS	STATUS,Z
	 GOTO	cfgKEY_SHORT_XX
	MOVF	BEF_POSITION,W
	MOVWF	MENUPOSITION
	MOVF	BEF_ROW,W
	MOVWF	MENUROW	
	GOTO	CONFIGLOOP
cfgKEY_SHORT_XX				; それ以外は編集フラグを反転
	MOVLW	B'00100000'
	XORWF	FLAG2,F
	CLRF	CALCOUNT_L
	CLRF	CALCOUNT_M
	GOTO	CONFIGLOOP
;------------------------------------------------------------------------------
cfgKEY_LONG
	CLRF	PCLATH			; ■ PCLATH
	GOTO	FORCE_REDRAW
;------------------------------------------------------------------------------
cfgDIAL_DECR
	BTFSC	FLAG2,EDIT_VALUE
	 GOTO	DECR_VALUE
	MOVF	MENUROW,W		; 0行目以上の時は行-1
	BTFSC	STATUS,Z
	 GOTO	cfgDIAL_DECR2
	DECF	MENUROW,F
	GOTO	CONFIGLOOP
cfgDIAL_DECR2
	MOVF	TMP00,W			; 表示開始行が0でなければ-1
	BTFSC	STATUS,Z
	 GOTO	CONFIGLOOP		; SLEEP表示を更新しないといけないので、再描画を行う。
	DECF	MENUPOSITION,F
	GOTO	CONFIGLOOP
;------------------------------------------------------------------------------
cfgDIAL_INCR
	BTFSC	FLAG2,EDIT_VALUE
	 GOTO	INCR_VALUE
	MOVF	TMP01,W
	CALL	menurow_limit		; 行が上限でなければ+1
	SUBWF	MENUROW,W
	BTFSC	STATUS,Z
	 GOTO	cfgDIAL_INCR2
	INCF	MENUROW,F
	GOTO	CONFIGLOOP
cfgDIAL_INCR2
	MOVF	TMP01,W
	CALL	menuposition_limit	; 表示開始行が上限でなければ+1
	SUBWF	TMP00,W
	BTFSC	STATUS,Z
	 GOTO	CONFIG_NODISPLAY
	INCF	MENUPOSITION,F
	GOTO	CONFIGLOOP
menurow_limit
	ADDWF	PCL,F
	 RETLW	5
	 RETLW	5
	 RETLW	5
	 RETLW	2
	 RETLW	2
	 RETLW	4
menuposition_limit
	ADDWF	PCL,F
	 RETLW	1
	 RETLW	5
	 RETLW	0
	 RETLW	0
	 RETLW	0
	 RETLW	0

DECR_VALUE
INCR_VALUE
	MOVF	TMP02,W
	MOVWF	TMP03
	MOVLW	0x51			; 途切れているメニュー番号を詰めて並べてTMP03に入れる
	SUBWF	TMP03,W
	MOVLW	0x51-0x43		; ALT  SubDisp
	BTFSC	STATUS,C		;      GraphType
	 SUBWF	TMP03,F			;      ALT Unit
	MOVLW	0x41			;      VSI Unit
	SUBWF	TMP03,W			;      QNH Unit
	MOVLW	0x41-0x33		;      VSI Avg.
	BTFSC	STATUS,C		;      VSI RANGE
	 SUBWF	TMP03,F			;      Y-Axis
	MOVLW	0x31			;      TimeSpan
	SUBWF	TMP03,W			;      OSR
	MOVLW	0x31-0x26		; BARO SubDisp
	BTFSC	STATUS,C		;      GraphType
	 SUBWF	TMP03,F			;      Press Unit
	MOVLW	0x21			;      TimeSpan
	SUBWF	TMP03,W			;      OSR
	MOVLW	0x21-0x1B		; TEMP Temp Unit
	BTFSC	STATUS,C		;      GraphType
	 SUBWF	TMP03,F			; Backlight
	MOVLW	0x11			; Contrast
	SUBWF	TMP03,F			; CAL Alt
					;     Press
	INCF	TMP03,W			;     Temp
	MOVWF	TMP13			;     VSI
	CLRF	TMP10
	MOVLW	B'01100011'		; メモリ節約のためビットフィールドで条件を決める
	MOVWF	TMP11			; 0=FLAG, 1=NUMBER
	MOVLW	B'01111110'
	MOVWF	TMP12
EDIT_TYPE
	RRF	TMP12,F
	RRF	TMP11,F
	RRF	TMP10,F
	DECFSZ	TMP13,F
	 GOTO	EDIT_TYPE
	BTFSS	STATUS,C
	 GOTO	EDIT_FLAG
	GOTO	EDIT_NUMBER
EDIT_FLAG				; フラグ編集
	MOVLW	0x20
	ADDWF	TMP01,W
	MOVWF	FSR			; 変更するメモリアドレス
	MOVF	TMP02,W
	ANDLW	0x0F
	CLRF	PCLATH			; ■ PCLATH
	CALL	exp24
	BSF	PCLATH,3		; ■ PCLATH
	MOVF	MATH00,W
	CALL	change_flag		; TMP00と01が壊れる
	MOVLW	0x15
	SUBWF	TMP02,W			; QNH Unitの時だけ後処理を行う
	BTFSS	STATUS,Z
	 GOTO	CONFIGLOOP

	BTFSC	ALT_CFG,QNH_UNIT
	 GOTO	INCH_TO_HPA
HPA_TO_INCH
	CLRF	MATH00			; hPaからinHgへ変換
	BCF	STATUS,C		; hPaは2倍してから変換
	RLF	QNH_LSB,W		; 小数点の位置に注意
	MOVWF	MATH01
	RLF	QNH_MSB,W
	MOVWF	MATH02
	CLRF	MATH03
	RLF	MATH03,F
	CLRF	PCLATH			; ■ PCLATH
	CALL	convert_hpa2inch
	BSF	PCLATH,3		; ■ PCLATH
	MOVF	MATH01,W
	MOVWF	QNH_MSB
	MOVF	MATH00,W
	MOVWF	QNH_LSB
	GOTO	SAVE_QNH
INCH_TO_HPA
	CLRF	PCLATH			; ■ PCLATH
	CALL	convert_inch2hpa	; inHgからhPaはルーチンを呼ぶだけ
	MOVF	TMP11,W
	MOVWF	QNH_MSB
	MOVF	TMP10,W
	MOVWF	QNH_LSB
SAVE_QNH
	BCF	STATUS,IRP		; ●IRP=0
	MOVLW	QNH_MSB
	MOVWF	FSR
	MOVLW	EE_QNH_MSB
	MOVWF	_EEADDR
	MOVLW	2
	CLRF	PCLATH			; ■ PCLATH
	CALL	write_ee_data		; 変換済みの値を保存する。
	CALL	send_QNH		; 丸め誤差が出るのでセンサへ再送する。
	BSF	PCLATH,3		; ■ PCLATH
	GOTO	CONFIGLOOP

numlowlimit
	SUBLW	5
	CLRW				; CAL以外は0
	BTFSS	STATUS,C
	 MOVLW	0x80			; CALの場合は一律0x80
	RETURN				; テーブルにするほどでもない

numhighlimit
	ADDWF	PCL,F
	 RETLW	7			; ALT_INTERVAL
	 RETLW	7			; ALT_OSR
	 RETLW	12			; BARO_INTERVAL
	 RETLW	7			; BARO_OSR
	 RETLW	9			; BACKLIGHT
	 RETLW	9			; CONTRAST
	 RETLW	0x7F			; CAL_ALT
	 RETLW	0x7F			; CAL_BARO
	 RETLW	0x7F			; CAL_TEMP
	 RETLW	0x7F			; CAL_VSI

post_proccess
	ADDWF	PCL,F
	 GOTO	POST_CTRLREG
	 GOTO	POST_CTRLREG
	 GOTO	POST_CTRLREG
	 GOTO	POST_CTRLREG
	 GOTO	lcd_backlight
	 GOTO	lcd_contrast
	 GOTO	send_CALIB
	 GOTO	send_CALIB
	 GOTO	send_CALIB
	 RETURN

POST_CTRLREG
	RLF	TMP03,W			; 実行中のモードと設定したモードは同じか?
	XORWF	MODE_CFG,W
	ANDLW	4
	BTFSS	STATUS,Z
	 RETURN				; 違うならOSR,STを再送する必要は無い。
	CLRF	PCLATH			; ■ PCLATH
	CALL	send_STANDBY		; 計測停止
	BSF	PCLATH,3		; ■ PCLATH
	BTFSS	TMP03,0			; 変更したのはINTERVAL?
	 CALL	send_ST			;  ならばSTを送る。
	CLRF	PCLATH			; ■ PCLATH
	CALL	send_ACTIVE		; REG1(OSR)
	RETURN
		
EDIT_NUMBER
	MOVLW	17			; 数値編集のメニュー番号を詰めて並べてTMP03に入れる
	SUBWF	TMP03,W
	MOVLW	2
	BTFSC	STATUS,C
	 SUBWF	TMP03,F
	MOVLW	13
	SUBWF	TMP03,W
	MOVLW	3
	BTFSC	STATUS,C
	 SUBWF	TMP03,F
	MOVLW	8
	SUBWF	TMP03,F
	BCF	STATUS,IRP		; ●IRP=0
	MOVLW	ALT_INTERVAL		; 変更するメモリアドレスを計算
	ADDWF	TMP03,W
	MOVWF	FSR
	MOVLW	HIGH numhighlimit	; ■ PCLATH
	MOVWF	PCLATH
	MOVF	TMP03,W
	BTFSS	TMP20,0			; DECR_VALUEイベント?
	 CALL	numlowlimit
	BTFSC	TMP20,0
	 CALL	numhighlimit		; INCR_VALUEイベント?
	SUBWF	INDF,W			; 上限下限チェック
	BTFSC	STATUS,Z		; 既にリミットに達している場合は何も実行しない
	 GOTO	CONFIG_NODISPLAY
	BTFSS	TMP20,0			; DECR_VALUEイベント?
	 DECF	INDF,F
	BTFSC	TMP20,0			; INCR_VALUEイベント?
	 INCF	INDF,F
	CALL	save_value
	MOVLW	HIGH post_proccess
	MOVWF	PCLATH			; ■ PCLATH
	MOVF	TMP03,W
	CALL	post_proccess
	BSF	PCLATH,3		; ■ PCLATH
	GOTO	CONFIGLOOP

;------------------------------------------------------------------------------
cfgSENSOR				; 裏でデータ取得だけ実行させる
	CLRF	PCLATH			; ■ PCLATH
	CALL	retrieve
	INCF	CALCOUNT_L,F
	BTFSC	STATUS,Z
	 INCF	CALCOUNT_M,F
	BSF	PCLATH,3		; ■ PCLATH
	MOVF	MENUPOSITION,W
	ADDWF	MENUROW,W
	SUBLW	0x54
	BTFSC	FLAG2,EDIT_VALUE	; EDIT_VALUEが1でVSIキャリブレーションの時だけカウンタを表示させる
	 BTFSS	STATUS,Z
	GOTO	CONFIG_NODISPLAY
	MOVF	CALCOUNT_L,W
	MOVWF	MATH00
	MOVF	CALCOUNT_M,W
	MOVWF	MATH01
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW STRING
	MOVWF	FSR
	CLRF	PCLATH			; ■ PCLATH
	CALL	dec_10000
	CALL	dec_1000
	CALL	format_xxx
	CLRF	INDF
	MOVLW	4
	CALL	zero_replace
	MOVLW	5
	MOVWF	LCD_Y
	MOVLW	36
	MOVWF	LCD_X
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH
	GOTO	CONFIG_NODISPLAY
;------------------------------------------------------------------------------
; メニュー画面表示
; PCLATHのでコードを省略しているので、プログラムの置き場所に注意。
;
; 使用変数
; 	TMP00,01,02
;------------------------------------------------------------------------------
menu_display			
	CLRF	PCLATH			; ■ PCLATH
	CALL	lcd_cls
	CLRF	LCD_Y
	MOVLW	HIGH txt_SLEEP		; 文字列の上位アドレスはページをまたがないように配置してコードを削減する
	MOVWF	TMP21
	MOVF	MENUPOSITION,W
	ANDLW	15
	MOVWF	TMP00			; TMP00=表示開始行
	
	MOVLW	HIGH MENU_TABLE
	MOVWF	PCLATH			; ■ PCLATH
	SWAPF	MENUPOSITION,W
	ANDLW	15
	MOVWF	TMP01			; TMP01=メニューツリー
	ADDWF	PCL,F
MENU_TABLE
	GOTO	MENU_ROOT
	GOTO	MENU_ALT
	GOTO	ROW_BACK		; BARO,TEMP,DISP,CALは6行以下なので、途中から表示させる分岐は必要ない。
	GOTO	ROW_BACK
	GOTO	ROW_BACK
	GOTO	ROW_BACK

MENU_ROOT
	MOVF	TMP00,W
	BTFSC	STATUS,Z
	 GOTO	ROW_SLEEP
	GOTO	ROW_MODE		; これ以下は不要

MENU_ALT
	MOVF	TMP00,W
	ADDWF	PCL,F
	 GOTO	ROW_BACK
	 GOTO	ROW_SUBDISP
	 GOTO	ROW_GRAPHTYPE
	 GOTO	ROW_ALTUNIT
	 GOTO	ROW_VSIUNIT
	 GOTO	ROW_QNHUNIT		; これ以下は不要
	
;------------------------------------------------------------------------------
; 個々のメニュー表示
;------------------------------------------------------------------------------
check_edit
	BTFSS	FLAG2,EDIT_VALUE
	 RETURN
check_cursor				; カーソル位置の行は反転フラグをONにする
	MOVF	LCD_Y,W
	SUBWF	MENUROW,W
	BTFSC	STATUS,Z
	 BSF	FLAG1,NEG_FONT
	RETURN

print_value				; 指定の場所に指定した文字を取得して表示
	MOVWF	LCD_X
	CLRF	PCLATH			; ■ PCLATH=P0
	CALL	getstr
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH=P1
	RETURN

print_menu
	MOVWF	TMP20			; 指定した文字をX=0に表示し、次の行への準備をする
	CALL	check_cursor
	CLRW
	CALL	print_value
	BCF	FLAG1,NEG_FONT
	INCF	LCD_Y,F
	MOVF	LCD_Y,W
	SUBLW	6
	RETURN
;------------------------------------------------------------------------------
ROW_SLEEP
	MOVLW	LOW txt_SLEEP
	BSF	STATUS,RP0		; ◆ RP=1
	BTFSC	OPTION_REG,INTEDG
	 MOVLW	LOW txt_RETURN
	BCF	STATUS,RP0		; ◆ RP=0
	CALL	print_menu
ROW_MODE
	MOVLW	LOW txt_ALTIMETER
	BTFSC	MODE_CFG,MODE
	 MOVLW	LOW txt_BAROMETER
	MOVWF	TMP20
	MOVLW	30
	CALL	print_value
	MOVLW	LOW txt_MODE
	CALL	print_menu
ROW_ALT
	MOVLW	LOW txt_ALTIMETER
	CALL	print_menu
ROW_BARO
	MOVLW	LOW txt_BAROMETER
	CALL	print_menu
ROW_TEMP
	MOVLW	LOW txt_TEMPERATURE
	CALL	print_menu
ROW_DISP
	MOVLW	LOW txt_DISPLAY
	CALL	print_menu
	BTFSC	STATUS,Z
	 RETURN
ROW_CAL
	MOVLW	LOW txt_CALIBRATION
	CALL	print_menu
	RETURN
;------------------------------------------------------------------------------
ROW_BACK
	MOVLW	LOW txt_BACK
	CALL	print_menu
	MOVLW	HIGH BACKNEXT_TABLE	; BACKは複数で共通なので、表示しているツリーによって分岐させる
	MOVWF	PCLATH			; ■ PCLATH
	DECF	TMP01,W
	ADDWF	PCL,F
BACKNEXT_TABLE
	 GOTO	ROW_SUBDISP		; 1 ALT
	 GOTO	ROW_SUBDISP		; 2 BARO
	 GOTO	ROW_TEMPUNIT		; 3 TEMP
	 GOTO	ROW_BACKLIGHT		; 4 DISP
	 GOTO	ROW_CALALT		; 5 CAL
	
ROW_SUBDISP
	CALL	check_edit
	BCF	STATUS,IRP		; ● IRP=0
	MOVLW	ALT_CFG-1
	ADDWF	TMP01,W			; ツリーの番号によってALT,BAROのどれを見るか
	MOVWF	FSR
	MOVLW	LOW txt_OFF
	BTFSC	INDF,ALT_SUBDISP
	 MOVLW	LOW txt_ON
	MOVWF	TMP20
	MOVLW	66
	CALL	print_value
	MOVLW	LOW txt_SUBDISPLAY
	CALL	print_menu
ROW_GRAPHTYPE
	CALL	check_edit
	BCF	STATUS,IRP		; ● IRP=0
	MOVLW	ALT_CFG-1
	ADDWF	TMP01,W			; ツリーの番号によってALT,BARO,TEMPのどれを見るか
	MOVWF	FSR
	MOVLW	LOW txt_DOT
	BTFSC	INDF,ALT_GTYPE
	 MOVLW	LOW txt_BAR
	MOVWF	TMP20
	MOVLW	60
	CALL	print_value
	MOVLW	LOW txt_GRAPHTYPE
	CALL	print_menu
	DECF	TMP01,W			; ツリーの番号によってALTかBAROへ分岐
	BTFSC	STATUS,Z
	 GOTO	ROW_ALTUNIT
	BTFSC	TMP01,0
	 RETURN				; TEMPの時はGRAPHTYPEが最後
	GOTO	ROW_PRESSUNIT
ROW_ALTUNIT
	CALL	check_edit
	MOVLW	LOW txt_ft
	BTFSC	ALT_CFG,ALT_UNIT
	 MOVLW	LOW txt_m
	MOVWF	TMP20
	MOVLW	54
	CALL	print_value
	MOVLW	LOW txt_ALTUNIT
	CALL	print_menu
ROW_VSIUNIT
	CALL	check_edit
	MOVLW	LOW txt_FPM
	BTFSC	ALT_CFG,VSI_UNIT
	 MOVLW	LOW txt_MPS
	MOVWF	TMP20
	MOVLW	54
	CALL	print_value
	MOVLW	LOW txt_VSIUNIT
	CALL	print_menu
ROW_QNHUNIT
	CALL	check_edit
	MOVLW	LOW txt_INHG
	BTFSC	ALT_CFG,QNH_UNIT
	 MOVLW	LOW txt_HPA
	MOVWF	TMP20
	MOVLW	54
	CALL	print_value
	MOVLW	LOW txt_QNHUNIT
	CALL	print_menu
	BTFSC	STATUS,Z
	 RETURN
ROW_VSIAVG
	CALL	check_edit
	MOVLW	LOW txt_OFF
	BTFSC	ALT_CFG,VSI_AVG
	 MOVLW	LOW txt_ON
	MOVWF	TMP20
	MOVLW	54
	CALL	print_value
	MOVLW	LOW txt_VSIAVG
	CALL	print_menu
	BTFSC	STATUS,Z
	 RETURN
ROW_VSIRANGE
	CALL	check_edit
	MOVLW	LOW txt_NRML
	BTFSC	ALT_CFG,VSI_RANGE
	 MOVLW	LOW txt_WIDE
	MOVWF	TMP20
	MOVLW	60
	CALL	print_value
	MOVLW	LOW txt_VSIRANGE
	CALL	print_menu
	BTFSC	STATUS,Z
	 RETURN
ROW_YAXIS
	CALL	check_edit
	MOVLW	LOW txt_FLOAT
	BTFSC	ALT_CFG,ALT_YTYPE
	 MOVLW	LOW txt_FIX
	MOVWF	TMP20
	MOVLW	42
	CALL	print_value
	MOVLW	LOW txt_YAXIS
	CALL	print_menu
	BTFSC	STATUS,Z
	 RETURN
ROW_TIMESPAN
	CALL	check_edit
	MOVLW	LOW txt_MIN
	BTFSC	TMP01,1
	 MOVLW	LOW txt_HOUR
	MOVWF	TMP20
	MOVLW	66
	CALL	print_value

	MOVLW	HIGH ALT_INTERVAL_TABLE
	MOVWF	PCLATH			; ■ PCLATH
	MOVLW	LOW STRING
	MOVWF	FSR
	BSF	STATUS,IRP		; ●IRP=1
	MOVLW	54
	MOVWF	LCD_X
	BTFSC	TMP01,1
	 GOTO	ROW_TIMESPAN_BARO
ROW_TIMESPAN_ALT
	MOVF	ALT_INTERVAL,W
	CALL	get_alt_interval
	MOVWF	MATH00
	GOTO	ROW_TIMESPAN2
ROW_TIMESPAN_BARO
	MOVF	BARO_INTERVAL,W
	CALL	get_baro_interval
	MOVWF	MATH10
	MOVF	BARO_INTERVAL,W
	CALL	get_baro_st
	CLRF	PCLATH			; ■ PCLATH
	ADDLW	1
	CALL	exp24
	CALL	mul8
	MOVLW	60
	MOVWF	MATH10
	CLRF	MATH11
	CALL	div16
ROW_TIMESPAN2
	CLRF	PCLATH			; ■ PCLATH
	CALL	format_xx
	CLRF	INDF
	MOVLW	1
	CALL	zero_replace
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH

	MOVLW	LOW txt_TIMESPAN
	CALL	print_menu
	BTFSC	STATUS,Z
	 RETURN
ROW_OSR
	CALL	check_edit
	MOVLW	ALT_OSR
	BTFSC	TMP01,1			; ツリーの番号によってALT,BAROのどれを見るか
	 MOVLW	BARO_OSR
	MOVWF	FSR
	MOVLW	66
	CALL	print_n
	MOVLW	LOW txt_OVERSAMPLE
	CALL	print_menu
	RETURN

print_n
	MOVWF	LCD_X
	BCF	STATUS,IRP		; ● IRP=0
	MOVF	INDF,W
	MOVWF	MATH00
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW STRING
	MOVWF	FSR
	CLRF	PCLATH			; ■ PCLATH
	CALL	dec_1
	CLRF	INDF			; NULL
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH
	RETURN
;------------------------------------------------------------------------------
ROW_PRESSUNIT
	CALL	check_edit
	MOVLW	LOW txt_HPA
	BTFSC	BARO_CFG,BARO_UNIT
	 MOVLW	LOW txt_INHG
	MOVWF	TMP20
	MOVLW	60
	CALL	print_value
	MOVLW	LOW txt_PRESSUNIT
	CALL	print_menu
	GOTO	ROW_TIMESPAN
;------------------------------------------------------------------------------
ROW_TEMPUNIT
	CALL	check_edit
	MOVLW	LOW txt_C
	BTFSC	TEMP_CFG,TEMP_UNIT
	 MOVLW	LOW txt_F
	MOVWF	TMP20
	MOVLW	60
	CALL	print_value
	MOVLW	LOW txt_TEMPUNIT
	CALL	print_menu
	GOTO	ROW_GRAPHTYPE
;------------------------------------------------------------------------------
ROW_BACKLIGHT
	CALL	check_edit
	MOVLW	BACKLIGHT
	MOVWF	FSR
	MOVLW	60
	CALL	print_n
	MOVLW	LOW txt_BACKLIGHT
	CALL	print_menu
ROW_CONTRAST
	CALL	check_edit
	MOVLW	CONTRAST
	MOVWF	FSR
	MOVLW	54
	CALL	print_n
	MOVLW	LOW txt_CONTRAST
	CALL	print_menu
	RETURN
;------------------------------------------------------------------------------
ROW_CALALT
	CALL	check_edit
	CLRF	MATH02			; 負の数の時はMATH02もFFにする
	BTFSC	CAL_ALT,7
	 COMF	MATH02,F
	MOVF	CAL_ALT,W
	MOVWF	MATH01
	CLRF	MATH00			; MATH00は0クリアでok
	BSF	FLAG2,CALIB
	CLRF	PCLATH			; ■ PCLATH
	CALL	alt2meter
	BCF	FLAG2,CALIB
	MOVLW	42
	MOVWF	LCD_X
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH
	MOVLW	LOW txt_ALTITUDE
	CALL	print_menu
ROW_CALPRESS
	CALL	check_edit
	MOVF	CAL_BARO,W
	MOVWF	MATH02
	CLRF	MATH01
	CLRF	MATH00
	CLRF	PCLATH			; ■ PCLATH
	CALL	altx100			; 符号判定を流用
	CLRF	MATH01
	BCF	STATUS,C
	RLF	MATH02,W
	MOVWF	MATH00
	RLF	MATH01,F
	RLF	MATH00,F
	RLF	MATH01,F
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW STRING
	MOVWF	FSR
	MOVLW	'0'			; 符号用のスペースを入れておく
	MOVWF	INDF
	INCF	FSR,F
	CALL	format_x_xx
	CALL	hpa_unit
	BTFSC	FLAG1,MATH_SIGN
	 CALL	add_sign	
	MOVLW	36
	MOVWF	LCD_X
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH
	MOVLW	LOW txt_PRESSURE
	CALL	print_menu
ROW_CALTEMP
	CALL	check_edit
	SWAPF	CAL_TEMP,W
	ANDLW	0xF0
	MOVWF	MATH00
	SWAPF	CAL_TEMP,W
	ANDLW	0x0F
	BTFSC	CAL_TEMP,7
	 IORLW	0xF0
	MOVWF	MATH01
	CLRF	PCLATH			; ■ PCLATH
	CALL	temp2celsius
	MOVLW	30
	MOVWF	LCD_X
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH
	MOVLW	LOW txt_TEMP
	CALL	print_menu
ROW_CALVSI
	CALL	check_edit
	MOVF	CAL_VSI,W
	MOVWF	MATH00
	MOVLW	1
	BTFSC	CAL_VSI,7		; 補正値の7ビット目が1ならば、
	 CLRW				; 1.0以下として扱う。
	MOVWF	MATH01
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW STRING
	MOVWF	FSR
	CLRF	PCLATH			; ■ PCLATH
	CALL	format_xxx
	CLRF	INDF
	MOVLW	48
	MOVWF	LCD_X
	CALL	puts8
	BSF	PCLATH,3		; ■ PCLATH
	MOVLW	LOW txt_VSI
	CALL	print_menu
	RETURN
;------------------------------------------------------------------------------
; 設定フラグ変更とEEPROM書き込み
;
; 引数
;	FSR		変更するメモリアドレス
;	W		変更するビット
;
; 戻り値
;	なし
;
; 使用変数
;	TMP00,01(write_ee_data)
;------------------------------------------------------------------------------
change_flag
	BCF	STATUS,IRP		; ● IRP=0
	XORWF	INDF,F			; ビット反転
save_value
	MOVLW	0x20			; EEPROMのアドレスに変換
	SUBWF	FSR,W
	MOVWF	_EEADDR
	MOVLW	1			; 書き込みバイト数
	CLRF	PCLATH			; ■ PCLATH
	CALL	write_ee_data
	BSF	PCLATH,3		; ■ PCLATH
	RETURN

;------------------------------------------------------------------------------
; PWMデューティー変更
;
; 引数
;	BACKLIGHT
;
; 戻り値
;	なし
;
; 使用変数
;	なし
;------------------------------------------------------------------------------
lcd_backlight
	MOVF	BACKLIGHT,W
	MOVWF	CCPR1L
	RETURN
	
;------------------------------------------------------------------------------
; LCD濃度変更
;
; 引数
;	CONTRAST
;
; 戻り値
;	なし
;
; 使用変数
;	TMP21, 20(lcd_command)
;------------------------------------------------------------------------------
lcd_contrast
	MOVLW	B'00100001'		; Function Set(Power_On, H_addr, Ext_Inst)
	CLRF	PCLATH			; ■ PCLATH
	CALL	lcd_command
	MOVF	CONTRAST,W		; コントラストの値は3倍する
	MOVWF	TMP21
	BCF	STATUS,C
	RLF	TMP21,W
	ADDWF	TMP21,W
	ADDLW	0x80 + 53
	CALL	lcd_command
	BSF	PCLATH,3		; ■ PCLATH
	RETURN

;------------------------------------------------------------------------------
; 文字列テーブル
;  テーブルは0x0Cxxのエリア内に収めること
;------------------------------------------------------------------------------
txt_title	DA	"ALT-1"
txt_version	DA	"Ver.0.62 "
txt_reset	DA	"FACTORY RESET"
txt_going_to	DA	"Going to",NULL
txt_ft		DA	"ft",NULL
txt_FPM		DA	"ft"		; 位置を動かすな
txt__m		DA	"/m",NULL
txt_m		DA	"m"
txt__s		DA	"/s",NULL

txt_SLEEP	DA	"Sleep"
txt_RETURN	DA	"Return",NULL
txt_MODE	DA	"Mode:"
txt_ALTIMETER	DA	"Altimeter"
txt_BAROMETER	DA	"Barometer"
txt_TEMPERATURE	DA	"Temperature"
txt_DISPLAY	DA	"Display"
txt_CALIBRATION	DA	"Calibration"

txt_SUBDISPLAY	DA	"SubDisplay:"
txt_GRAPHTYPE	DA	"GraphType:",NULL
txt_ALTUNIT	DA	"ALT Unit:"
txt_VSIUNIT	DA	"VSI Unit:"
txt_QNHUNIT	DA	"QNH Unit:"
txt_VSIAVG	DA	"VSI Avg.:"
txt_VSIRANGE	DA	"VSI Range:",NULL
txt_TIMESPAN	DA	"TimeSpan:"
txt_YAXIS	DA	"Y-Axis:"
txt_OVERSAMPLE	DA	"OverSample:"
txt_PRESSUNIT	DA	"PressUnit:",NULL
txt_TEMPUNIT	DA	"Temp Unit:",NULL
txt_BACKLIGHT	DA	"Backlight:",NULL
txt_CONTRAST	DA	"Contrast:"
txt_ALTITUDE	DA	"Alt  :",NULL
txt_PRESSURE	DA	"Press:",NULL
txt_TEMP	DA	"Temp :",NULL
txt_VSI		DA	"VSI  :",NULL

txt_OFF		DA	"OFF"
txt_ON		DA	"ON",NULL
txt_DOT		DA	"Dot"
txt_BAR		DA	"Bar"
txt_MPS		DA	"m/s"
txt_HPA		DA	"hPa"
txt_INHG	DA	"inHg",NULL
txt_MIN		DA	"min"
txt_HOUR	DA	"hr",NULL
txt_FLOAT	DA	"Float"
txt_FIX		DA	"Fix"
txt_C		DA	"'C",NULL
txt_F		DA	"'F",NULL
txt_BACK	DA	"Back",NULL
txt_NRML	DA	"NRML",NULL
txt_WIDE	DA	"WIDE",NULL

;------------------------------------------------------------------------------
; VSIゲージ
;
; 引数
;	VS_L,VS_M
;	VSI_RANGE		0=/2 1=/5
;
; 戻り値
;	なし
;
; 使用変数
;	TMP00
;------------------------------------------------------------------------------
vsi_gauge
	MOVLW	6			; VSIのフォントを削除
	MOVWF	TMP00
	BSF	STATUS,IRP		; ● IRP=1
	MOVLW	LOW FONTCACHE
	MOVWF	FSR
VSI_CLEAR
	CLRF	INDF
	INCF	FSR,F
	DECFSZ	TMP00,F
	 GOTO	VSI_CLEAR

	MOVF	VS,W			; レンジ調整
	MOVWF	MATH00
	MOVF	VSIWIDE,W
	MOVWF	MATH10
	MOVLW	12			; ゼロ点ガイド
	MOVWF	LCD_X
	MOVLW	2
	MOVWF	LCD_Y
	CLRF	PCLATH			; ■ PCLATH
	CALL	lcd_locate
	MOVLW	0x80
	CALL	lcd_data
	CALL	lcd_data
	CALL	lcd_data
	INCF	LCD_Y,F
	CALL	lcd_locate
	MOVLW	0x01
	CALL	lcd_data
	CALL	lcd_data
	CALL	lcd_data

	BTFSC	ALT_CFG,VSI_RANGE
	 CALL	div8
	BSF	PCLATH,3		; ■ PCLATH

	MOVLW	24			; 24以上は表示できないので23にする
	SUBWF	MATH00,W
	MOVLW	23
	BTFSC	STATUS,C
	 MOVWF	MATH00
	INCF	MATH00,F
VSI_SHIFT
	MOVF	FLAG2,W			; RP=3ではFLAG2が見えなくなるのでコピーしておく
	MOVWF	TMP00
	COMF	STATUS,F		; ◆ RP=3 ● IRP=0
	BSF	STATUS,C		; 種
	BTFSC	TMP00,VSI_SIGN
	 GOTO	VSI_NEG
	RRF	2+FONTCACHE,F
	RRF	1+FONTCACHE,F
	RRF	LOW FONTCACHE,F
	GOTO	VSI_GAUGE2
VSI_NEG
	RLF	3+FONTCACHE,F
	RLF	4+FONTCACHE,F
	RLF	5+FONTCACHE,F
VSI_GAUGE2
	COMF	STATUS,F		; ◆ RP=0 ● IRP=1
	DECFSZ	MATH00,F
	 GOTO	VSI_SHIFT

	MOVLW	5+LOW FONTCACHE		; 表示ループ
	MOVWF	FSR
	MOVLW	5
	MOVWF	LCD_Y
VSI_YLOOP
	MOVLW	12			; ゲージの幅
	MOVWF	TMP00
	MOVLW	0
	MOVWF	LCD_X
	CLRF	PCLATH			; ■ PCLATH
	CALL	lcd_locate
	MOVF	INDF,W
VSI_XLOOP
	CLRF	PCLATH			; ■ PCLATH
	CALL	lcd_data
	BSF	PCLATH,3		; ■ PCLATH
	DECFSZ	TMP00,F
	 GOTO	VSI_XLOOP
	DECF	FSR,F
	MOVLW	1
	SUBWF	LCD_Y,F
	BTFSC	STATUS,C
	 GOTO	VSI_YLOOP
	RETURN
;------------------------------------------------------------------------------
; フォントテーブル 8x5
;------------------------------------------------------------------------------
	ORG	0x0D39
FONT5
	DA	0x0408, 0x0408	; 2D -
	DA	0x3000, 0x0060	; .
	DA	0x0000, 0x0000	; / > スペース
	DA	0x20BE, 0x1F41	; 0
	DA	0x2100, 0x207F	; 1
	DA	0x28E2, 0x2349	; 2
	DA	0x24A2, 0x1B49	; 3
	DA	0x091C, 0x087F	; 4
	DA	0x22A7, 0x1CC5	; 5
	DA	0x24BE, 0x1949	; 6
	DA	0x3883, 0x0389	; 7
	DA	0x24B6, 0x1B49	; 8
	DA	0x24A6, 0x1F49	; 9
;------------------------------------------------------------------------------
; フォントテーブル 8x6
;------------------------------------------------------------------------------
FONT8
	DA	0x0000, 0x0000, 0x0000	; 26 & > スペース 
	DA	0x0287, 0x0007, 0x0000	; ' > °
	DA	0x3F80, 0x20C1, 0x0000	; ( > [
	DA	0x2080, 0x3FC1, 0x0000	; ) > ]
	DA	0x0414, 0x043E, 0x0014	; *
	DA	0x0408, 0x043E, 0x0008	; +
	DA	0x0082, 0x04D1, 0x0006	; , > ?
	DA	0x0408, 0x0408, 0x0008	; -
	DA	0x3000, 0x0060, 0x0000	; .
	DA	0x0820, 0x0208, 0x0002	; /
	DA	0x28BE, 0x22C9, 0x003E	; 0
	DA	0x2100, 0x207F, 0x0000	; 1
	DA	0x30C2, 0x24D1, 0x0046	; 2
	DA	0x20A1, 0x25C5, 0x0031	; 3
	DA	0x0A18, 0x3F92, 0x0010	; 4
	DA	0x22A7, 0x22C5, 0x0039	; 5
	DA	0x253C, 0x24C9, 0x0030	; 6
	DA	0x3881, 0x0289, 0x0003	; 7
	DA	0x24B6, 0x24C9, 0x0036	; 8
	DA	0x2486, 0x14C9, 0x001E	; 9
	DA	0x1B00, 0x0036, 0x0000	; :
	DA	0x08FE, 0x0891, 0x007E	; A
	DA	0x24FF, 0x24C9, 0x0036	; B
	DA	0x20BE, 0x20C1, 0x0022	; C
	DA	0x20FF, 0x1141, 0x001C	; D
	DA	0x24FF, 0x24C9, 0x0041	; E
	DA	0x04FF, 0x0489, 0x0001	; F
	DA	0x20BE, 0x24C9, 0x007A	; G
	DA	0x047F, 0x0408, 0x007F	; H
	DA	0x2080, 0x20FF, 0x0000	; I
	DA	0x2020, 0x1FC1, 0x0001	; J
	DA	0x047F, 0x1114, 0x0041	; K
	DA	0x207F, 0x2040, 0x0040	; L
	DA	0x017F, 0x010C, 0x007F	; M
	DA	0x027F, 0x0808, 0x007F	; N
	DA	0x20BE, 0x20C1, 0x003E	; O
	DA	0x04FF, 0x0489, 0x0006	; P
	DA	0x20BE, 0x10D1, 0x005E	; Q
	DA	0x04FF, 0x1499, 0x0046	; R
	DA	0x24C6, 0x24C9, 0x0031	; S
	DA	0x0081, 0x00FF, 0x0001	; T
	DA	0x203F, 0x2040, 0x003F	; U
	DA	0x101F, 0x1040, 0x001F	; V
	DA	0x203F, 0x2038, 0x003F	; W
	DA	0x0A63, 0x0A08, 0x0063	; X
	DA	0x0203, 0x0278, 0x0003	; Y
	DA	0x28E1, 0x22C9, 0x0043	; Z
	DA	0x2A20, 0x2A54, 0x0078	; a
	DA	0x247F, 0x2244, 0x0038	; b
	DA	0x2238, 0x2244, 0x0020	; c
	DA	0x2238, 0x2444, 0x007F	; d
	DA	0x2A38, 0x2A54, 0x0018	; e
	DA	0x3F08, 0x0089, 0x0002	; f
	DA	0x290C, 0x2952, 0x003E	; g
	DA	0x047F, 0x0204, 0x0078	; h
	DA	0x2200, 0x207D, 0x0000	; i
	DA	0x2020, 0x1EC4, 0x0000	; j
	DA	0x087F, 0x2228, 0x0000	; k
	DA	0x2080, 0x207F, 0x0000	; l
	DA	0x027C, 0x0218, 0x0078	; m
	DA	0x047C, 0x0204, 0x0078	; n
	DA	0x2238, 0x2244, 0x0038	; o
	DA	0x0A7C, 0x0A14, 0x0008	; p
	DA	0x0A08, 0x0C14, 0x007C	; q
	DA	0x047C, 0x0204, 0x0008	; r
	DA	0x2A48, 0x2A54, 0x0020	; s
	DA	0x1F84, 0x2044, 0x0020	; t
	DA	0x203C, 0x1040, 0x007C	; u
	DA	0x101C, 0x1040, 0x001C	; v
	DA	0x203C, 0x2030, 0x003C	; w
	DA	0x1444, 0x1410, 0x0044	; x
	DA	0x280C, 0x2850, 0x003C	; y
;	DA	0x3244, 0x2654, 0x0044	; z

;------------------------------------------------------------------------------
; フォントテーブル 16x8
;------------------------------------------------------------------------------
#if FONT == 0
FONT16	; ぱうフォント
	DA	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000	; 26 & > スペース
	DA	0x001E, 0x003F, 0x0033, 0x0033, 0x003F, 0x001E, 0x0000	; ' = °
	DA	0x0000, 0x1FFE, 0x3FFF, 0x3003, 0x3003, 0x3003, 0x0000	; ( > [
	DA	0x3003, 0x3003, 0x3003, 0x3FFF, 0x1FFE, 0x0000, 0x0000	; ) > ]
	DA	0x18C6, 0x1EDE, 0x07F8, 0x07F8, 0x1EDE, 0x18C6, 0x0000	; *
	DA	0x00C0, 0x00C0, 0x3FFF, 0x3FFF, 0x00C0, 0x00C0, 0x0000	; +
	DA	0x001C, 0x000E, 0x1C07, 0x3EC7, 0x3EFF, 0x1C7F, 0x003E	; , > ?
	DA	0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x0000	; -
	DA	0x1C00, 0x3E00, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000	; .
	DA	0x1800, 0x1E00, 0x0780, 0x01E0, 0x0078, 0x001E, 0x0006	; /
	DA	0x03F0, 0x1FFE, 0x3D8F, 0x30C3, 0x3C6F, 0x1FFE, 0x03F0	; 0
	DA	0x0000, 0x0006, 0x0006, 0x3FFF, 0x3FFF, 0x0000, 0x0000	; 1
	DA	0x303C, 0x387E, 0x3C67, 0x3E03, 0x3787, 0x31FE, 0x307C	; 2
	DA	0x0C0C, 0x1C0E, 0x38C7, 0x30C3, 0x39E7, 0x1FFE, 0x0F3C	; 3
	DA	0x0FC0, 0x0FF8, 0x0C3E, 0x0C07, 0x3FFF, 0x3FFF, 0x0C00	; 4
	DA	0x1C7F, 0x3C7F, 0x3063, 0x3063, 0x38E3, 0x1FC3, 0x0F83	; 5
	DA	0x0FE0, 0x1FF8, 0x38FC, 0x306E, 0x38E7, 0x1FC3, 0x0F80	; 6
	DA	0x0003, 0x3803, 0x3E03, 0x0F83, 0x03E3, 0x00FF, 0x003E	; 7
	DA	0x1F1C, 0x3FFE, 0x31E7, 0x30C3, 0x39E7, 0x1FFE, 0x0F1C	; 8
	DA	0x007C, 0x30FE, 0x39C7, 0x1D83, 0x0F87, 0x07FE, 0x01FC	; 9
	DA	0x0000, 0x0E1C, 0x1F3E, 0x1F3E, 0x0E1C, 0x0000, 0x0000	; :
	DA	0x3FE0, 0x3FFC, 0x033F, 0x0307, 0x033F, 0x3FFC, 0x3FE0	; A
	DA	0x3FFF, 0x3FFF, 0x30C3, 0x30C3, 0x39E7, 0x1FFE, 0x0F3C	; B
	DA	0x0FF8, 0x1FFE, 0x380F, 0x3003, 0x3807, 0x1E3E, 0x0E3C	; C
	DA	0x3FFF, 0x3FFF, 0x3003, 0x3807, 0x1C0E, 0x0FFC, 0x03F0	; D
	DA	0x1FFF, 0x3FFF, 0x30C3, 0x30C3, 0x30C3, 0x30C3, 0x3003	; E
	DA	0x3FFE, 0x3FFF, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x0003	; F
	DA	0x0FF8, 0x1FFE, 0x380F, 0x3183, 0x3987, 0x1F9E, 0x0F9C	; G
	DA	0x3FFF, 0x3FFF, 0x00C0, 0x00C0, 0x00C0, 0x3FFF, 0x3FFF	; H
	DA	0x0000, 0x0000, 0x3003, 0x3FFF, 0x3FFF, 0x3003, 0x0000	; I
	DA	0x0F80, 0x1F80, 0x3800, 0x3000, 0x3800, 0x1FFF, 0x0FFF	; J
	DA	0x3FFF, 0x3FFF, 0x0198, 0x079C, 0x0E0E, 0x3C07, 0x3003	; K
	DA	0x0FFF, 0x1FFF, 0x3800, 0x3000, 0x3000, 0x3000, 0x3000	; L
	DA	0x3FFF, 0x3FFF, 0x00F8, 0x01C0, 0x00F0, 0x3FFF, 0x3FFF	; M
	DA	0x3FFF, 0x3FFF, 0x001E, 0x0078, 0x03E0, 0x3FFF, 0x3FFF	; N
	DA	0x0FFC, 0x1FFE, 0x3807, 0x3003, 0x3807, 0x1FFE, 0x0FFC	; O
	DA	0x3FFF, 0x3FFF, 0x0183, 0x0183, 0x01C7, 0x00FE, 0x007C	; P
	DA	0x0FFC, 0x1FFE, 0x3987, 0x3183, 0x3F07, 0x1FFE, 0x1BFC	; Q
	DA	0x3FFF, 0x3FFF, 0x0183, 0x0783, 0x1FC7, 0x3CFE, 0x307C	; R
	DA	0x0E1E, 0x1E3F, 0x3873, 0x30E3, 0x39C7, 0x1F8E, 0x0F0C	; S
	DA	0x0003, 0x0003, 0x3FFF, 0x3FFF, 0x0003, 0x0003, 0x0003	; T
	DA	0x0FFF, 0x1FFF, 0x3800, 0x3000, 0x3800, 0x1FFF, 0x0FFF	; U
	DA	0x001F, 0x00FF, 0x07F0, 0x3F00, 0x3FC0, 0x07FF, 0x003F	; V
	DA	0x03FF, 0x3FFF, 0x3FC0, 0x03E0, 0x3FC0, 0x3FFF, 0x03FF	; W
	DA	0x3007, 0x3C1F, 0x1F7C, 0x07F0, 0x0FFC, 0x3E1F, 0x3807	; X
	DA	0x000F, 0x003F, 0x0070, 0x3FE0, 0x3FF0, 0x003F, 0x000F	; Y
	DA	0x3003, 0x3C03, 0x3F03, 0x37C3, 0x31F3, 0x307F, 0x301E	; Z
	DA	0x1C00, 0x3E60, 0x3770, 0x3330, 0x3370, 0x3FE0, 0x3FC0	; a
	DA	0x3FFF, 0x3FFF, 0x3030, 0x3030, 0x3870, 0x1FE0, 0x0FC0	; b
	DA	0x0FC0, 0x1FE0, 0x3870, 0x3030, 0x3870, 0x1CE0, 0x0CC0	; c
	DA	0x0FC0, 0x1FE0, 0x3870, 0x3030, 0x3030, 0x3FFF, 0x3FFF	; d
	DA	0x0FC0, 0x1FE0, 0x3B70, 0x3330, 0x3370, 0x3BE0, 0x1BC0	; e
	DA	0x0060, 0x0060, 0x0060, 0x3FFE, 0x3FFF, 0x0063, 0x0063	; f
	DA	0x01E0, 0x33F0, 0x3738, 0x3E18, 0x3E1E, 0x1FFE, 0x07F0	; g
	DA	0x3FFF, 0x3FFF, 0x00E0, 0x0070, 0x0070, 0x3FE0, 0x3FC0	; h
	DA	0x0000, 0x0000, 0x000E, 0x3FDF, 0x3FDF, 0x000E, 0x0000	; i
	DA	0x3000, 0x3000, 0x380E, 0x1FDF, 0x0FDF, 0x000E, 0x0000	; j
	DA	0x3FFF, 0x3FFF, 0x0380, 0x07C0, 0x1EE0, 0x3870, 0x3030	; k
	DA	0x0000, 0x0000, 0x1FFF, 0x3FFF, 0x3000, 0x3000, 0x0000	; l
	DA	0x3FF0, 0x0070, 0x3FF0, 0x3FE0, 0x0070, 0x3FF0, 0x3FE0	; m
	DA	0x3FF0, 0x3FF0, 0x0030, 0x0030, 0x0070, 0x3FF0, 0x3FC0	; n
	DA	0x0FC0, 0x1FE0, 0x3870, 0x3030, 0x3870, 0x1FE0, 0x0FC0	; o
	DA	0x3FF0, 0x3FF0, 0x0C30, 0x0C30, 0x0E70, 0x07E0, 0x03C0	; p
	DA	0x03C0, 0x07E0, 0x0E70, 0x0C30, 0x0C30, 0x3FF0, 0x3FF0	; q
	DA	0x0000, 0x3FF0, 0x3FF0, 0x0060, 0x0030, 0x03F0, 0x01E0	; r
	DA	0x18E0, 0x39F0, 0x33B0, 0x3330, 0x3730, 0x3E70, 0x1C60	; s
	DA	0x0030, 0x0030, 0x1FFE, 0x3FFE, 0x3030, 0x3C30, 0x1C00	; t
;	DA	0x1FF0, 0x3FF0, 0x3000, 0x3000, 0x3000, 0x3FF0, 0x1FF0	; u
;	DA	0x01F0, 0x0FF0, 0x3E00, 0x3E00, 0x07C0, 0x01F0, 0x0070	; v
;	DA	0x03F0, 0x3FF0, 0x3F00, 0x03C0, 0x3F00, 0x3FF0, 0x03F0	; w
;	DA	0x3830, 0x3E70, 0x0FE0, 0x07C0, 0x0EE0, 0x3C70, 0x3030	; x
;	DA	0x0070, 0x31F0, 0x3FC0, 0x1F80, 0x03C0, 0x01F0, 0x0070	; y
;	DA	0x3830, 0x3E30, 0x3730, 0x33B0, 0x31F0, 0x3070, 0x0000	; z
#endif

#if FONT == 1
FONT16	; PC-98 ボールドフォントは8バイト必要になるので実装出来ない
	DA	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000	; 26 & > スペース
	DA	0x000C, 0x0012, 0x0012, 0x000C, 0x0000, 0x0000, 0x0000	; ' = °
	DA	0x0000, 0x0000, 0x0000, 0x0FFE, 0x0802, 0x0802, 0x0000	; ( > [
	DA	0x0000, 0x0802, 0x0802, 0x0FFE, 0x0000, 0x0000, 0x0000	; ) > ]
	DA	0x0000, 0x00A0, 0x0040, 0x01F0, 0x0040, 0x00A0, 0x0000	; *
	DA	0x0040, 0x0040, 0x0040, 0x03F8, 0x0040, 0x0040, 0x0040	; +
	DA	0x0018, 0x0004, 0x0002, 0x0D82, 0x0042, 0x0044, 0x0038	; , > ?
	DA	0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040	; -
	DA	0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000	; .
	DA	0x0200, 0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008	; /
	DA	0x07FC, 0x0E02, 0x0982, 0x0842, 0x0832, 0x080E, 0x07FC	; 0
	DA	0x0000, 0x0008, 0x0804, 0x0FFE, 0x0800, 0x0000, 0x0000	; 1
	DA	0x0E18, 0x0904, 0x0882, 0x0882, 0x0842, 0x0844, 0x0838	; 2
	DA	0x0208, 0x0404, 0x0842, 0x0842, 0x0842, 0x04A4, 0x0318	; 3
	DA	0x0200, 0x0380, 0x0260, 0x0218, 0x0204, 0x0FFE, 0x0200	; 4
	DA	0x027E, 0x0442, 0x0822, 0x0822, 0x0822, 0x0442, 0x0380	; 5
	DA	0x03F8, 0x0444, 0x0822, 0x0822, 0x0822, 0x0444, 0x0388	; 6
	DA	0x0006, 0x0002, 0x0002, 0x0FC2, 0x0032, 0x000A, 0x0006	; 7
	DA	0x0318, 0x04A4, 0x0842, 0x0842, 0x0842, 0x04A4, 0x0318	; 8
	DA	0x0238, 0x0444, 0x0882, 0x0882, 0x0882, 0x0444, 0x03F8	; 9
	DA	0x0000, 0x0000, 0x0630, 0x0630, 0x0000, 0x0000, 0x0000	; :
	DA	0x0FF0, 0x0108, 0x0104, 0x0102, 0x0104, 0x0108, 0x0FF0	; A
	DA	0x0FFE, 0x0842, 0x0842, 0x0842, 0x0842, 0x04A4, 0x0318	; B
	DA	0x03F8, 0x0404, 0x0802, 0x0802, 0x0802, 0x0404, 0x0208	; C
	DA	0x0802, 0x0FFE, 0x0802, 0x0802, 0x0802, 0x0404, 0x03F8	; D
	DA	0x0FFE, 0x0842, 0x0842, 0x0842, 0x0842, 0x0842, 0x0802	; E
	DA	0x0FFE, 0x0042, 0x0042, 0x0042, 0x0042, 0x0042, 0x0002	; F
	DA	0x03F8, 0x0404, 0x0802, 0x0802, 0x0842, 0x0444, 0x0FC8	; G
	DA	0x0FFE, 0x0040, 0x0040, 0x0040, 0x0040, 0x0040, 0x0FFE	; H
	DA	0x0000, 0x0000, 0x0802, 0x0FFE, 0x0802, 0x0000, 0x0000	; I
	DA	0x0600, 0x0800, 0x0800, 0x0800, 0x0402, 0x03FE, 0x0002	; J
	DA	0x0FFE, 0x0040, 0x00A0, 0x0110, 0x0208, 0x0404, 0x0802	; K
	DA	0x0000, 0x0FFE, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800	; L
	DA	0x0FFE, 0x0004, 0x0008, 0x0030, 0x0008, 0x0004, 0x0FFE	; M
	DA	0x0FFE, 0x0004, 0x0018, 0x0060, 0x0180, 0x0200, 0x0FFE	; N
	DA	0x03F8, 0x0404, 0x0802, 0x0802, 0x0802, 0x0404, 0x03F8	; O
	DA	0x0FFE, 0x0082, 0x0082, 0x0082, 0x0082, 0x0044, 0x0038	; P
	DA	0x03F8, 0x0604, 0x0902, 0x0902, 0x0902, 0x0604, 0x0BF8	; Q
	DA	0x0FFE, 0x0042, 0x0042, 0x00C2, 0x0142, 0x0624, 0x0818	; R
	DA	0x0218, 0x0424, 0x0842, 0x0842, 0x0842, 0x0484, 0x0308	; S
	DA	0x0002, 0x0002, 0x0002, 0x0FFE, 0x0002, 0x0002, 0x0002	; T
	DA	0x07FE, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x07FE	; U
	DA	0x01FE, 0x0200, 0x0400, 0x0800, 0x0400, 0x0200, 0x01FE	; V
	DA	0x03FE, 0x0C00, 0x0300, 0x00C0, 0x0300, 0x0C00, 0x03FE	; W
	DA	0x0E0E, 0x0110, 0x00A0, 0x0040, 0x00A0, 0x0110, 0x0E0E	; X
	DA	0x000E, 0x0010, 0x0020, 0x0FC0, 0x0020, 0x0010, 0x000E	; Y
	DA	0x0E02, 0x0902, 0x0882, 0x0842, 0x0822, 0x0812, 0x080E	; Z
	DA	0x0720, 0x0890, 0x0890, 0x0890, 0x0490, 0x0FE0, 0x0000	; a
	DA	0x0000, 0x0FFE, 0x0420, 0x0810, 0x0810, 0x0420, 0x03C0	; b
	DA	0x03C0, 0x0420, 0x0810, 0x0810, 0x0810, 0x0420, 0x0240	; c
	DA	0x03C0, 0x0420, 0x0810, 0x0810, 0x0420, 0x0FFE, 0x0000	; d
	DA	0x03C0, 0x04A0, 0x0890, 0x0890, 0x0890, 0x04A0, 0x02C0	; e
	DA	0x0000, 0x0010, 0x0FFC, 0x0012, 0x0012, 0x0004, 0x0000	; f
	DA	0x04E0, 0x0910, 0x1208, 0x1208, 0x1208, 0x0910, 0x07F8	; g
	DA	0x0000, 0x0FFE, 0x0020, 0x0010, 0x0010, 0x0020, 0x0FC0	; h
	DA	0x0000, 0x0000, 0x0000, 0x0FE6, 0x0000, 0x0000, 0x0000	; i
	DA	0x0000, 0x0800, 0x1000, 0x1000, 0x0FF3, 0x0000, 0x0000	; j
	DA	0x0000, 0x0FFE, 0x0100, 0x0180, 0x0240, 0x0420, 0x0810	; k
	DA	0x0000, 0x0000, 0x0002, 0x0FFE, 0x0000, 0x0000, 0x0000	; l
	DA	0x0FF0, 0x0010, 0x0010, 0x0FE0, 0x0010, 0x0010, 0x0FE0	; m
	DA	0x0000, 0x0FF0, 0x0020, 0x0010, 0x0010, 0x0010, 0x0FE0	; n
	DA	0x03C0, 0x0420, 0x0810, 0x0810, 0x0810, 0x0420, 0x03C0	; o
	DA	0x0000, 0x1FF8, 0x0210, 0x0408, 0x0408, 0x0210, 0x01E0	; p
	DA	0x01E0, 0x0210, 0x0408, 0x0408, 0x0210, 0x1FF8, 0x0000	; q
	DA	0x0000, 0x0FF0, 0x0020, 0x0010, 0x0010, 0x0020, 0x0000	; r
	DA	0x0460, 0x0890, 0x0890, 0x0890, 0x0890, 0x0890, 0x0720	; s
	DA	0x0010, 0x0010, 0x07FE, 0x0810, 0x0810, 0x0400, 0x0000	; t
;	DA	0x07F0, 0x0800, 0x0800, 0x0800, 0x0400, 0x0FF0, 0x0000	; u
;	DA	0x0030, 0x00C0, 0x0300, 0x0C00, 0x0300, 0x00C0, 0x0030	; v
;	DA	0x03F0, 0x0C00, 0x0200, 0x0180, 0x0200, 0x0C00, 0x03F0	; w
;	DA	0x0810, 0x0420, 0x0240, 0x0180, 0x0240, 0x0420, 0x0810	; x
;	DA	0x0000, 0x10F8, 0x1100, 0x0A00, 0x0400, 0x0200, 0x01F8	; y
;	DA	0x0C10, 0x0A10, 0x0910, 0x0890, 0x0850, 0x0830, 0x0810	; z
#endif
;------------------------------------------------------------------------------
; データEEPROM
;------------------------------------------------------------------------------
	ORG	0x2100
	DE	DEF_MODE_CFG
	DE	DEF_ALT_CFG
	DE	DEF_BARO_CFG
	DE	DEF_TEMP_CFG
	DE	DEF_ALT_RANGE
	DE	DEF_BARO_RANGE
	DE	DEF_TEMP_RANGE
	DE	DEF_QNH_MSB
	DE	DEF_QNH_LSB
	DE	DEF_ALT_INTERVAL
	DE	DEF_ALT_OSR
	DE	DEF_BARO_INTERVAL
	DE	DEF_BARO_OSR
	DE	DEF_BACKLIGHT
	DE	DEF_CONTRAST
	DE	DEF_CAL_ALT
	DE	DEF_CAL_BARO
	DE	DEF_CAL_TEMP
	DE	DEF_CAL_VSI
	DE	DEF_VSIWIDE

	END
