; Tab width = 4

;---------------------------------------------------------------------------
; ** ローバッテリー検出とデータ退避サンプル1 **
;
; ローバッテリー状態を検出して、必要なデータをフラッシュメモリに退避する
;----------------------------------------------------------------------------
; 1.00 981208 SEGA Enterprises,LTD.
;----------------------------------------------------------------------------

chip	LC868700			; チップの種類をアセンブラに指定
world	external			; 外部メモリ用プログラム

public	main				; ghead.asm から参照されるシンボル

extern	_game_end			; ghead.asm への参照シンボル
extern	fm_wrt_ex, fm_vrf_ex, fm_prd_ex	; ghead.asm への参照シンボル


; **** システム定数の定義 ***************************************************

							; OCR(発振制御レジスタ)設定値
osc_rc		equ 081h		;   システムクロックに内蔵RC発振を指定
osc_xt		equ 082h		;   システムクロックに水晶発振を指定

LowBattChk	equ 06eh		; ローバッテリー検出フラグ(RAMバンク0)

fmflag		equ 07ch		; フラッシュメモリ書き込み終了検出方式
fmbank		equ 07dh		; フラッシュメモリバンク切替え
fmadd_h		equ 07eh		; フラッシュメモリ上位アドレス
fmadd_l		equ 07fh		; フラッシュメモリ下位アドレス

fmbuff		equ 080h		; フラッシュメモリ読み書き用バッファ先頭


; *** データセグメント ******************************************************

		dseg				; データセグメント開始

r0:		ds		1			; 間接アドレッシングレジスタ r0
r1:		ds		1			; 間接アドレッシングレジスタ r1
r2:		ds		1			; 間接アドレッシングレジスタ r2
r3:		ds		1			; 間接アドレッシングレジスタ r3
		ds		12			; その他のシステム予約レジスタ


; *** コードセグメント ******************************************************

		cseg				; コードセグメント開始

; *-------------------------------------------------------------------------*
; * ユーザープログラム														*
; *-------------------------------------------------------------------------*
main:
		call	cls			; LCD表示イメージを消去する

loop0:						; テストメインループ先頭

		; アプリケーションメイン処理

							; ** [M](モード)ボタンチェック **
		ld		P3
		bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了

							; ** バッテリ状態チェック **
		call	ChkBatt		; バッテリーの状態をチェック
		bz		loop0		; acc=0 ならバッテリ正常でループ

							; **  ローバッテリー 処理 **
		call	prepare		; テスト退避用のデータを用意する。
							; 実際のアプリケーションでは退避すべきデータを
							; 収集してフラッシュROM書きこみ用のバッファに配置
							; するようにする。

		call	WriteData	; フラッシュメモリへバッファに用意した(退避すべき)
							; データを書きこむ

finish:						; ** アプリケーション終了処理 **
		jmp		_game_end	; アプリケーション終了

		
; *-------------------------------------------------------------------------*

prepare:					; **** テスト退避用のデータを準備する ****
							; fmbuff に 10h〜8fh の 128byte のデータを用意

		push	PSW			; PSW値を退避
		set1	PSW,1		; データRAMバンク1を選択

		mov		#fmbuff,r0	; 読み書きバッファのアドレスを r0 に
		mov		#128,c		; ループカウンタ(128回)
		mov		#010h,b		; 書き込むデータの初期値
loop4:
		ld		b			; データをバッファに置く
		st		@r0			;
	
		inc		b			; 書き込みテスト用データを変える
	
		inc		r0			; バッファのアドレスをインクリメント
	
		dec		c			; ループカウンタのデクリメント
		ld		c
		bnz		loop4		; 128回の繰り返し

		pop		PSW			; PSW値を復帰

		ret					; prepare 終わり


; *-------------------------------------------------------------------------*
; * ローバッテリー状態を検出する											*
; * 出力: acc = 0    : 電池状態正常											*
; *       acc = 0ffh : ローバッテリー										*
; *-------------------------------------------------------------------------*
ChkBatt:
		ld		P7			; P71の状態をチェックする
		bn		acc,1,next3	; 電池ないとき分岐

							; ** 電池ある **
		mov		#0,acc		; acc = 0
		ret					; ChkBatt終わり。電池ありなら acc=0 として帰る

next3:						; ** 電池なし **
		mov		#0ffh,acc	; acc = 0ffh
		ret					; ChkBatt終わり。電池なしなら acc=0ffh として帰る


; *-------------------------------------------------------------------------*
; * バッファのデータをフラッシュメモリへ書きこむ							*
; *-------------------------------------------------------------------------*
WriteData:					; **** フラッシュメモリへの書き込み ****
							
		push	PSW			; PSW値を退避
		set1	PSW,1		; データRAMバンク1を選択

		mov		#0,fmbank	; フラッシュメモリのバンク指定 = 0		
		mov		#high(fmarea),fmadd_h	; 書き込み先アドレス(上位)
		mov		#low(fmarea),fmadd_l	; 書き込み先アドレス(下位)		
		mov		#0,fmflag	; トクルビット方式により終了を検出
		
		clr1	PSW,1		; データRAMバンク0を選択
		mov		#0ffh,acc	; ローバッテリー検出をしない(0ffh)
		st		LowBattChk	; ローバッテリー自動検出フラグ(RAMバンク0)

		pop		PSW			; PSW値を復帰

		push	OCR			; OCR値を退避
		mov		#osc_rc,OCR ; システムクロックを指定(RC)
		call	fm_wrt_ex	; BIOS「フラッシュメモリへの書き込み」
		pop		OCR			; OCR値を復帰

		push	PSW			; PSW値を退避
		clr1	PSW,1		; データRAMバンク0を選択
		mov		#0,acc		; ローバッテリー検出をする(0)
		st		LowBattChk	; ローバッテリー自動検出フラグ(RAMバンク0)
		pop		PSW			; PSW値を復帰

		ret					; WriteData終わり


; *-------------------------------------------------------------------------*
; * LCD表示イメージを消去する												*
; *-------------------------------------------------------------------------*
cls:
		push	OCR			; OCR値を退避
		mov		#osc_rc,OCR ; システムクロックを指定

		mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
		call	cls_s		; そのバンク内のデータをクリア

		mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
		call	cls_s		; そのバンク内のデータをクリア
		pop		OCR			; OCR値を復帰
		
		ret					; cls終わり
		
cls_s:						; *** 表示用RAM 1BANK分の消去 ***
		mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
		mov		#80h,b 		; ループカウンタbにループ数をセット
loop3:
		mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
		inc		r2			;
		dbnz	b,loop3		; bが0になるまで繰り返す
		
		ret					; cls_s終わり
		

; *-------------------------------------------------------------------------*
; * データ保存用フラッシュメモリ領域										*
; *-------------------------------------------------------------------------*
		org ((*-1) land 0ff80h) + 80h		; 128byte アライン
fmarea:
		; 128byte フラッシュメモリ領域を確保する
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

end		
