6-10 フラッシュメモリの読み書き


フラッシュメモリへの書き込み、読み込み、ベリファイを行い、各フェーズが終了するごとに“SEGA”の文字を順次表示します。

60〜78行目は、フラッシュメモリに書き込むデータをRAMに準備します。データは0〜128の値で、間接アドレスレジスタを用いてRAMバンク1のアドレス10H〜8FHにセットします。データの準備フェーズを終えると、LCDに“S”の文字を表示します。

91〜102行目では、システムBIOSを呼び出すためにそのパラメータをセットし、ローバッテリ自動検出を禁止します。

104〜115行目では、システムBIOSを呼び出す前にシステムクロックをRC発振の6分周に切り換えています。システムBIOS呼び出し後は、元のクロック(水晶発振)に切り換えています。

クロック切り換え後は、ローバッテリ自動検出を有効にして、LCDに“E”を表示します。

注意

フラッシュメモリにアクセス中は、ベースタイマーを含めすべての割り込みを禁止してください。ベースタイマーは内蔵の時計機能が利用していますので、できる限り割り込み禁止時間を短くしてください。時計が遅れる原因になります。

また、フラッシュメモリへの書き込みの際は、システムクロックを1/6分周のRC発振にしてください。読み込みの際は、1/12分周でかまいません。

128〜146行目は、フラッシュメモリに書き込んだデータと、RAMのデータをシステムBIOSのベリファイ機能を使って比較します。完全に同一であれば、LCDに“G”を表示します。データが一致せずシステムBIOSがエラーを返した場合は“G”の文字を表示せず次のフェーズを実行します。

159〜173行目では、フラッシュメモリに書き込んだデータをRAMに読み出しています。読み出したデータは、172行目以降にある自前の比較ルーチンでデータを検証しています。データが完全に一致した場合は“A”の文字を表示しプログラムを終了します。もし、一致しなかった場合は“A”の文字を表示せずに終了します。

“G”や“A”の文字が表示されなかった場合は、それ以前に行ったフラッシュメモリへのアクセスでデータが化けていることになります。

357行目以降のデータは、データの書き込み先(フラッシュメモリ)です。

注意

フラッシュメモリに書き込みを行う場合は、必ずアプリケーション自身内に書き込む領域を用意します。アプリケーション外のフラッシュメモリへの書き込みは禁止されています。

フラッシュメモリのアクセスは、常に128バイト単位で行われますので、364行目のORGで128バイトのアライメントを行っています。

注意

フラッシュメモリの領域確保には、アセンブラ疑似命令のDSコマンドは利用できません。DSコマンドは、RAM領域に対してのみ有効です。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** フラッシュメモリ使用サンプル1 **
005	;
006	; フラッシュメモリにデータを書き込み、ベリファイし、読み出し、検証する。
007	; 全てが良好に動作するとLCD上に「SEGA」の文字が揃って表示される。
008	;----------------------------------------------------------------------------
009	; 1.01 990208 SEGA Enterprises,LTD.
010	;----------------------------------------------------------------------------
011	
012	chip	LC868700			; チップの種類をアセンブラに指定
013	world	external			; 外部メモリ用プログラム
014	
015	public	main				; ghead.asm から参照されるシンボル
016	
017	extern	_game_end			; ghead.asm への参照シンボル
018	extern	fm_wrt_ex, fm_vrf_ex, fm_prd_ex	; ghead.asm への参照シンボル
019	
020	
021	; **** システム定数の定義 ***************************************************
022	
023								; OCR(発振制御レジスタ)設定値
024	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定(1/12)
025	osc_rcfw	equ 0cdh		;	システムクロックに内蔵RC発振を指定(1/6)
026	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
027	
028	LowBattChk	equ 06eh		; ローバッテリ検出フラグ(RAMバンク0)
029	
030	fmflag		equ 07ch		; フラッシュメモリ書き込み終了検出方式
031	fmbank		equ 07dh		; フラッシュメモリバンク切替え
032	fmadd_h		equ 07eh		; フラッシュメモリ上位アドレス
033	fmadd_l		equ 07fh		; フラッシュメモリ下位アドレス
034	
035	fmbuff		equ 080h		; フラッシュメモリ読み書き用バッファ先頭
036	
037	; *** データセグメント ******************************************************
038	
039			dseg				; データセグメント開始
040	
041	r0:		ds		1			; 間接アドレッシングレジスタ r0
042	r1:		ds		1			; 間接アドレッシングレジスタ r1
043	r2:		ds		1			; 間接アドレッシングレジスタ r2
044	r3:		ds		1			; 間接アドレッシングレジスタ r3
045			ds		12			; その他のシステム予約レジスタ
046	
047	; *** コードセグメント ******************************************************
048	
049			cseg				; コードセグメント開始
050	
051	; *-------------------------------------------------------------------------*
052	; * ユーザープログラム														*
053	; *-------------------------------------------------------------------------*
054	main:
055			call	cls			; LCD表示イメージを消去する
056	
057	
058								; **** テスト書き込み用のデータを準備する ****
059								; fmbuff に 10h〜8fh の 128byte のデータを用意
060	
061			push	PSW			; PSW値を退避
062			set1	PSW,1		; データRAMバンク1を選択
063	
064			mov		#fmbuff,r0	; 読み書きバッファのアドレスを r0 に
065			mov		#128,c		; ループカウンタ(128回)
066			mov		#010h,b		; 書き込むデータの初期値
067	loop4:
068			ld		b			; データをバッファに置く
069			st		@r0			;
070		
071			inc		b			; 書き込みテスト用データを変える
072		
073			inc		r0			; バッファのアドレスをインクリメント
074		
075			dec		c			; ループカウンタのデクリメント
076			ld		c
077			bnz		loop4		; 128回の繰り返し
078	
079			pop		PSW			; PSW値を復帰
080			
081	
082								; **** 「S」を表示 ****
083								
084			mov		#1,c		; 水平座標
085			mov		#1,b		; 垂直座標
086			mov		#0ah,acc	; キャラクタコード 'S'
087			call	putch		; 一文字表示
088	
089	
090								; **** フラッシュメモリへの書き込み ****
091								
092			push	PSW			; PSW値を退避
093			set1	PSW,1		; データRAMバンク1を選択
094	
095			mov		#0,fmbank	; フラッシュメモリのバンク指定 = 0		
096			mov		#high(fmarea),fmadd_h	; 書き込み先アドレス(上位)
097			mov		#low(fmarea),fmadd_l	; 書き込み先アドレス(下位)		
098			
099			clr1	PSW,1		; データRAMバンク0を選択
100			mov		#0ffh,acc	; ローバッテリ検出をしない(0ffh)
101			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
102	
103			pop		PSW			; PSW値を復帰
104	
105			push	OCR			; OCR値を退避
106			mov		#osc_rcfw,OCR ; システムクロックを指定(RC)
107			call	fm_wrt_ex	; BIOS「フラッシュメモリへの書き込み」
108			pop		OCR			; OCR値を復帰
109	
110			push	PSW			; PSW値を退避
111			clr1	PSW,1		; データRAMバンク0を選択
112			mov		#0,acc		; ローバッテリ検出をする(0)
113			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
114			pop		PSW			; PSW値を復帰
115	
116	
117								; **** 「E」を表示 ****
118	
119			mov		#2,c		; 水平座標
120			mov		#1,b		; 垂直座標
121			mov		#0bh,acc	; キャラクタコード 'E'
122			call	putch		; 一文字表示
123	
124	
125								; **** フラッシュメモリとのベリファイ ****
126	
127			push	PSW			; PSW値を退避
128			set1	PSW,1		; データRAMバンク1を選択
129	
130			mov		#0,fmbank	; フラッシュメモリのバンク指定 = 0		
131			mov		#high(fmarea),fmadd_h	; アドレス(上位)
132			mov		#low(fmarea),fmadd_l	; アドレス(下位)
133			
134			
135			push	OCR			; OCR値を退避
136			mov		#osc_rc,OCR ; システムクロックを指定(RC)
137			call	fm_vrf_ex	; BIOS「フラッシュメモリとのベリファイ」
138			pop		OCR			; OCR値を復帰
139	
140			pop		PSW			; PSW値を復帰
141	
142			bnz		vrt_bad		; 書き込み失敗分岐
143								; 成功時のみ「G」を表示する
144	
145								; **** 「G」を表示 ****
146	
147			mov		#3,c		; 水平座標
148			mov		#1,b		; 垂直座標
149			mov		#0ch,acc	; キャラクタコード 'G'
150			call	putch		; 一文字表示
151	vrt_bad:
152	
153	
154								; **** フラッシュメモリのページデータ読み出し ****
155	
156			push	PSW			; PSW値を退避
157			set1	PSW,1		; データRAMバンク1を選択
158	
159			mov		#0,fmbank	; フラッシュメモリのバンク指定 = 0		
160			mov		#high(fmarea),fmadd_h	; アドレス(上位)
161			mov		#low(fmarea),fmadd_l	; アドレス(下位)
162			
163			push	OCR			; OCR値を退避
164			mov		#osc_rc,OCR ; システムクロックを指定(RC)
165			call	fm_prd_ex	; BIOS「フラッシュメモリのページデータ読み出し」
166			pop		OCR			; OCR値を復帰
167	
168			pop		PSW			; PSW値を復帰
169	
170	
171								; **** 読み込んだデータを検証する ****
172	
173			push	PSW			; PSW値を退避
174			set1	PSW,1		; データRAMバンク1を選択
175	
176			mov		#fmbuff,r0	; 読み書きバッファのアドレスを r0 に
177			mov		#128,c		; ループカウンタ(128回)
178			mov		#010h,b		; 比較用データの初期値
179	loop5:
180			ld		b			; データをバッファに置く
181			sub		@r0			; データを比較
182			bnz		read_bad	; 比較エラー.「A」を表示せず終了
183		
184			inc		b			; 書き込みテスト用データを変える
185		
186			inc		r0			; バッファのアドレスをインクリメント
187		
188			dec		c			; ループカウンタのデクリメント
189			ld		c
190			bnz		loop5		; 128回の繰り返し
191	
192			pop		PSW			; PSW値を復帰
193	
194	
195								; **** 「A」を表示 ****
196	
197			mov		#4,c		; 水平座標
198			mov		#1,b		; 垂直座標
199			mov		#0dh,acc	; キャラクタコード 'A'
200			call	putch		; 一文字表示
201	
202	
203	read_bad:	
204	loop6:						; ** [M](モード)ボタンチェック **
205			ld		P3
206			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
207			
208			br		loop6		; [M]ボタンが押されるまで待つ
209	
210	finish:						; ** アプリケーション終了処理 **
211			jmp		_game_end	; アプリケーション終了
212	
213	
214	; *-------------------------------------------------------------------------*
215	; * LCD表示イメージを消去する												*
216	; *-------------------------------------------------------------------------*
217	cls:
218			push	OCR			; OCR値を退避
219			mov		#osc_rc,OCR ; システムクロックを指定
220	
221			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
222			call	cls_s		; そのバンク内のデータをクリア
223	
224			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
225			call	cls_s		; そのバンク内のデータをクリア
226			pop		OCR			; OCR値を復帰
227			
228			ret					; cls終わり
229			
230	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
231			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
232			mov		#80h,b 		; ループカウンタbにループ数をセット
233	loop3:
234			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
235			inc		r2			;
236			dbnz	b,loop3		; bが0になるまで繰り返す
237			
238			ret					; cls_s終わり
239			
240	
241	; *-------------------------------------------------------------------------*
242	; * 指定位置に1キャラクタ表示する											*
243	; * 入力 acc : キャラクタコード												*
244	; *        c : 文字水平位置												  	*
245	; *        b : 文字垂直位置												  	*
246	; *-------------------------------------------------------------------------*
247	putch:
248			push	XBNK
249			push	acc
250			call	locate		; 座標から表示RAMのアドレスを計算
251			pop		acc
252			call	put_chara	; 1キャラクタ表示する
253			pop		XBNK
254			
255			ret					; putch終わり
256			
257	
258	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
259			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
260			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
261	
262								; *** 表示用RAMバンクアドレスの判断 ***
263			ld		b			; b>=2 のとき next1 へ
264			sub		#2			;
265			bn		PSW,7,next1	;
266			
267			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
268			br		next2
269	next1:
270			st		b
271			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
272	next2:
273	
274								; *** 表示指定位置のRAMアドレス計算 ***
275			ld		b			; b * 40h + c + 80h
276			rol					;
277			rol					;
278			rol					;
279			rol					;
280			rol					;
281			rol					;
282			add		c			;
283			add		#80h		;
284			st		r2			; RAMアドレスをr2に格納
285					
286			ret					; locate終わり
287	
288	
289	put_chara:
290			push	PSW			; PSW値を退避
291			set1	PSW,1		; データRAMバンク1を選択
292	
293								; *** キャラクタデータアドレスの計算 ***
294			rol					; (TRH,TRL) = acc*8 + fontdata
295			rol					;
296			rol					;	
297			add		#low(fontdata)	;
298			st		TRL				;
299			mov		#0,acc			;
300			addc	#high(fontdata)	;
301			st		TRH			;
302	
303			push	OCR			; OCR値を退避
304			mov		#osc_rc,OCR ; システムクロックを指定
305	
306			mov		#0,b		; キャラクタデータ読み出し用オフセット値
307			mov		#4,c		; ループカウンタ
308	loop1:
309			ld		b			; 1ライン目の表示データを読み出す
310			ldc					;
311			inc		b			; 読み出しデータのオフセットを +1
312			st		@r2			; 表示データを表示用RAMに転送
313			ld		r2			; 表示用RAMアドレス +6
314			add		#6			;
315			st		r2			;
316	
317			ld		b			; 2ライン目の表示データを読み出す
318			ldc					;
319			inc		b			; 読み出しデータのオフセットを +1
320			st		@r2			; 表示データを表示用RAMに転送
321			ld		r2			; 表示用RAMアドレス +10
322			add		#10			;
323			st		r2			;
324			
325			dec		c			; ループカウンタのデクリメント
326			ld		c			; 
327			bnz		loop1		; 8ライン分(4回)繰り返し
328			
329			pop		OCR			; OCR値を復帰
330			pop		PSW			; PSW値を復帰
331	
332			ret					; put_chara終わり
333	
334	
335	; *-------------------------------------------------------------------------*
336	; * キャラクタのビットイメージデータ										*
337	; *-------------------------------------------------------------------------*
338	fontdata:
339			db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;'0' 00 
340			db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;'1' 01
341			db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;'2' 02
342			db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;'3' 03
343			db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;'4' 04
344			db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;'5' 05
345			db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;'6' 06
346			db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;'7' 07
347			db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;'8' 08
348			db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;'9' 09
349	
350			db 07ch, 0e6h, 076h, 038h, 0dch, 0ceh, 07ch, 000h	;'S' 0a
351			db 0feh, 0c0h, 0c0h, 0f8h, 0c0h, 0c0h, 0feh, 000h	;'E' 0b
352			db 07ch, 0e6h, 0c0h, 0dch, 0c6h, 0e6h, 07ch, 000h	;'G' 0c
353			db 01eh, 036h, 066h, 0c6h, 0c6h, 0feh, 0c6h, 000h	;'A' 0d
354			
355	
356	; *-------------------------------------------------------------------------*
357	; * データ保存用フラッシュメモリ領域										*
358	; *-------------------------------------------------------------------------*
359			org ((*-1) land 0ff80h) + 80h		; 128byte アライン
360	fmarea:
361			; 128byte フラッシュメモリ領域を確保する
362			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
363			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
364			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
365			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
366			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
367			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
368			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
369			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
370	
371	end		

[]   [INDEX]   []

(C)SEGA ENTERPRISES, LTD., 1998