第6章 サンプルプログラムリスト

ここでは、ビジュアルメモリSDKに付属のサンプルプログラムを掲載します。

インフォメーションフォークのソースファイル“IFORK.ASM”の説明、“GHEAD.ASM”の詳細は割愛します。

注意

すべてのサンプルプログラムは、タブ(09H)を4(バイト)にしてご覧ください。


6-1 LCDパターン表示


このサンプルでは、LCD(XRAM)に単純なパターンを表示させます。

51,55,59,63,67行目でパターンを指定し、matrixルーチンでLCD全体にこのパターンを描画します。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** LCD表示処理サンプル1 **
005	;
006	; 表示用RAMにデータを転送してLCDに単純なパターンを表示する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	
016	extern	_game_end			; アプリケーション終了
017	
018	
019	; **** システム定数の定義 ***************************************************
020	
021								; OCR(発振制御レジスタ)設定値
022	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
023	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
024	
025	
026	; *** データセグメント ******************************************************
027	
028			dseg				; データセグメント開始
029	
030	r0:		ds		1			; 間接アドレッシングレジスタ r0
031	r1:		ds		1			; 間接アドレッシングレジスタ r1
032	r2:		ds		1			; 間接アドレッシングレジスタ r2
033	r3:		ds		1			; 間接アドレッシングレジスタ r3
034			ds		12			; その他のシステム予約レジスタ
035	
036	
037	; *** コードセグメント ******************************************************
038	
039			cseg				; コードセグメント開始
040	
041	; *-------------------------------------------------------------------------*
042	; * ユーザープログラム														*
043	; *-------------------------------------------------------------------------*
044	main:
045			mov		#0f0h,c		; 表示用データ
046			call	matrix		; LCDにパターンを表示
047			set1	PCON,0		; HALTモードに移行して割り込みを待つ。
048								; ベースタイマの割り込みがかかることにより
049								; HALTモードは解除され処理が先に進む。
050	
051			mov		#00fh,c		; 以下同様に何パターンか表示する
052			call	matrix
053			set1	PCON,0
054	
055			mov		#0cch,c
056			call	matrix
057			set1	PCON,0
058	
059			mov		#033h,c
060			call	matrix
061			set1	PCON,0
062	
063			mov		#055h,c
064			call	matrix
065			set1	PCON,0
066	
067			mov		#0aah,c
068			call	matrix
069			set1	PCON,0
070	
071								; ** [M](モード)ボタンチェック **
072			ld		P3
073			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
074	
075			jmp		main		; 繰り返す
076	
077	finish:						; ** アプリケーション終了処理 **
078			jmp		_game_end	; アプリケーション終了
079	
080	
081	; *-------------------------------------------------------------------------*
082	; *	LCD全体にパターンを表示する												*
083	; * 入力	c: 基本表示パターン												*
084	; *-------------------------------------------------------------------------*
085	matrix:						; **** LCD 一面を描く ****
086	
087			push	acc			; 各レジスタを退避する
088			push	b
089			push	c
090			push	XBNK
091	
092	xb0_a:	mov		#000h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
093			mov		#080h,b
094			 
095	la1:	ld		c			; c:表示データ
096			call	line2		; 2行表示
097			ld		b			; 2行先へアドレスを進める
098			add		#010h		;
099			st		b			;
100			bnz		la1			; バンクの終端まで繰り返し
101			
102	xb1_a:	mov		#001h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
103			mov		#080h,b
104	
105	la2:	ld		c			; c:表示データ
106			call	line2		; 2行表示
107			ld		b			; 2行先へアドレスを進める
108			add		#010h		;
109			st		b			;
110			bnz		la2			; バンクの終端まで繰り返し
111	
112			pop		XBNK		; 退避レジスタの復帰
113			pop		c
114			pop		b
115			pop		acc
116	
117			ret					; matrix終了
118	
119	
120	line2:						; **** LCD 2行分表示 ****
121	
122			push	acc			; 各レジスタを退避する
123			push	b			;
124			push	c			;
125			push	PSW			;
126			push	OCR			;
127			mov		#osc_rc,OCR	; システムクロックを指定
128			set1	PSW,1		; データRAMバンク1を選択
129			st		c			; 表示データを c に退避
130			ld		b			; 表示用RAMアドレスを、r2にセット
131			st		r2			;
132	
133	lp1:						; **** 1行目表示処理 ****
134			ld		c			; 表示データを表示用RAMに転送
135			st		@r2			;
136			inc		r2			; 次の表示位置にアドレスを移動
137			ld		r2
138			and		#00fh		; 表示位置が 1行目右端にくるまで..
139			xor		#006h		; 
140			bnz		lp1			; 繰り返し
141			
142			ld		c			; cレジスタのビットパターンを反転する
143			xor		#0ffh		;
144			st c				;
145	
146	lp2:						; **** 2行目表示処理 ****
147			ld		c			; 表示データを表示用RAMに転送
148			st		@r2			;
149			inc		r2			; 次の表示位置にアドレスを移動
150			ld		r2			;
151			and		#00fh		; 表示位置が 2行目右端にくるまで..
152			xor		#00ch		;
153			bnz		lp2			; 繰り返し
154	
155			pop		OCR			; 退避レジスタを復帰
156			pop		PSW			;
157			pop		c			;
158			pop		b			;
159			pop		acc			;
160			
161			ret					; line2終了
162	
163			end

6-2 LCDキャラクタパターン表示


このサンプルでは、LCD(XRAM)に“SEGA 1998”という文字を表示させます。

内蔵のフォントはアプリケーションから利用できないので、表示させるフォントパターンをあらかじめ用意する必要があります。

メインルーチンのB,Cレジスタで指定した座標に指定のフォントパターンを書き込むputchを呼び出します。フォント情報は、222行目以降に8×8ドットのデータを持たせています。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** LCD表示処理サンプル2 **
005	;
006	; ・表示用RAMを0でフィルして表示イメージを消去する
007	; ・キャラクタパターンを指定位置に表示する
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			; アプリケーション終了
018	
019	
020	; **** システム定数の定義 ***************************************************
021	
022								; OCR(発振制御レジスタ)設定値
023	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
024	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
025	
026	
027	; *** データセグメント ******************************************************
028	
029			dseg				; データセグメント開始
030	
031	r0:		ds		1			; 間接アドレッシングレジスタ r0
032	r1:		ds		1			; 間接アドレッシングレジスタ r1
033	r2:		ds		1			; 間接アドレッシングレジスタ r2
034	r3:		ds		1			; 間接アドレッシングレジスタ r3
035			ds		12			; その他のシステム予約レジスタ
036	
037	
038	; *** コードセグメント ******************************************************
039	
040			cseg				; コードセグメント開始
041	
042	; *-------------------------------------------------------------------------*
043	; * ユーザープログラム														*
044	; *-------------------------------------------------------------------------*
045	main:
046			call	cls			; LCD表示イメージを消去する
047	
048			mov		#1,c		; 水平座標
049			mov		#1,b		; 垂直座標
050			mov		#0ah,acc	; キャラクタコード 'S'
051			call	putch		; 一文字表示
052	
053			mov		#2,c
054			mov		#1,b
055			mov		#0bh,acc	; 'E'
056			call	putch
057			
058			mov		#3,c
059			mov		#1,b
060			mov		#0ch,acc	; 'G'
061			call	putch
062	
063			mov		#4,c
064			mov		#1,b
065			mov		#0dh,acc	; 'A'
066			call	putch
067	
068			mov		#1,c
069			mov		#2,b
070			mov		#1,acc		; '1'
071			call	putch
072	
073			mov		#2,c
074			mov		#2,b
075			mov		#9,acc		; '9'
076			call	putch
077			
078			mov		#3,c
079			mov		#2,b
080			mov		#9,acc		; '9'
081			call	putch
082	
083			mov		#4,c
084			mov		#2,b
085			mov		#8,acc		; '8'
086			call	putch
087	
088	loop0:						; ** [M](モード)ボタンチェック **
089			ld		P3
090			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
091	
092			jmp		loop0		; ループして待つ
093	
094	finish:						; ** アプリケーション終了処理 **
095			jmp		_game_end	; アプリケーション終了
096	
097	
098	; *-------------------------------------------------------------------------*
099	; * LCD表示イメージを消去する												*
100	; *-------------------------------------------------------------------------*
101	cls:
102			push	OCR			; OCR値を退避
103			mov		#osc_rc,OCR ; システムクロックを指定
104	
105			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
106			call	cls_s		; そのバンク内のデータをクリア
107	
108			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
109			call	cls_s		; そのバンク内のデータをクリア
110			pop		OCR			; OCR値を復帰
111			
112			ret					; cls終わり
113			
114	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
115			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
116			mov		#80h,b 		; ループカウンタbにループ数をセット
117	loop3:
118			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
119			inc		r2			;
120			dbnz	b,loop3		; bが0になるまで繰り返す
121			
122			ret					; cls_s終わり
123			
124	
125	; *-------------------------------------------------------------------------*
126	; * 指定位置に1キャラクタ表示する											*
127	; * 入力 acc : キャラクタコード												*
128	; *        c : 文字水平位置												  	*
129	; *        b : 文字垂直位置												  	*
130	; *-------------------------------------------------------------------------*
131	putch:
132			push	XBNK
133			push	acc
134			call	locate		; 座標から表示RAMのアドレスを計算
135			pop		acc
136			call	put_chara	; 1キャラクタ表示する
137			pop		XBNK
138			
139			ret					; putch終わり
140			
141	
142	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
143			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
144			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
145	
146								; *** 表示用RAMバンクアドレスの判断 ***
147			ld		b			; b>=2 のとき next1 へ
148			sub		#2			;
149			bn		PSW,7,next1	;
150			
151			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
152			br		next2
153	next1:
154			st		b
155			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
156	next2:
157	
158								; *** 表示指定位置のRAMアドレス計算 ***
159			ld		b			; b * 40h + c + 80h
160			rol					;
161			rol					;
162			rol					;
163			rol					;
164			rol					;
165			rol					;
166			add		c			;
167			add		#80h		;
168			st		r2			; RAMアドレスをr2に格納
169					
170			ret					; locate終わり
171	
172	
173	put_chara:
174			push	PSW			; PSW値を退避
175			set1	PSW,1		; データRAMバンク1を選択
176	
177								; *** キャラクタデータアドレスの計算 ***
178			rol					; (TRH,TRL) = acc*8 + fontdata
179			rol					;
180			rol					;	
181			add		#low(fontdata)	;
182			st		TRL				;
183			mov		#0,acc			;
184			addc	#high(fontdata)	;
185			st		TRH			;
186	
187			push	OCR			; OCR値を退避
188			mov		#osc_rc,OCR ; システムクロックを指定
189	
190			mov		#0,b		; キャラクタデータ読み出し用オフセット値
191			mov		#4,c		; ループカウンタ
192	loop1:
193			ld		b			; 1ライン目の表示データを読み出す
194			ldc					;
195			inc		b			; 読み出しデータのオフセットを +1
196			st		@r2			; 表示データを表示用RAMに転送
197			ld		r2			; 表示用RAMアドレス +6
198			add		#6			;
199			st		r2			;
200	
201			ld		b			; 2ライン目の表示データを読み出す
202			ldc					;
203			inc		b			; 読み出しデータのオフセットを +1
204			st		@r2			; 表示データを表示用RAMに転送
205			ld		r2			; 表示用RAMアドレス +10
206			add		#10			;
207			st		r2			;
208			
209			dec		c			; ループカウンタのデクリメント
210			ld		c			; 
211			bnz		loop1		; 8ライン分(4回)繰り返し
212			
213			pop		OCR			; OCR値を復帰
214			pop		PSW			; PSW値を復帰
215	
216			ret					; put_chara終わり
217	
218	
219	; *-------------------------------------------------------------------------*
220	; * キャラクタのビットイメージデータ										*
221	; *-------------------------------------------------------------------------*
222	fontdata:
223			db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;'0' 00 
224			db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;'1' 01
225			db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;'2' 02
226			db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;'3' 03
227			db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;'4' 04
228			db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;'5' 05
229			db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;'6' 06
230			db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;'7' 07
231			db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;'8' 08
232			db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;'9' 09
233	
234			db 07ch, 0e6h, 076h, 038h, 0dch, 0ceh, 07ch, 000h	;'S' 0a
235			db 0feh, 0c0h, 0c0h, 0f8h, 0c0h, 0c0h, 0feh, 000h	;'E' 0b
236			db 07ch, 0e6h, 0c0h, 0dch, 0c6h, 0e6h, 07ch, 000h	;'G' 0c
237			db 01eh, 036h, 066h, 0c6h, 0c6h, 0feh, 0c6h, 000h	;'A' 0d

6-3 ベースタイマー割り込みを使ったカウンタ


ベースタイマーからかかる0.5秒ごとの割り込みを検知し、その数をカウントします。

割り込みが発生すると“GHEAD.ASM”の35行目にジャンプし、さらにその先のラベルINT_1Bにジャンプします。108行目からベースタイマー割り込み処理が始まりますが、ここでは内蔵の時計処理を行っています。112行目までのROM内の時計処理をいったん行った後、“B_TIMER1.ASM”にあるラベルint_BaseTimerにジャンプさせます。

“B_TIMER1.ASM”では、外部プログラムから参照されるラベルint_BaseTimerをPUBLIC宣言(16行目)しています。242行目以降は、ユーザー側ベースタイマー割り込みハンドラです。割り込みハンドラ内では、カウンタをインクリメントしています。

再び“GHEAD.ASM”に戻り、IEレジスタの内容をint_1bが呼び出されたときの値に戻し、割り込みからの復帰(IRET)を行います。

メインルーチンでは、カウンタの値を常にLCDに表示しています。 ●GHEAD.ASM

001	chip	LC868700
002	world	external
003	; *-----------------------------------------------------*
004	; *	External header program Ver 1.00		*
005	; *					05/20-'98	*
006	; *-----------------------------------------------------*
007	
008	public	fm_wrt_ex_exit,fm_vrf_ex_exit
009	public	fm_prd_ex_exit,timer_ex_exit,_game_start,_game_end
010	other_side_symbol	fm_wrt_in,fm_vrf_in
011	other_side_symbol	fm_prd_in,timer_in,game_end
012	
013	extern	main		;ユーザープログラム側にあるシンボル
014	extern	int_BaseTimer	;ユーザープログラム側にあるシンボル
015	
016	; *-----------------------------------------------------*
017	; *	Vector table(?)					*
018	; *-----------------------------------------------------*
019	cseg
020	org	0000h
021	_game_start:
022	;reset:
023			jmpf	main		; main program jump
024	org	0003h
025	;int_03:
026			jmp	int_03
027	org	000bh
028	;int_0b:
029			jmp	int_0b
030	org	0013h
031	;int_13:
032			jmp	int_13
033	org	001bh
034	;int_1b:
035			jmp	int_1b
036	org	0023h
037	;int_23:
038			jmp	int_23
039	org	002bh
040	;int_2b:
041			jmp	int_2b
042	org	0033h
043	;int_33:
044			jmp	int_33
045	org	003bh
046	;int_3b:
047			jmp	int_3b
048	org	0043h
049	;int_43:
050			jmp	int_43
051	org	004bh
052	;int_4b:
053			jmp	int_4b
054	; *-----------------------------------------------------*
055	; *	interrupt programs				*
056	; *-----------------------------------------------------*
057	int_03:
058			reti
059	int_0b:
060			reti
061	int_13:
062			reti
063	int_23:
064			reti
065	int_2b:
066			reti
067	int_33:
068			reti
069	int_3b:
070			reti
071	; *-----------------------------------------------------*
072	int_43:
073			reti
074	int_4b:
075			clr1	p3int,1		;interrupt flag clear
076			reti
077	
078	org	0100h
079	; *-----------------------------------------------------*
080	; *	flash memory write external program		*
081	; *-----------------------------------------------------*
082	fm_wrt_ex:
083			change	fm_wrt_in
084		fm_wrt_ex_exit:
085			ret
086	org	0110h
087	; *-----------------------------------------------------*
088	; *	flash memory verify external program		*
089	; *-----------------------------------------------------*
090	fm_vrf_ex:
091			change	fm_vrf_in
092		fm_vrf_ex_exit:
093			ret
094	
095	org	0120h
096	; *-----------------------------------------------------*
097	; *	flash memory page read external program		*
098	; *-----------------------------------------------------*
099	fm_prd_ex:
100			change	fm_prd_in
101		fm_prd_ex_exit:
102			ret
103	
104	org	0130h
105	; *-----------------------------------------------------*
106	; *	flash memory => timer call external program	*
107	; *-----------------------------------------------------*
108	int_1b:
109	timer_ex:
110			push	ie
111			clr1	ie,7		;interrupt prohibition
112			change	timer_in
113		timer_ex_exit:
114			call	int_BaseTimer	;(ユーザー側ベースタイマ割り込み処理)
115			pop	ie
116			reti
117	
118	org	01f0h
119	_game_end:
120			change	game_end
121	end
●B_TIMER1.ASM
001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** ベースタイマ割り込み利用サンプル1 **
005	;
006	; ・ベースタイマ割り込み(0.5秒ごと)をカウントする
007	; ・カウンタの値を2桁10進数でLCDに表示する
008	;----------------------------------------------------------------------------
009	; 1.01 990208 SEGA Enterprises,LTD.
010	;----------------------------------------------------------------------------
011	
012	chip	LC868700			; チップの種類をアセンブラに指定
013	world	external			; 外部メモリ用プログラム
014	
015	public	main				; ghead.asm から参照されるシンボル
016	public	int_BaseTimer		; ghead.asm から参照されるシンボル
017	
018	extern	_game_end			; ghead.asm への参照シンボル
019	
020	
021	; **** システム定数の定義 ***************************************************
022	
023								; OCR(発振制御レジスタ)設定値
024	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
025	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
026	
027	
028	; *** データセグメント ******************************************************
029	
030			dseg				; データセグメント開始
031	
032	r0:		ds		1			; 間接アドレッシングレジスタ r0
033	r1:		ds		1			; 間接アドレッシングレジスタ r1
034	r2:		ds		1			; 間接アドレッシングレジスタ r2
035	r3:		ds		1			; 間接アドレッシングレジスタ r3
036			ds		12			; その他のシステム予約レジスタ
037			
038	counter: ds		1			; ベースタイマ割り込みカウンタ
039	work1:	ds		1			; 作業用 (put2digit)
040	
041	
042	; *** コードセグメント ******************************************************
043	
044			cseg				; コードセグメント開始
045			
046	; *-------------------------------------------------------------------------*
047	; * ユーザープログラム														*
048	; *-------------------------------------------------------------------------*
049	main:
050			mov		#0,counter	; カウンタの値をリセット
051			
052			call	cls			; LCD表示イメージを消去する
053			
054	loop0:
055			mov		#2,c		; 表示位置(水平)
056			mov		#1,b		; 表示位置(垂直)
057			ld		counter		; カウンタの値をaccへ
058			call	put2digit	; accの値(2桁)を数値表示する
059			
060			set1	pcon,0		; 次の割り込みまでHALTモードで待つ
061	
062								; ** [M](モード)ボタンチェック **
063			ld		P3
064			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
065	
066			br		loop0		; 繰り返し
067	
068	finish:						; ** アプリケーション終了処理 **
069			jmp		_game_end	; アプリケーション終了
070	
071	
072	; *-------------------------------------------------------------------------*
073	; * 2桁の数値を表示する														*
074	; * 入力 acc : 数値															*
075	; *        c : 文字水平位置												  	*
076	; *        b : 文字垂直位置												  	*
077	; *-------------------------------------------------------------------------*
078	put2digit:
079			push	b			; 座標データを退避
080			push	c			;
081			st		c			; 10の位と1の位の値をそれぞれ計算
082			xor		a			; ( acc = acc/10, work1 = acc mod 10 )
083			mov		#10,b		;
084			div					;
085			ld		b			;
086			st		work1		; 1の位の計算結果をwork1に保存
087			ld		c			;
088			pop		c			; 座標値を(c.b)に復帰
089			pop		b			; 
090			push	b			; また退避
091			push	c			;
092			call	putch		; 10の位を表示
093			ld		work1		; 1の位の値を読み込み
094			pop		c			; 座標値を(c,b)に復帰
095			pop		b			; 
096			inc		c			; 表示座標を右へ
097			call	putch		; 1の位を表示
098	
099			ret					; put2digit終わり
100	
101	
102	; *-------------------------------------------------------------------------*
103	; * LCD表示イメージを消去する												*
104	; *-------------------------------------------------------------------------*
105	cls:
106			push	OCR			; OCR値を退避
107			mov		#osc_rc,OCR ; システムクロックを指定
108	
109			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
110			call	cls_s		; そのバンク内のデータをクリア
111	
112			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
113			call	cls_s		; そのバンク内のデータをクリア
114			pop		OCR			; OCR値を復帰
115			
116			ret					; cls終わり
117			
118	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
119			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
120			mov		#80h,b 		; ループカウンタbにループ数をセット
121	loop3:
122			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
123			inc		r2			;
124			dbnz	b,loop3		; bが0になるまで繰り返す
125			
126			ret					; cls_s終わり
127			
128	
129	; *-------------------------------------------------------------------------*
130	; * 指定位置に1キャラクタ表示する											*
131	; * 入力 acc : キャラクタコード												*
132	; *        c : 文字水平位置												  	*
133	; *        b : 文字垂直位置												  	*
134	; *-------------------------------------------------------------------------*
135	putch:
136			push	XBNK
137			push	acc
138			call	locate		; 座標から表示RAMのアドレスを計算
139			pop		acc
140			call	put_chara	; 1キャラクタ表示する
141			pop		XBNK
142			
143			ret					; putch終わり
144			
145	
146	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
147			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
148			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
149	
150								; *** 表示用RAMバンクアドレスの判断 ***
151			ld		b			; b>=2 のとき next1 へ
152			sub		#2			;
153			bn		PSW,7,next1	;
154			
155			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
156			br		next2
157	next1:
158			st		b
159			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
160	next2:
161	
162								; *** 表示指定位置のRAMアドレス計算 ***
163			ld		b			; b * 40h + c + 80h
164			rol					;
165			rol					;
166			rol					;
167			rol					;
168			rol					;
169			rol					;
170			add		c			;
171			add		#80h		;
172			st		r2			; RAMアドレスをr2に格納
173					
174			ret					; locate終わり
175	
176	
177	put_chara:
178			push	PSW			; PSW値を退避
179			set1	PSW,1		; データRAMバンク1を選択
180	
181								; *** キャラクタデータアドレスの計算 ***
182			rol					; (TRH,TRL) = acc*8 + fontdata
183			rol					;
184			rol					;	
185			add		#low(fontdata)	;
186			st		TRL				;
187			mov		#0,acc			;
188			addc	#high(fontdata)	;
189			st		TRH			;
190	
191			push	OCR			; OCR値を退避
192			mov		#osc_rc,OCR ; システムクロックを指定
193	
194			mov		#0,b		; キャラクタデータ読み出し用オフセット値
195			mov		#4,c		; ループカウンタ
196	loop1:
197			ld		b			; 1ライン目の表示データを読み出す
198			ldc					;
199			inc		b			; 読み出しデータのオフセットを +1
200			st		@r2			; 表示データを表示用RAMに転送
201			ld		r2			; 表示用RAMアドレス +6
202			add		#6			;
203			st		r2			;
204	
205			ld		b			; 2ライン目の表示データを読み出す
206			ldc					;
207			inc		b			; 読み出しデータのオフセットを +1
208			st		@r2			; 表示データを表示用RAMに転送
209			ld		r2			; 表示用RAMアドレス +10
210			add		#10			;
211			st		r2			;
212			
213			dec		c			; ループカウンタのデクリメント
214			ld		c			; 
215			bnz		loop1		; 8ライン分(4回)繰り返し
216	
217			pop		OCR			; OCR値を復帰
218			pop		PSW			; PSW値を復帰
219	
220			ret					; put_chara終わり
221	
222	
223	; *-------------------------------------------------------------------------*
224	; * キャラクタのビットイメージデータ										*
225	; *-------------------------------------------------------------------------*
226	fontdata:
227			db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;'0' 00 
228			db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;'1' 01
229			db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;'2' 02
230			db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;'3' 03
231			db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;'4' 04
232			db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;'5' 05
233			db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;'6' 06
234			db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;'7' 07
235			db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;'8' 08
236			db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;'9' 09		
237	
238	
239	; *-------------------------------------------------------------------------*
240	; * ベースタイマ割り込みハンドラ部											*
241	; *-------------------------------------------------------------------------*
242	int_BaseTimer:
243			push	acc			; 使用レジスタを退避
244			inc		counter		; カウンタをインクリメント
245			ld		counter		; カウンタが100になったら..
246			bne		#100,next3	;
247			mov		#0,counter	; カウンタのリセット
248	next3:						;
249			pop		acc			; 退避レジスタを復帰
250			
251			ret					; (ユーザー側)割り込み処理終了

6-4 ボタン押下の検出


ビジュアルメモリのボタン押下状態(リセットボタンとMODEボタンを除く)を調べ、押されているボタンをLCDに表示します。

46行目でポート3に0FFHを書き込み、全ビットをプルアップします。

ボタンの押下状態は、51行目でポート3の状態をACCに読み込みます。この時点で押されているボタンがあれば、対応するビットが0にリセットされています。

52行目では、そのビットがセット(ボタンが押されていない)されているかをチェックし、次のボタンチェック処理に移ります。もしボタンが押されている場合は、52行目の条件は偽となり、対応するボタンを表示する処理を行います。

ノート

システムBIOSから呼び出された直後は、ポート3割り込みが有効になっています。また、ポート3割り込みはレベル割り込みなので、ボタンが押されている間は割り込みが上がり続けます。

そこで、ポート3割り込みを無効にすると、アプリケーション全体のパフォーマンスが向上します。

なお、ポート3割り込みでHALTモードの解除を行うアプリケーションは、その直前でポート3割り込みを許可する必要があります。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** ボタン状態検出サンプル1 **
005	;
006	; ・ボタンの状態を読み込んで、押下されているボタンをLCDに表示する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	
016	extern	_game_end			; ghead.asm への参照シンボル
017	
018	
019	; **** システム定数の定義 ***************************************************
020	
021								; OCR(発振制御レジスタ)設定値
022	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
023	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
024	
025	
026	; *** データセグメント ******************************************************
027	
028			dseg				; データセグメント開始
029	
030	r0:		ds		1			; 間接アドレッシングレジスタ r0
031	r1:		ds		1			; 間接アドレッシングレジスタ r1
032	r2:		ds		1			; 間接アドレッシングレジスタ r2
033	r3:		ds		1			; 間接アドレッシングレジスタ r3
034			ds		12			; その他のシステム予約レジスタ
035	
036	; *** コードセグメント ******************************************************
037	
038			cseg				; コードセグメント開始
039			
040	; *-------------------------------------------------------------------------*
041	; * ユーザープログラム														*
042	; *-------------------------------------------------------------------------*
043	main:
044			call	cls			; LCD表示イメージを消去する
045	
046			mov		#0ffh,P3	; P3の初期化(プルアップ設定)
047	
048	loop0:
049								; ** [A]ボタンのチェック **
050			mov		#0,b
051			ld		P3			; P3の状態を読み込む
052			bp		acc,4,next3	; [A]ボタン押されてなければ next3
053			mov		#1,b		; 表示文字コード 'A'
054	next3:	
055			ld		b
056			mov		#4,c		; 表示座標(水平)
057			mov		#3,b		; 表示座標(垂直)
058			call	putch		; 一文字表示
059	
060								; ** [B]ボタンのチェック **
061			mov		#0,b
062			ld		P3
063			bp		acc,5,next4	; [B]ボタン押されてなければ next4
064			mov		#2,b		; 表示文字コード 'B'
065	next4:	
066			ld		b
067			mov		#5,c
068			mov		#2,b
069			call	putch
070	
071								; ** [↑]ボタンのチェック **
072			mov		#0,b
073			ld		P3
074			bp		acc,0,next5	; [↑]ボタン押されてなければ next5
075			mov		#3,b		; 表示文字コード '↑'
076	next5:	
077			ld		b
078			mov		#1,c
079			mov		#1,b
080			call	putch
081	
082								; ** [→]ボタンのチェック **
083			mov		#0,b
084			ld		P3
085			bp		acc,3,next6	; [→]ボタン押されてなければ next6
086			mov		#4,b		; 表示文字コード '→'
087	next6:	
088			ld		b
089			mov		#2,c
090			mov		#2,b
091			call	putch
092	
093								; ** [↓]ボタンのチェック **
094			mov		#0,b
095			ld		P3
096			bp		acc,1,next7	; [↓]ボタン押されてなければ next7
097			mov		#5,b		; 表示文字コード '↓'
098	next7:	
099			ld		b
100			mov		#1,c
101			mov		#3,b
102			call	putch
103	
104								; ** [←]ボタンのチェック **
105			mov		#0,b
106			ld		P3
107			bp		acc,2,next8	; [←]ボタン押されてなければ next8
108			mov		#6,b		; 表示文字コード '←'
109	next8:	
110			ld		b
111			mov		#0,c
112			mov		#2,b
113			call	putch
114	
115								; ** [S]ボタンのチェック **
116			mov		#0,b
117			ld		P3
118			bp		acc,7,next9	; [S]ボタン押されてなければ next9
119			mov		#8,b		; 表示文字コード 'S'
120	next9:	
121			ld		b
122			mov		#4,c
123			mov		#1,b
124			call	putch
125	
126								; ** [M]ボタンのチェック **
127			ld		P3
128			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
129	
130			brf		loop0		; 繰り返し
131	
132	finish:						; ** アプリケーション終了処理 **
133			jmp		_game_end	; アプリケーション終了
134	
135	
136	; *-------------------------------------------------------------------------*
137	; * LCD表示イメージを消去する												*
138	; *-------------------------------------------------------------------------*
139	cls:
140			push	OCR			; OCR値を退避
141			mov		#osc_rc,OCR ; システムクロックを指定
142	
143			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
144			call	cls_s		; そのバンク内のデータをクリア
145	
146			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
147			call	cls_s		; そのバンク内のデータをクリア
148			pop		OCR			; OCR値を復帰
149			
150			ret					; cls終わり
151			
152	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
153			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
154			mov		#80h,b 		; ループカウンタbにループ数をセット
155	loop3:
156			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
157			inc		r2			;
158			dbnz	b,loop3		; bが0になるまで繰り返す
159			
160			ret					; cls_s終わり
161			
162	
163	; *-------------------------------------------------------------------------*
164	; * 指定位置に1キャラクタ表示する											*
165	; * 入力 acc : キャラクタコード												*
166	; *        c : 文字水平位置												  	*
167	; *        b : 文字垂直位置												  	*
168	; *-------------------------------------------------------------------------*
169	putch:
170			push	XBNK
171			push	acc
172			call	locate		; 座標から表示RAMのアドレスを計算
173			pop		acc
174			call	put_chara	; 1キャラクタ表示する
175			pop		XBNK
176			
177			ret					; putch終わり
178			
179	
180	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
181			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
182			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
183	
184								; *** 表示用RAMバンクアドレスの判断 ***
185			ld		b			; b>=2 のとき next1 へ
186			sub		#2			;
187			bn		PSW,7,next1	;
188			
189			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
190			br		next2
191	next1:
192			st		b
193			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
194	next2:
195	
196								; *** 表示指定位置のRAMアドレス計算 ***
197			ld		b			; b * 40h + c + 80h
198			rol					;
199			rol					;
200			rol					;
201			rol					;
202			rol					;
203			rol					;
204			add		c			;
205			add		#80h		;
206			st		r2			; RAMアドレスをr2に格納
207					
208			ret					; locate終わり
209	
210	
211	put_chara:
212			push	PSW			; PSW値を退避
213			set1	PSW,1		; データRAMバンク1を選択
214	
215								; *** キャラクタデータアドレスの計算 ***
216			rol					; (TRH,TRL) = acc*8 + fontdata
217			rol					;
218			rol					;	
219			add		#low(fontdata)	;
220			st		TRL				;
221			mov		#0,acc			;
222			addc	#high(fontdata)	;
223			st		TRH			;
224	
225			push	OCR			; OCR値を退避
226			mov		#osc_rc,OCR ; システムクロックを指定
227	
228			mov		#0,b		; キャラクタデータ読み出し用オフセット値
229			mov		#4,c		; ループカウンタ
230	loop1:
231			ld		b			; 1ライン目の表示データを読み出す
232			ldc					;
233			inc		b			; 読み出しデータのオフセットを +1
234			st		@r2			; 表示データを表示用RAMに転送
235			ld		r2			; 表示用RAMアドレス +6
236			add		#6			;
237			st		r2			;
238	
239			ld		b			; 2ライン目の表示データを読み出す
240			ldc					;
241			inc		b			; 読み出しデータのオフセットを +1
242			st		@r2			; 表示データを表示用RAMに転送
243			ld		r2			; 表示用RAMアドレス +10
244			add		#10			;
245			st		r2			;
246			
247			dec		c			; ループカウンタのデクリメント
248			ld		c			; 
249			bnz		loop1		; 8ライン分(4回)繰り返し
250			
251			pop		OCR			; OCR値を復帰
252			pop		PSW			; PSW値を復帰
253	
254			ret					; put_chara終わり
255	
256	
257	; *-------------------------------------------------------------------------*
258	; * キャラクタのビットイメージデータ										*
259	; *-------------------------------------------------------------------------*
260	fontdata:
261			db 000h, 000h, 038h, 038h, 038h, 000h, 000h, 000h	;'・' 00
262			db 01eh, 036h, 066h, 0c6h, 0c6h, 0feh, 0c6h, 000h	;'A'  01
263			db 0fch, 066h, 066h, 07ch, 066h, 066h, 0fch, 000h	;'B'  02
264	
265			db 010h, 038h, 07ch, 0feh, 038h, 038h, 038h, 000h	;'↑' 03
266			db 010h, 018h, 0fch, 0feh, 0fch, 018h, 010h, 000h	;'→' 04
267			db 038h, 038h, 038h, 0feh, 07ch, 038h, 010h, 000h	;'↓' 05
268			db 010h, 030h, 07eh, 0feh, 07eh, 030h, 010h, 000h	;'←' 06
269	
270			db 0c6h, 0eeh, 0feh, 0d6h, 0c6h, 0c6h, 0c6h, 000h	;'M'  07
271			db 07ch, 0e6h, 076h, 038h, 0dch, 0ceh, 07ch, 000h	;'S'  08

6-5 PWM音源の利用


高い音(約781Hz)と低い音(約342Hz)を交互に発生させます。

このサンプルの本質は、72行目以降のサブルーチンです。

SndInitでは、PWMを利用できるようにしています。Snd1(2)Startでは、タイマー1に発生する周波数を設定し、カウント動作を開始させます。SndStopでは、カウント動作を停止し音声出力を停止します。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** サウンド使用サンプル1 **
005	;
006	; ・2種類の音(高/低音)を断続的に出力する
007	;   (低い音 0.5秒 - 無音 0.5秒 - 高い音 0.5秒 - 無音 0.5秒 …)
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			; アプリケーション終了
018	
019	
020	; **** システム定数の定義 ***************************************************
021	
022								; OCR(発振制御レジスタ)設定値
023	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
024	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
025	
026	
027	; *** データセグメント ******************************************************
028	
029			dseg				; データセグメント開始
030	
031	r0:		ds		1			; 間接アドレッシングレジスタ r0
032	r1:		ds		1			; 間接アドレッシングレジスタ r1
033	r2:		ds		1			; 間接アドレッシングレジスタ r2
034	r3:		ds		1			; 間接アドレッシングレジスタ r3
035			ds		12			; その他のシステム予約レジスタ
036	
037	
038	; *** コードセグメント ******************************************************
039	
040			cseg				; コードセグメント開始
041			
042	; *-------------------------------------------------------------------------*
043	; * ユーザープログラム														*
044	; *-------------------------------------------------------------------------*
045	main:
046			call	SndInit		; サウンド初期化
047			
048	loop0:	
049			call	Snd1Start	; 約342Hz の発音開始
050			set1	PCON,0		; ベースタイマ割り込みまでHALT(0.5秒)
051	
052			call	SndStop		; ブザー音停止
053			set1	PCON,0		; ベースタイマ割り込みまでHALT(0.5秒)
054	
055			call	Snd2Start	; 約781Hz の発音開始
056			set1	PCON,0		; ベースタイマ割り込みまでHALT(0.5秒)
057			
058			call	SndStop		; ブザー音停止
059			set1	PCON,0		; ベースタイマ割り込みまでHALT(0.5秒)
060	
061	
062								; ** [M](モード)ボタンチェック **
063			ld		P3
064			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
065	
066			br		loop0		; 繰り返し
067	
068	finish:						; ** アプリケーション終了処理 **
069			jmp		_game_end	; アプリケーション終了
070			
071	
072	; *-------------------------------------------------------------------------*
073	; * 音声出力関係															*
074	; *-------------------------------------------------------------------------*
075	SndInit:					; *** 音声出力ハードの初期化 ***
076			clr1	P1,7		; 音声出力ポートセット
077		
078			ret
079			
080	Snd1Start:					; *** 約342Hz の発音開始 ***
081			mov		#0f0h,T1LR	; 周期 = 100h-0f0h = 16
082			mov		#0f8h,T1LC	; Lレベル幅 = 100h-0f8h = 8
083			mov		#0D0h,T1CNT	; 音声出力開始
084			
085			ret
086	
087	Snd2Start:					; *** 約781Hz の発音開始 ***
088			mov		#0f9h,T1LR	; 周期 = 100h-0f9h = 7
089			mov		#0fch,T1LC	; Lレベル幅 = 100h-0fch = 4
090			mov		#0D0h,T1CNT	; 音声出力開始
091			
092			ret
093	
094	SndStop:					; *** 発音停止 ***
095			mov		#0,T1CNT	; 音声出力停止
096			
097			ret

6-6 タイマー0を使った割り込み


タイマー0を使って1秒ごとの割り込みを発生させます。割り込みが発生したことは、音で知らせます。

このプログラムの本質は、78〜93行目のT0Mode2Initルーチンです。タイマー0のモード2、プリスケーラ付き16ビットカウンタを利用します。タイマーには32KHzが入るので、それをプリスケーラおよびカウンタで約1秒ごとにオーバーフローを起こすように設定します。

タイマー0はオーバーフローで割り込みを発生するので、その割り込みハンドラを用意します。割り込みハンドラ内では、カウントアップを行い、割り込み要因フラグを0にリセットして、割り込み処理を終了します。

メインルーチンでは、カウンタの値が偶数か奇数かを判定し、高い音と低い音を交互に出力します。61行目では、CPUをHALTモードにし、割り込みが発生するまで動作を停止します。タイマー0割り込みやポート3割り込みが発生すると、次の行から動作を開始します。 ●GHEAD.ASM

001	chip	LC868700
002	world	external
003	; *-----------------------------------------------------*
004	; *	External header program Ver 1.00		*
005	; *					05/20-'98	*
006	; *-----------------------------------------------------*
007	
008	public	fm_wrt_ex_exit,fm_vrf_ex_exit
009	public	fm_prd_ex_exit,timer_ex_exit,_game_start,_game_end
010	other_side_symbol	fm_wrt_in,fm_vrf_in
011	other_side_symbol	fm_prd_in,timer_in,game_end
012	
013	extern	main			;ユーザープログラム側にあるシンボル
014	extern	int_T0H			;ユーザープログラム側にあるシンボル
015	
016	; *-----------------------------------------------------*
017	; *	Vector table(?)					*
018	; *-----------------------------------------------------*
019	cseg
020	org	0000h
021	_game_start:
022	;reset:
023			jmpf	main		; main program jump
024	org	0003h
025	;int_03:
026			jmp	int_03
027	org	000bh
028	;int_0b:
029			jmp	int_0b
030	org	0013h
031	;int_13:
032			jmp	int_13
033	org	001bh
034	;int_1b:
035			jmp	int_1b
036	org	0023h
037	;int_23:
038			jmp	int_23
039	org	002bh
040	;int_2b:
041			jmp	int_2b
042	org	0033h
043	;int_33:
044			jmp	int_33
045	org	003bh
046	;int_3b:
047			jmp	int_3b
048	org	0043h
049	;int_43:
050			jmp	int_43
051	org	004bh
052	;int_4b:
053			jmp	int_4b
054	; *-----------------------------------------------------*
055	; *	interrupt programs				*
056	; *-----------------------------------------------------*
057	int_03:
058			reti
059	int_0b:
060			reti
061	int_13:
062			reti
063	int_23:
064			jmp		int_T0H	;(ユーザー側割り込み処理へ)
065	int_2b:
066			reti
067	int_33:
068			reti
069	int_3b:
070			reti
071	; *-----------------------------------------------------*
072	int_43:
073			reti
074	int_4b:
075			clr1	p3int,1		;interrupt flag clear
076			reti
077	
078	org	0100h
079	; *-----------------------------------------------------*
080	; *	flash memory write external program		*
081	; *-----------------------------------------------------*
082	fm_wrt_ex:
083			change	fm_wrt_in
084		fm_wrt_ex_exit:
085			ret
086	org	0110h
087	; *-----------------------------------------------------*
088	; *	flash memory verify external program		*
089	; *-----------------------------------------------------*
090	fm_vrf_ex:
091			change	fm_vrf_in
092		fm_vrf_ex_exit:
093			ret
094	
095	org	0120h
096	; *-----------------------------------------------------*
097	; *	flash memory page read external program		*
098	; *-----------------------------------------------------*
099	fm_prd_ex:
100			change	fm_prd_in
101		fm_prd_ex_exit:
102			ret
103	
104	org	0130h
105	; *-----------------------------------------------------*
106	; *	flash memory => timer call external program	*
107	; *-----------------------------------------------------*
108	int_1b:
109	timer_ex:
110			push	ie
111			clr1	ie,7		;interrupt prohibition
112			change	timer_in
113		timer_ex_exit:
114			pop	ie
115			reti
116	
117	org	01f0h
118	_game_end:
119			change	game_end
120	end
●TIMER1.ASM
001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** タイマ/カウンタT0割り込み使用サンプル1 **
005	;
006	; ・ブザー音を断続的(2秒周期)に出力する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	public	int_T0H				; ghead.asm から参照されるシンボル
016	
017	extern	_game_end			; アプリケーション終了
018	
019	
020	; **** システム定数の定義 ***************************************************
021	
022								; OCR(発振制御レジスタ)設定値
023	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
024	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
025	
026	
027	; *** データセグメント ******************************************************
028	
029			dseg				; データセグメント開始
030	
031	r0:		ds		1			; 間接アドレッシングレジスタ r0
032	r1:		ds		1			; 間接アドレッシングレジスタ r1
033	r2:		ds		1			; 間接アドレッシングレジスタ r2
034	r3:		ds		1			; 間接アドレッシングレジスタ r3
035			ds		12			; その他のシステム予約レジスタ
036	
037	counter: ds		1			; タイマ割り込みカウンタ
038	
039	
040	; *** コードセグメント ******************************************************
041	
042			cseg				; コードセグメント開始
043			
044	; *-------------------------------------------------------------------------*
045	; * ユーザープログラム														*
046	; *-------------------------------------------------------------------------*
047	main:
048			call	SndInit		; 音声出力初期化
049			call	T0Mode2Init ; タイマ(T0)の初期化
050			mov		#0,counter	; カウンタのクリア
051			
052	loop0:	
053			ld		counter		; カウンタの値を読み込む
054			bp		acc,1,next1	; カウンタのbit0が1ならnext1へ
055			
056			call	Snd2Start	; 発音開始
057			br		next2
058	next1:
059			call	SndStop		; 音停止
060	next2:
061			set1	PCON,0		; 次の割り込みまでHALT
062	
063	
064								; ** [M](モード)ボタンチェック **
065			ld		P3
066			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
067	
068			br		loop0		; 繰り返し
069			
070	finish:						; ** アプリケーション終了処理 **
071			jmp		_game_end	; アプリケーション終了
072	
073	
074	; *-------------------------------------------------------------------------*
075	; * タイマ/カウンタT0 の初期化												*
076	; *   モード2(16bitカウンタ)で、約1秒毎に割り込みをかける					*
077	; *-------------------------------------------------------------------------*
078	T0Mode2Init:
079			mov		#255,T0PRR	; プリスケーラ値セット
080								;   8bitプリスケーラなので
081								;   周期 = (256-255)*0.000183 = 0.000183 (sec)
082			mov		#high(65536-5464),T0HR ; プリセット値(H)セット
083			mov		#low(65536-5464),T0LR  ; プリセット値(L)セット
084								;   プリスケーラとセットで
085								;   0.000183 * 5464 = 0.999912 (≒1sec)
086								;   1秒毎にオーバーフローが起こる
087			mov		#0ffh,T0L	; 最初すぐにオーバーフローするようにする
088			mov		#0ffh,T0H	;
089			mov		#0e4h,T0CNT	; モード2 (16bitカウンタ)
090								; T0Hオーバーフローで割り込みを発生させる
091								; T0動作開始
092		
093			ret					; T0Mode2Init終わり
094	
095	
096	T0HStop:					; *** T0Hタイマ停止 ***
097	
098			clr1	T0CNT,7		; T0Hカウント動作停止
099			ret
100	
101	
102	; *-------------------------------------------------------------------------*
103	; * タイマT0H割り込みハンドラ												*
104	; *-------------------------------------------------------------------------*
105	int_T0H:					; *** T0H割り込みハンドラ ***
106			inc		counter
107	
108			clr1	T0CNT,3		; タイマT0H割り込み要因クリア
109			reti
110	
111	
112	; *-------------------------------------------------------------------------*
113	; * 音声出力関係															*
114	; *-------------------------------------------------------------------------*
115	SndInit:					; *** 音声出力ハードの初期化 ***
116			clr1	P1,7		; 音声出力ポートセット
117		
118			ret
119			
120	Snd1Start:					; *** 約342Hz の発音開始 ***
121			mov		#0f0h,T1LR	; 周期 = 100h-0f0h = 16
122			mov		#0f8h,T1LC	; Lレベル幅 = 100h-0f8h = 8
123			mov		#0D4h,T1CNT	; 音声出力開始
124			
125			ret
126	
127	Snd2Start:					; *** 約781Hz の発音開始 ***
128			mov		#0f9h,T1LR	; 周期 = 100h-0f9h = 7
129			mov		#0fch,T1LC	; Lレベル幅 = 100h-0fch = 4
130			mov		#0D4h,T1CNT	; 音声出力開始
131			
132			ret
133	
134	SndStop:					; *** 発音停止 ***
135			mov		#0,T1CNT	; 音声出力停止
136			
137			ret

6-7 シリアル通信(送信側)


シリアルインターフェイスを使って、0〜99のデータを送信します。

注意

シリアル通信は、水晶発振で動作させてください。

受信は、次に掲載されいる「シリアル通信(受信側)」で行ってください。

53行目ではローバッテリ自動検出を禁止しています。実体は158行目以降のBattChkOnとBattChkOffです。

56行目では、シリアルインターフェイスの初期化を行っています。初期化の実体は95行目以降のルーチンです。非常に手間がかかるので、このロジックをそのままコピーして利用することをお勧めします。

初期化を行った後は、0.5秒ごとに発生するベースタイマー割り込みでカウンタをインクリメントします。このカウンタの数値をシリアルインターフェイスで送信します。

MODEボタンによりプログラムが中断されると、シリアルインターフェイスを規定の値に書き戻し(126行目からのSioEndルーチン)、ローバッテリ自動検出を有効にしてプログラムを終了します。 ●GHEAD.ASM

001	chip	LC868700
002	world	external
003	; *-----------------------------------------------------*
004	; *	External header program Ver 1.00		*
005	; *					05/20-'98	*
006	; *-----------------------------------------------------*
007	
008	public	fm_wrt_ex_exit,fm_vrf_ex_exit
009	public	fm_prd_ex_exit,timer_ex_exit,_game_start,_game_end
010	other_side_symbol	fm_wrt_in,fm_vrf_in
011	other_side_symbol	fm_prd_in,timer_in,game_end
012	
013	extern	main			;ユーザープログラム側にあるシンボル
014	extern	int_BaseTimer		;ユーザープログラム側にあるシンボル
015	
016	; *-----------------------------------------------------*
017	; *	Vector table(?)					*
018	; *-----------------------------------------------------*
019	cseg
020	org	0000h
021	_game_start:
022	;reset:
023			jmpf	main		; main program jump
024	org	0003h
025	;int_03:
026			jmp	int_03
027	org	000bh
028	;int_0b:
029			jmp	int_0b
030	org	0013h
031	;int_13:
032			jmp	int_13
033	org	001bh
034	;int_1b:
035			jmp	int_1b
036	org	0023h
037	;int_23:
038			jmp	int_23
039	org	002bh
040	;int_2b:
041			jmp	int_2b
042	org	0033h
043	;int_33:
044			jmp	int_33
045	org	003bh
046	;int_3b:
047			jmp	int_3b
048	org	0043h
049	;int_43:
050			jmp	int_43
051	org	004bh
052	;int_4b:
053			jmp	int_4b
054	; *-----------------------------------------------------*
055	; *	interrupt programs				*
056	; *-----------------------------------------------------*
057	int_03:
058			reti
059	int_0b:
060			reti
061	int_13:
062			reti
063	int_23:
064			reti
065	int_2b:
066			reti
067	int_33:
068			reti
069	int_3b:
070			reti
071	; *-----------------------------------------------------*
072	int_43:
073			reti
074	int_4b:
075			clr1	p3int,1		;interrupt flag clear
076			reti
077	
078	org	0100h
079	; *-----------------------------------------------------*
080	; *	flash memory write external program		*
081	; *-----------------------------------------------------*
082	fm_wrt_ex:
083			change	fm_wrt_in
084		fm_wrt_ex_exit:
085			ret
086	org	0110h
087	; *-----------------------------------------------------*
088	; *	flash memory verify external program		*
089	; *-----------------------------------------------------*
090	fm_vrf_ex:
091			change	fm_vrf_in
092		fm_vrf_ex_exit:
093			ret
094	
095	org	0120h
096	; *-----------------------------------------------------*
097	; *	flash memory page read external program		*
098	; *-----------------------------------------------------*
099	fm_prd_ex:
100			change	fm_prd_in
101		fm_prd_ex_exit:
102			ret
103	
104	org	0130h
105	; *-----------------------------------------------------*
106	; *	flash memory => timer call external program	*
107	; *-----------------------------------------------------*
108	int_1b:
109	timer_ex:
110			push	ie
111			clr1	ie,7		;interrupt prohibition
112			change	timer_in
113		timer_ex_exit:
114			call	int_BaseTimer ; ユーザー側割り込み処理
115			pop	ie
116			reti
117	
118	org	01f0h
119	_game_end:
120			change	game_end
121	end
●TIMER1.ASM
001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** シリアル通信サンプル1 (データ送信) **
005	;
006	; ・一定期間ごとにシリアル通信ポートから単純なデータを送信する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	public	int_BaseTimer		; ghead.asm から参照されるシンボル
016	
017	extern	_game_end			; アプリケーション終了
018	
019	
020	; **** システム定数の定義 ***************************************************
021	
022								; OCR(発振制御レジスタ)設定値
023	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
024	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
025	
026	LowBattChk	equ 06eh		; ローバッテリ検出フラグ(RAMバンク0)
027	
028	
029	; *** データセグメント ******************************************************
030	
031			dseg				; データセグメント開始
032	
033	r0:		ds		1			; 間接アドレッシングレジスタ r0
034	r1:		ds		1			; 間接アドレッシングレジスタ r1
035	r2:		ds		1			; 間接アドレッシングレジスタ r2
036	r3:		ds		1			; 間接アドレッシングレジスタ r3
037			ds		12			; その他のレジスタ
038	
039	counter: ds		1			; カウンタ
040	
041	
042	; *** コードセグメント ******************************************************
043	
044			cseg				; コードセグメント開始
045	
046	; *-------------------------------------------------------------------------*
047	; * ユーザープログラム														*
048	; *-------------------------------------------------------------------------*
049	main:
050			push	PSW			; PSW値を退避
051			set1	PSW,1		; データRAMバンク1を選択
052	
053			call	BattChkOff	; ローバッテリ自動検出機能 OFF
054	
055	cwait:
056			call	SioInit		; シリアル通信の初期化
057			bz		start		; VM が接続されていればスタート
058	
059			ld		P3			; [M]ボタンチェック
060			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
061	
062			jmp		cwait		; VM が接続されるまで待機
063	start:
064	
065			set1	pcon,0		; 次の割り込みまで(0.5秒)HALTで待つ
066	
067			mov		#0,counter	; カウンタの値を0にリセット
068	loop0:
069			ld		counter		; カウンタの値を読み込む
070	
071			call	SioSend1	; 1byte送信する
072	
073			set1	pcon,0		; 次の割り込みまで(0.5秒)HALTで待つ
074	
075								; ** [M](モード)ボタンチェック **
076			ld		P3
077			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
078	
079			jmp		loop0		; 繰り返し
080	
081	finish:						; ** アプリケーション終了処理 **
082			call	SioEnd		; シリアル通信終了処理
083			call	BattChkOn	; ローバッテリ自動検出機能 ON
084			pop		PSW			; PSW値を復帰
085			jmp		_game_end	; アプリケーション終了
086	
087	; *-------------------------------------------------------------------------*
088	; * シリアル通信の初期化													*
089	; * 出力: acc = 0   : 正常終了												*
090	; *       acc = 0ffh: VM が接続されていない								*
091	; *-------------------------------------------------------------------------*
092	; シリアル通信の初期化
093	; システムクロックが水晶モードであることを前提としています。
094	
095	SioInit:
096								; **** VM同士の接続を確認 ****
097			ld		P7			; 接続状態の確認
098			and		#%00001101	; P70, P72, P73 をチェック
099			sub		#%00001000	; P70=0, P72=0, P73=1 か判定
100			bz		next2		; 接続されているときnext2へ
101		
102			mov		#0ffh,acc	; 接続されていないとき acc=0ffh として異常終了
103			ret					; SioInit終わり
104	next2:
105	
106								; **** シリアル通信の初期化 ****
107			mov		#0,SCON0	; LSBを先頭に出力するよう指定
108			mov		#0,SCON1	; LSBを先頭に入力するよう指定
109			mov		#088h,SBR	; 転送レートを設定する
110			clr1	P1,0		; P10ラッチをクリア(P10/SO0)
111			clr1	P1,2		; P12ラッチをクリア(P12/SCK0)
112			clr1	P1,3		; P13ラッチをクリア(P13/SO1)
113	
114			mov		#%00000101,P1FCR ; 端子機能設定
115			mov		#%00000101,P1DDR ; 端子機能設定
116	
117			mov		#0,SBUF0	; 転送バッファクリア
118			mov		#0,SBUF1	; 転送バッファクリア
119	
120			ret					; SioInit終わり
121	
122	
123	; *-------------------------------------------------------------------------*
124	; * シリアル通信の終了														*
125	; *-------------------------------------------------------------------------*
126	SioEnd:						; **** シリアル通信終了処理 ****
127	
128			mov		#0,SCON0	; SCON0 = 0
129			mov		#0,	SCON1	; SCON1 = 0
130			mov		#0bfh,P1FCR	; P1FCR = 0bfh
131			mov		#0a4h,P1DDR	; P1DDR = 0a4h
132	
133			ret					; SioEnd終わり
134	
135	
136	; *-------------------------------------------------------------------------*
137	; * シリアルポートから1byte送信する											*
138	; *   入力 acc: 送信データ													*
139	; *-------------------------------------------------------------------------*
140	SioSend1:					; **** 1byte送信する ****
141	
142			push	acc			; 送信データの退避
143			
144	sslp1:	ld		SCON0		; 前のデータの送信中なら待つ
145			bp		acc,3,sslp1 ; 
146			
147			pop		acc			; 送信データの復帰
148			
149			st		SBUF0		; 転送するデータをセットする
150			set1	SCON0,3		; 送信開始
151	
152			ret					; SioSend1終わり
153	
154	
155	; *-------------------------------------------------------------------------*
156	; *	ローバッテリ自動検出機能 ON												*
157	; *-------------------------------------------------------------------------*
158	BattChkOn:
159			push	PSW			; PSW値を退避
160	
161			clr1	PSW,1		; データRAMバンク0を選択
162			mov		#0,acc		; ローバッテリ検出をする(0)
163			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
164	
165			pop		PSW			; PSW値を復帰
166			ret					; BattChkOn終わり
167	
168	
169	; *-------------------------------------------------------------------------*
170	; *	ローバッテリ自動検出機能 OFF											*
171	; *-------------------------------------------------------------------------*
172	BattChkOff:
173			push	PSW			; PSW値を退避
174	
175			clr1	PSW,1		; データRAMバンク0を選択
176			mov		#0ffh,acc	; ローバッテリ検出をしない(0ffh)
177			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
178	
179			pop		PSW			; PSW値を復帰
180			ret					; BattChkOff終わり
181	
182	
183	; *-------------------------------------------------------------------------*
184	; *	ベースタイマ割り込みハンドラ											*
185	; *-------------------------------------------------------------------------*
186	int_BaseTimer:
187			push	PSW			; PSW値を退避
188			push	acc
189	
190			set1	PSW,1		; データRAMバンク1を選択
191			
192			inc		counter		; カウンタを進める
193			
194			ld		counter		; カウンタの値が..
195			bne		#100,next1	; 100でなければnext1
196			mov		#0,counter	; 100ならば0にリセット
197	next1:
198			pop		acc
199			pop		PSW			; PSW値復帰
200			
201			clr1	BTCR,1		; ベースタイマ割り込み要因クリア
202			ret					; ユーザー側割り込み処理終了

6-8 シリアル通信(受信側)


シリアルインターフェイスを使って、データを受信します。

このプログラムは、シリアル通信の本質を説明するため、SIO割り込みを利用していません。実用的なシリアル通信は、次の「汎用シリアルドライバ」を参照してください。

ローバッテリ自動検出を停止し、シリアルインターフェイスを初期化します。

64行目では、シリアルインターフェイスにデータが(1バイト)溜っているかをチェックしています。もしデータがあれば、受信したデータをput2digitルーチンで10進数に変換しLCDに表示します。

MODEボタンによりプログラムが中断されると、シリアルインターフェイスを規定の値に書き戻し(121行目からのSioEndルーチン)、ローバッテリ自動検出を有効にしてプログラムを終了します。

注意

「シリアル通信(送信側)」では、0.5秒ごとにデータを送信しているので問題にはなりませんが、受信処理が完了していない時点でデータを送信すると、データを取りこぼします。

連続したデータを受信する場合は、SIO割り込みを利用してください。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** シリアル通信サンプル2 (データ受信) **
005	;
006	; ・シリアル通信ポートから受信した数値をLCDに表示する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	
016	extern	_game_end			; アプリケーション終了
017	
018	
019	; **** システム定数の定義 ***************************************************
020	
021								; OCR(発振制御レジスタ)設定値
022	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
023	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
024	
025	LowBattChk	equ 06eh		; ローバッテリ検出フラグ(RAMバンク0)
026	
027	
028	; *** データセグメント ******************************************************
029	
030			dseg				; データセグメント開始
031	
032	r0:		ds		1			; 間接アドレッシングレジスタ r0
033	r1:		ds		1			; 間接アドレッシングレジスタ r1
034	r2:		ds		1			; 間接アドレッシングレジスタ r2
035	r3:		ds		1			; 間接アドレッシングレジスタ r3
036			ds		12			; その他のレジスタ
037	
038	counter: ds		1			; カウンタ
039	work1:	ds		1			; 作業用(put2digitで使用)
040	
041	
042	; *** コードセグメント ******************************************************
043	
044			cseg				; コードセグメント開始
045	
046	; *-------------------------------------------------------------------------*
047	; * ユーザープログラム														*
048	; *-------------------------------------------------------------------------*
049	main:
050			call	cls			; LCD表示の消去
051			call	BattChkOff	; ローバッテリ自動検出機能 OFF
052			clr1	P3INT,0		; P3割り込みをマスク
053	cwait:
054			call	SioInit		; シリアル通信の初期化
055			bz		start		; VM が接続されていればスタート
056	
057			ld		P3			; [M]ボタンチェック
058			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
059	
060			jmp		cwait		; VM が接続されるまで待機
061	start:
062	
063	loop0:
064			call	SioRecv1	; 1byte受信する
065			bnz		next4		; 受信データがない場合はnext4へ
066	
067			ld		b			; 受信したデータをaccへ
068			mov		#2,c		; 表示座標(水平)
069			mov		#1,b		; 表示座標(垂直)
070			call	put2digit	; LCDに2桁数値表示
071	
072	next4:						; ** [M](モード)ボタンチェック **
073			ld		P3
074			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
075	
076			jmp		loop0		; 繰り返し
077	
078	finish:						; ** アプリケーション終了処理 **
079			call	SioEnd		; シリアル通信終了処理
080			call	BattChkOn	; ローバッテリ自動検出機能 ON
081			jmp		_game_end	; アプリケーション終了		
082	
083	; *-------------------------------------------------------------------------*
084	; * シリアル通信の初期化													*
085	; * 出力: acc = 0   : 正常終了												*
086	; *       acc = 0ffh: VM が接続されていない								*
087	; *-------------------------------------------------------------------------*
088	; シリアル通信の初期化
089	; システムクロックが水晶モードであることを前提としています。
090	SioInit:
091								; **** VM同士の接続を確認 ****
092			ld		P7			; 接続状態の確認
093			and		#%00001101	; P70, P72, P73 をチェック
094			sub		#%00001000	; P70=0, P72=0, P73=1 か判定
095			bz		next3		; 接続されているときnext3へ
096		
097			mov		#0ffh,acc	; 接続されていないとき acc=0ffh として異常終了
098			ret					; SioInit終わり
099	next3:
100	
101								; **** シリアル通信の初期化 ****
102			mov		#0,SCON0	; LSBを先頭に出力するよう指定
103			mov		#0,SCON1	; LSBを先頭に入力するよう指定
104			mov		#088h,SBR	; 転送レートを設定する
105			clr1	P1,0		; P10ラッチをクリア(P10/SO0)
106			clr1	P1,2		; P12ラッチをクリア(P12/SCK0)
107			clr1	P1,3		; P13ラッチをクリア(P13/SO1)
108	
109			mov		#%00000101,P1FCR ; 端子機能設定
110			mov		#%00000101,P1DDR ; 端子機能設定
111	
112			mov		#0,SBUF0	; 転送バッファクリア
113			mov		#0,SBUF1	; 転送バッファクリア
114	
115			ret					; SioInit終わり
116	
117	
118	; *-------------------------------------------------------------------------*
119	; * シリアル通信の終了														*
120	; *-------------------------------------------------------------------------*
121	SioEnd:						; **** シリアル通信終了処理 ****
122	
123			mov		#0,SCON0	; SCON0 = 0
124			mov		#0,	SCON1	; SCON1 = 0
125			mov		#0bfh,P1FCR	; P1FCR = 0bfh
126			mov		#0a4h,P1DDR	; P1DDR = 0a4h
127	
128			ret					; SioEnd終わり
129	
130	
131	; *-------------------------------------------------------------------------*
132	; * シリアルポートから1byte受信する											*
133	; *   出力 b: 受信データ													*
134	; *        acc=0   : 受信データあり											*
135	; *        acc=0ffh: 受信データなし											*
136	; *-------------------------------------------------------------------------*
137	SioRecv1:					; **** 1byte受信する ****
138			ld		SCON1
139			bp		acc,1,next5	; 受信データがあるときnext5へ
140			bp		acc,3,next6 ; 現在転送中ならnext6へ
141			
142			set1	SCON1,3		; 転送開始
143	next6:
144			mov		#0ffh,acc	; acc=0ffh(受信データなし)として返る
145			ret					; SioRecv1終わり		
146	next5:
147			
148			ld		SBUF1		; 受信データを読み込む
149			st		b			; データをbへコピー
150			
151			clr1	SCON1,1		; 転送終了フラグをリセット
152			
153			mov		#0,acc		; acc=0(受信データあり)として返る
154			ret					; SioRecv1終わり
155	
156	
157	; *-------------------------------------------------------------------------*
158	; * 2桁の数値を表示する														*
159	; * 入力 acc : 数値															*
160	; *        c : 文字水平位置												  	*
161	; *        b : 文字垂直位置												  	*
162	; *-------------------------------------------------------------------------*
163	put2digit:
164			push	b			; 座標データを退避
165			push	c			;
166			st		c			; 10の位と1の位の値をそれぞれ計算
167			xor		a			; ( acc = acc/10, work1 = acc mod 10 )
168			mov		#10,b		;
169			div					;
170			ld		b			;
171			st		work1		; 1の位の計算結果をwork1に保存
172			ld		c			;
173			pop		c			; 座標値を(c.b)に復帰
174			pop		b			; 
175			push	b			; また退避
176			push	c			;
177			call	putch		; 10の位を表示
178			ld		work1		; 1の位の値を読み込み
179			pop		c			; 座標値を(c,b)に復帰
180			pop		b			; 
181			inc		c			; 表示座標を右へ
182			call	putch		; 1の位を表示
183	
184			ret					; put2digit終わり
185	
186	
187	; *-------------------------------------------------------------------------*
188	; * LCD表示イメージを消去する												*
189	; *-------------------------------------------------------------------------*
190	cls:
191			push	OCR			; OCR値を退避
192			mov		#osc_rc,OCR ; システムクロックを指定
193	
194			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
195			call	cls_s		; そのバンク内のデータをクリア
196	
197			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
198			call	cls_s		; そのバンク内のデータをクリア
199			pop		OCR			; OCR値を復帰
200			
201			ret					; cls終わり
202			
203	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
204			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
205			mov		#80h,b 		; ループカウンタbにループ数をセット
206	loop3:
207			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
208			inc		r2			;
209			dbnz	b,loop3		; bが0になるまで繰り返す
210			
211			ret					; cls_s終わり
212			
213	
214	; *-------------------------------------------------------------------------*
215	; * 指定位置に1キャラクタ表示する											*
216	; * 入力 acc : キャラクタコード												*
217	; *        c : 文字水平位置												  	*
218	; *        b : 文字垂直位置												  	*
219	; *-------------------------------------------------------------------------*
220	putch:
221			push	XBNK
222			push	acc
223			call	locate		; 座標から表示RAMのアドレスを計算
224			pop		acc
225			call	put_chara	; 1キャラクタ表示する
226			pop		XBNK
227			
228			ret					; putch終わり
229			
230	
231	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
232			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
233			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
234	
235								; *** 表示用RAMバンクアドレスの判断 ***
236			ld		b			; b>=2 のとき next1 へ
237			sub		#2			;
238			bn		PSW,7,next1	;
239			
240			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
241			br		next2
242	next1:
243			st		b
244			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
245	next2:
246	
247								; *** 表示指定位置のRAMアドレス計算 ***
248			ld		b			; b * 40h + c + 80h
249			rol					;
250			rol					;
251			rol					;
252			rol					;
253			rol					;
254			rol					;
255			add		c			;
256			add		#80h		;
257			st		r2			; RAMアドレスをr2に格納
258					
259			ret					; locate終わり
260	
261	
262	put_chara:
263			push	PSW			; PSW値を退避
264			set1	PSW,1		; データRAMバンク1を選択
265	
266								; *** キャラクタデータアドレスの計算 ***
267			rol					; (TRH,TRL) = acc*8 + fontdata
268			rol					;
269			rol					;	
270			add		#low(fontdata)	;
271			st		TRL				;
272			mov		#0,acc			;
273			addc	#high(fontdata)	;
274			st		TRH			;
275	
276			push	OCR			; OCR値を退避
277			mov		#osc_rc,OCR ; システムクロックを指定
278	
279			mov		#0,b		; キャラクタデータ読み出し用オフセット値
280			mov		#4,c		; ループカウンタ
281	loop1:
282			ld		b			; 1ライン目の表示データを読み出す
283			ldc					;
284			inc		b			; 読み出しデータのオフセットを +1
285			st		@r2			; 表示データを表示用RAMに転送
286			ld		r2			; 表示用RAMアドレス +6
287			add		#6			;
288			st		r2			;
289	
290			ld		b			; 2ライン目の表示データを読み出す
291			ldc					;
292			inc		b			; 読み出しデータのオフセットを +1
293			st		@r2			; 表示データを表示用RAMに転送
294			ld		r2			; 表示用RAMアドレス +10
295			add		#10			;
296			st		r2			;
297			
298			dec		c			; ループカウンタのデクリメント
299			ld		c			; 
300			bnz		loop1		; 8ライン分(4回)繰り返し
301			
302			pop		OCR			; OCR値を復帰
303			pop		PSW			; PSW値を復帰
304	
305			ret					; put_chara終わり
306	
307	
308	; *-------------------------------------------------------------------------*
309	; * キャラクタのビットイメージデータ										*
310	; *-------------------------------------------------------------------------*
311	fontdata:
312			db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;'0' 00 
313			db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;'1' 01
314			db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;'2' 02
315			db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;'3' 03
316			db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;'4' 04
317			db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;'5' 05
318			db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;'6' 06
319			db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;'7' 07
320			db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;'8' 08
321			db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;'9' 09		
322	
323	
324	; *-------------------------------------------------------------------------*
325	; *	ローバッテリ自動検出機能 ON												*
326	; *-------------------------------------------------------------------------*
327	BattChkOn:
328			push	PSW			; PSW値を退避
329	
330			clr1	PSW,1		; データRAMバンク0を選択
331			mov		#0,acc		; ローバッテリ検出をする(0)
332			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
333	
334			pop		PSW			; PSW値を復帰
335			ret					; BattChkOn終わり
336	
337	
338	; *-------------------------------------------------------------------------*
339	; *	ローバッテリ自動検出機能 OFF											*
340	; *-------------------------------------------------------------------------*
341	BattChkOff:
342			push	PSW			; PSW値を退避
343	
344			clr1	PSW,1		; データRAMバンク0を選択
345			mov		#0ffh,acc	; ローバッテリ検出をしない(0ffh)
346			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
347	
348			pop		PSW			; PSW値を復帰
349			ret					; BattChkOff終わり

6-9 汎用シリアルドライバ


ポート3割り込みを利用したバッファ付き汎用シリアルドライバを使った、シリアル送受信プログラムです。

このプログラムを2つのビジュアルメモリで実行させると、お互いにデータを送信/受信し、その内容をLCDに表示します。

メインルーチンでは、受信バッファをチェックしデータがある限り最優先で、受信データをLCDに表示します。バッファが空になると、送信するデータ(0〜99)を出力します。送信するデータは、ベースタイマー割り込みにより0.5秒に1回カウントアップされます。

128〜161行目のSioInitルーチンは、ビジュアルメモリの接続確認、インターフェイスの初期化に加え、バッファ(RAM)を初期化し、SIO割り込みを有効にしています。203〜245行目のSioGet1ルーチンは、受信バッファに溜っているデータを1バイト取り出します。

SIO割り込みを受けて動作するSIO受信ハンドラは、278〜317行目のint_SioRxルーチンです。受信したデータをバッファに溜めていきます。

注意

このサンプル同士で通信を行う場合は、データの取りこぼしはありませんが、連続したデータ転送を行う場合は、送信後一定時間のウェイトを置くなどしてください。

先のサンプル「シリアル通信(受信側)」にデータを送信すると、データの取りこぼしが発生し、うまく通信できません。

●GHEAD.ASM
001	chip	LC868700
002	world	external
003	; *-----------------------------------------------------*
004	; *	External header program Ver 1.00		*
005	; *					05/20-'98	*
006	; *-----------------------------------------------------*
007	
008	public	fm_wrt_ex_exit,fm_vrf_ex_exit
009	public	fm_prd_ex_exit,timer_ex_exit,_game_start,_game_end
010	other_side_symbol	fm_wrt_in,fm_vrf_in
011	other_side_symbol	fm_prd_in,timer_in,game_end
012	
013	extern	main			;ユーザープログラム側にあるシンボル
014	extern	int_BaseTimer		;ユーザープログラム側にあるシンボル
015	extern	int_SioRx		;ユーザープログラム側にあるシンボル
016	
017	; *-----------------------------------------------------*
018	; *	Vector table(?)					*
019	; *-----------------------------------------------------*
020	cseg
021	org	0000h
022	_game_start:
023	;reset:
024			jmpf	main		; main program jump
025	org	0003h
026	;int_03:
027			jmp	int_03
028	org	000bh
029	;int_0b:
030			jmp	int_0b
031	org	0013h
032	;int_13:
033			jmp	int_13
034	org	001bh
035	;int_1b:
036			jmp	int_1b
037	org	0023h
038	;int_23:
039			jmp	int_23
040	org	002bh
041	;int_2b:
042			jmp	int_2b
043	org	0033h
044	;int_33:
045			jmp	int_33
046	org	003bh
047	;int_3b:
048			jmp	int_3b
049	org	0043h
050	;int_43:
051			jmp	int_43
052	org	004bh
053	;int_4b:
054			jmp	int_4b
055	; *-----------------------------------------------------*
056	; *	interrupt programs				*
057	; *-----------------------------------------------------*
058	int_03:
059			reti
060	int_0b:
061			reti
062	int_13:
063			reti
064	int_23:
065			reti
066	int_2b:
067			reti
068	int_33:
069			reti
070	int_3b:
071			jmp		int_SioRx	; SIO受信割り込みハンドラ
072	
073	; *-----------------------------------------------------*
074	int_43:
075			reti
076	int_4b:
077			clr1	p3int,1		;interrupt flag clear
078			reti
079	
080	org	0100h
081	; *-----------------------------------------------------*
082	; *	flash memory write external program		*
083	; *-----------------------------------------------------*
084	fm_wrt_ex:
085			change	fm_wrt_in
086		fm_wrt_ex_exit:
087			ret
088	org	0110h
089	; *-----------------------------------------------------*
090	; *	flash memory verify external program		*
091	; *-----------------------------------------------------*
092	fm_vrf_ex:
093			change	fm_vrf_in
094		fm_vrf_ex_exit:
095			ret
096	
097	org	0120h
098	; *-----------------------------------------------------*
099	; *	flash memory page read external program		*
100	; *-----------------------------------------------------*
101	fm_prd_ex:
102			change	fm_prd_in
103		fm_prd_ex_exit:
104			ret
105	
106	org	0130h
107	; *-----------------------------------------------------*
108	; *	flash memory => timer call external program	*
109	; *-----------------------------------------------------*
110	int_1b:
111	timer_ex:
112			push	ie
113			clr1	ie,7		;interrupt prohibition
114			change	timer_in
115		timer_ex_exit:
116			call	int_BaseTimer ;(ユーザー側割り込み処理)
117			pop	ie
118			reti
119	
120	org	01f0h
121	_game_end:
122			change	game_end
123	end
●TIMER1.ASM
001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** シリアル通信サンプル3 (割り込み駆動受信バッファ付きシリアルドライバ) **
005	;
006	; ・16byte受信バッファ付きシリアル送受信通信ドライバと利用サンプル
007	; ・受信データを数値表示する
008	; ・一定期間ごとに単純なデータを送信する
009	;----------------------------------------------------------------------------
010	; 1.01 990208 SEGA Enterprises,LTD.
011	;----------------------------------------------------------------------------
012	
013	chip	LC868700			; チップの種類をアセンブラに指定
014	world	external			; 外部メモリ用プログラム
015	
016	public	main				; ghead.asm から参照されるシンボル
017	public	int_BaseTimer		; ghead.asm から参照されるシンボル
018	public	int_SioRx			; ghead.asm から参照されるシンボル
019	
020	extern	_game_end			; アプリケーション終了
021	
022	
023	; **** システム定数の定義 ***************************************************
024	
025									; OCR(発振制御レジスタ)設定値
026	osc_rc			equ 04dh		;	システムクロックに内蔵RC発振を指定
027	osc_xt			equ 0efh		;	システムクロックに水晶発振を指定
028	
029	LowBattChk		equ 06eh		; ローバッテリ検出フラグ(RAMバンク0)
030	
031	SioRxCueSize	equ 16			; シリアル受信バッファサイズ
032	
033	
034	; *** データセグメント ******************************************************
035	
036			dseg				; データセグメント開始
037	
038	r0:		ds		1			; 間接アドレッシングレジスタ r0
039	r1:		ds		1			; 間接アドレッシングレジスタ r1
040	r2:		ds		1			; 間接アドレッシングレジスタ r2
041	r3:		ds		1			; 間接アドレッシングレジスタ r3
042			ds		12			; その他のレジスタ
043	
044								; ** シリアルドライバ用 **
045	SioRxCueBehind:	ds	1		; 受信データ溜り量
046	SioRxCueRPnt:	ds	1		; 受信バッファ読み出しポイント
047	SioRxCueWPnt:	ds	1		; 受信バッファ書き込みポイント
048	SioRxCue:		ds	SioRxCueSize ; 受信バッファ
049	SioOverRun:		ds	1		; 受信オーバーランフラグ
050	
051								; ** 利用サンプル用ワーク **
052	bcount:	ds		1			; ベースクロックカウンタ
053	work1:	ds		1			; ワーク1
054	work2:	ds		1			; ワーク2
055	
056	work0:	ds		1			; ワーク(put2digit)
057	
058	
059	; *** コードセグメント ******************************************************
060	
061			cseg				; コードセグメント開始
062			
063	; *-------------------------------------------------------------------------*
064	; * シリアル通信ドライバ使用サンプル										*
065	; * 一定期間後とに単純なデータを送信する。									*
066	; * 受信したデータは順次LCDに数値表示する。									*
067	; *-------------------------------------------------------------------------*
068	main:
069			mov		#0,bcount
070			mov		#0,work1		; 送信データの初期値
071			clr1	P3INT,0			; P3割り込みをマスク
072			call	cls				; LCDを消去する
073			call	BattChkOff		; ローバッテリ自動検出機能 OFF
074			call	SioInit			; シリアル通信の初期化
075			bnz		finish			; VM が接続されていなければ終了
076	
077	stlp1:
078									; *** 受信データがあれば表示 ***
079			call	SioGet1			; 1byte受信
080			be		#0ffh,stnx1		; 受信データがなければスキップ		
081			bz		stnx3			; 正常受信データありのときstnx3へ
082	error:	br		finish			; 各種エラーを検出したとき強制終了
083	stnx3:
084			ld		b				; acc <- b 受信データ
085			mov		#0,c			; 表示座標(水平)
086			mov		#0,b			; 表示座標(垂直)
087			call	put2digit		; LCDに数値表示
088			br		stlp1			; 受信データがある限り優先して繰り返す
089	stnx1:							;
090	
091			set1	pcon,0			; 次の割り込みまで待つ
092	
093									; *** 一定期間毎に単純なデータ送信する ***
094			ld		bcount			; ベースタイマのカウンタ値
095			be		work2,stnx4		; 前回と同じならば送信しない
096			st		work2			; work2を更新
097								
098			ld		work1			; 送信用データを取り出す
099			call	SioPut1			; 送信する
100	
101			inc		work1			; 送信用データの更新
102			ld		work1			; (0〜99 の値を次々に送信する)
103			bne		#100,stnx2		;
104			mov		#0,work1		;
105	stnx2:							;
106	stnx4:
107					
108									; ** [M](モード)ボタンチェック **
109			ld		P3
110			bn		acc,6,finish	; [M]ボタンが押されていたらアプリ終了
111	
112			jmp		stlp1			; 繰り返す
113	
114	finish:							; ** アプリケーション終了処理 **
115			call	SioEnd			; シリアル通信終了処理
116			call	BattChkOn		; ローバッテリ自動検出機能 ON
117			jmp		_game_end		; アプリケーション終了
118	
119	; *=========================================================================*
120	; ***** 簡易シリアル通信ドライバ										*****
121	; *=========================================================================*
122	
123	; *-------------------------------------------------------------------------*
124	; * シリアル通信の初期化													*
125	; *																			*
126	; * システムクロックが水晶モードであることを前提としている。				*
127	; *-------------------------------------------------------------------------*
128	SioInit:
129										; **** VM同士の接続を確認 ****
130			ld		P7					; 接続状態の確認
131			and		#%00001101			; P70, P72, P73 をチェック
132			be		#%00001000,next3	; P70=0, P72=0, P73=1 か判定し
133										; 接続されているときnext3へ
134			mov		#0ffh,acc			; 接続されていないとき acc=0ffh で異常終了
135			ret							; SioInit終わり
136	next3:
137	
138										; **** シリアル通信の初期化 ****
139			mov		#0,SCON0			; LSBを先頭に出力するよう指定
140			mov		#0,SCON1			; LSBを先頭に入力するよう指定
141			mov		#088h,SBR			; 転送レートを設定する
142			clr1	P1,0				; P10ラッチをクリア(P10/SO0)
143			clr1	P1,2				; P12ラッチをクリア(P12/SCK0)
144			clr1	P1,3				; P13ラッチをクリア(P13/SO1)
145	
146			mov		#%00000101,P1FCR	; 端子機能設定
147			mov		#%00000101,P1DDR	; 端子機能設定
148	
149			mov		#0,SBUF0			; 転送バッファクリア
150			mov		#0,SBUF1			; 転送バッファクリア
151	
152			mov		#0,acc
153			st		SioRxCueBehind		; 受信データ溜り量リセット
154			st		SioRxCueRPnt		; 受信バッファ読み出しポイント
155			st		SioRxCueWPnt		; 受信バッファ書き込みポイント
156			st		SioOverRun			; 受信オーバーランフラグのリセット
157	
158			set1	SCON1,0				; 受信側転送終了割り込み有効
159			set1	SCON1,3				; 受信待機
160			
161			ret							; SioInit終わり
162	
163	
164	; *-------------------------------------------------------------------------*
165	; * シリアル通信の終了														*
166	; *-------------------------------------------------------------------------*
167	SioEnd:								; **** シリアル通信終了処理 ****
168	
169			mov		#0,SCON0			; SCON0 = 0
170			mov		#0,	SCON1			; SCON1 = 0
171			mov		#0bfh,P1FCR			; P1FCR = 0bfh
172			mov		#0a4h,P1DDR			; P1DDR = 0a4h
173	
174			ret							; SioEnd終わり
175	
176	
177	; *-------------------------------------------------------------------------*
178	; * 1byte送信する															*
179	; *																			*
180	; * 入力 acc: 送信データ													*
181	; *-------------------------------------------------------------------------*
182	SioPut1:
183			push	acc					; 送信データを退避
184	splp1:	ld		SCON0				; 転送中なら転送終了まで待つ
185			bp		acc,3,splp1 		;
186			pop		acc					; 送信データ復帰
187			
188			st		SBUF0				; 転送するデータをセットする
189			set1	SCON0,3				; 転送開始
190	
191			ret							; SioPut1終わり
192	
193	
194	; *-------------------------------------------------------------------------*
195	; * 受信バッファから1byte読み込む(非同期受信)								*
196	; *																			*
197	; * 出力 acc: 0=正常終了													*
198	; *           0ffh=受信データなし											*
199	; *           0feh=バッファ・オーバーフロー									*
200	; *           0fdh=オーバーラン・エラー										*
201	; *        b: 受信したデータ(正常終了時のみ有効)							*
202	; *-------------------------------------------------------------------------*
203	SioGet1:
204										; ** 溜まっているデータ量をチェック **
205			ld		SioRxCueBehind		; 溜まり量
206			bnz		sgnx1				; 溜まり量 != 0 のとき
207			mov		#0ffh,acc			; 溜まり量 == 0 のとき..
208			ret							;   acc = 0ffh で返る (受信データなし)
209	sgnx1:
210										; ** バッファオーバーフローの検出 **
211										; SioRxCueBehind - SioRxCueSize
212			be		#SioRxCueSize,sgnx3	; SioRxCueBehind == SioRxCueSize
213			bp		PSW,7,sgnx3			; SioRxCueBehind < SioRxCueSize
214										; SioRxCueBehind >  SioRxCueSize
215			mov		#0feh,acc			; バッファ量を越えてしまったとき
216			ret							;   acc = 0feh で返る (Buffer overflow)
217	sgnx3:
218										; ** オーバーランエラーの検出 **
219			ld		SioOverRun			; オーバーランフラグ
220			bz		sgnx4				; 検出されていないとき
221			mov		#0fdh,acc			; 検出されているとき
222			ret							;   acc = 0fdh で返る (Overrun error)
223	sgnx4:
224			
225			dec		SioRxCueBehind		; dec 溜まり量
226			
227										; ** 受信データ取り出しポイントの計算
228			ld		SioRxCueRPnt		; r0 = SioRxCue + SioRxCueRPnt
229			add		#SioRxCue			;
230			st		r0					;
231			
232			inc		SioRxCueRPnt		; inc データ取り出しポイント
233			
234										; ** 取り出しポイント==バッファサイズ なら
235										; ** 取り出しポイント=0にリセットする
236			ld		SioRxCueRPnt
237			bne		#SioRxCueSize,sgnx2	; SioRxCueRPnt != SioRxCueSize のとき
238			mov		#0,SioRxCueRPnt		; SioRxCueRPnt == SioRxCueSize のとき
239	sgnx2:
240	
241			ld		@r0					; 入力データをaccに取り込み..
242			st		b					; bへ
243			mov		#0,acc				; acc = 0 (正常終了 - データあり)
244			
245			ret							; SioGet1終わり
246	
247	
248	; *-------------------------------------------------------------------------*
249	; * 受信バッファから1byte読み込む											*
250	; * (受信データが無い場合はデータがくるまで待つ)							*
251	; *																			*
252	; * 出力 acc: 0=正常終了													*
253	; *           0feh=バッファ・オーバーフロー									*
254	; *           0fdh=オーバーラン・エラー										*
255	; *        b: 受信したデータ(正常終了時のみ有効)							*
256	; *-------------------------------------------------------------------------*
257	SioGet1W:
258			call	SioGet1				; 非同期受信
259			be		#0ffh,SioGet1W		; データがくるまで待つ
260			
261			ret							; SioGet1W終わり
262	
263	
264	; *-------------------------------------------------------------------------*
265	; * 受信バッファに溜まっているデータ量を取得する							*
266	; *																			*
267	; * 出力 acc: データ量(bytes)												*
268	; *-------------------------------------------------------------------------*
269	SioGetRxLen:
270			ld		SioRxCueBehind		; 溜まり量
271			
272			ret							; SioGetRxLen終わり
273	
274	
275	; *-------------------------------------------------------------------------*
276	; * SIO受信割り込みハンドラ													*
277	; *-------------------------------------------------------------------------*
278	int_SioRx:	
279			push	acc					; 使用レジスタ退避
280			push	PSW					;
281			set1	PSW,1				; データRAMバンク1を選択
282			push	r0					; レジスタ退避
283	
284										; ** 書き込みポイントの計算 **
285			ld		SioRxCueWPnt		; r0 = SioRxCue + SioRxCueWPnt
286			add		#SioRxCue			;
287			st		r0					;
288			
289			ld		SBUF1				; 受信データを読み込む
290			st		@r0					; バッファに書き込む
291	
292			inc		SioRxCueWPnt		; 書き込みポイント++
293	
294										; ** 書き込みポイントがバッファサイズに
295										; ** 達したらポイントをリセット
296			ld		SioRxCueWPnt		;
297			bne		#SioRxCueSize,isnx1	;
298			mov		#0,SioRxCueWPnt		;
299	isnx1:
300	
301			inc		SioRxCueBehind		; データ溜まり量++
302	
303			clr1	SCON1,1				; 転送終了フラグをリセット
304			
305										; ** オーバーランエラーのチェック **
306			bn		SCON1,6,isnx2		; オーバーランしていないならisnx2
307			mov		#1,SioOverRun		; オーバーランしている→フラグセット
308			clr1	SCON1,6				; オーバーランフラグをリセット
309	isnx2:
310			
311			set1	SCON1,3				; 次の転送を開始
312	
313			pop		r0					; 使用レジスタ復帰
314			pop		PSW					;
315			pop		acc					;
316			
317			reti						; int_SioRx終わり
318	
319	
320	; *-------------------------------------------------------------------------*
321	; * 2桁の数値を表示する														*
322	; * 入力 acc : 数値															*
323	; *        c : 文字水平位置												  	*
324	; *        b : 文字垂直位置												  	*
325	; *-------------------------------------------------------------------------*
326	put2digit:
327			push	b			; 座標データを退避
328			push	c			;
329			st		c			; 10の位と1の位の値をそれぞれ計算
330			xor		a			; ( acc = acc/10, work0 = acc mod 10 )
331			mov		#10,b		;
332			div					;
333			ld		b			;
334			st		work0		; 1の位の計算結果をwork0に保存
335			ld		c			;
336			pop		c			; 座標値を(c.b)に復帰
337			pop		b			; 
338			push	b			; また退避
339			push	c			;
340			call	putch		; 10の位を表示
341			ld		work0		; 1の位の値を読み込み
342			pop		c			; 座標値を(c,b)に復帰
343			pop		b			; 
344			inc		c			; 表示座標を右へ
345			call	putch		; 1の位を表示
346	
347			ret					; put2digit終わり
348			
349	
350	; *-------------------------------------------------------------------------*
351	; * LCD表示イメージを消去する												*
352	; *-------------------------------------------------------------------------*
353	cls:
354			push	OCR			; OCR値を退避
355			mov		#osc_rc,OCR ; システムクロックを指定
356	
357			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
358			call	cls_s		; そのバンク内のデータをクリア
359	
360			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
361			call	cls_s		; そのバンク内のデータをクリア
362			pop		OCR			; OCR値を復帰
363			
364			ret					; cls終わり
365			
366	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
367			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
368			mov		#80h,b 		; ループカウンタbにループ数をセット
369	loop3:
370			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
371			inc		r2			;
372			dbnz	b,loop3		; bが0になるまで繰り返す
373			
374			ret					; cls_s終わり
375			
376	
377	; *-------------------------------------------------------------------------*
378	; * 指定位置に1キャラクタ表示する											*
379	; * 入力 acc : キャラクタコード												*
380	; *        c : 文字水平位置												  	*
381	; *        b : 文字垂直位置												  	*
382	; *-------------------------------------------------------------------------*
383	putch:
384			push	XBNK
385			push	acc
386			call	locate		; 座標から表示RAMのアドレスを計算
387			pop		acc
388			call	put_chara	; 1キャラクタ表示する
389			pop		XBNK
390			
391			ret					; putch終わり
392			
393	
394	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
395			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
396			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
397	
398								; *** 表示用RAMバンクアドレスの判断 ***
399			ld		b			; b>=2 のとき next1 へ
400			sub		#2			;
401			bn		PSW,7,next1	;
402			
403			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
404			br		next2
405	next1:
406			st		b
407			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
408	next2:
409	
410								; *** 表示指定位置のRAMアドレス計算 ***
411			ld		b			; b * 40h + c + 80h
412			rol					;
413			rol					;
414			rol					;
415			rol					;
416			rol					;
417			rol					;
418			add		c			;
419			add		#80h		;
420			st		r2			; RAMアドレスをr2に格納
421					
422			ret					; locate終わり
423	
424	
425	put_chara:
426			push	PSW			; PSW値を退避
427			set1	PSW,1		; データRAMバンク1を選択
428	
429								; *** キャラクタデータアドレスの計算 ***
430			rol					; (TRH,TRL) = acc*8 + fontdata
431			rol					;
432			rol					;	
433			add		#low(fontdata)	;
434			st		TRL				;
435			mov		#0,acc			;
436			addc	#high(fontdata)	;
437			st		TRH			;
438	
439			push	OCR			; OCR値を退避
440			mov		#osc_rc,OCR ; システムクロックを指定
441	
442			mov		#0,b		; キャラクタデータ読み出し用オフセット値
443			mov		#4,c		; ループカウンタ
444	loop1:
445			ld		b			; 1ライン目の表示データを読み出す
446			ldc					;
447			inc		b			; 読み出しデータのオフセットを +1
448			st		@r2			; 表示データを表示用RAMに転送
449			ld		r2			; 表示用RAMアドレス +6
450			add		#6			;
451			st		r2			;
452	
453			ld		b			; 2ライン目の表示データを読み出す
454			ldc					;
455			inc		b			; 読み出しデータのオフセットを +1
456			st		@r2			; 表示データを表示用RAMに転送
457			ld		r2			; 表示用RAMアドレス +10
458			add		#10			;
459			st		r2			;
460			
461			dec		c			; ループカウンタのデクリメント
462			ld		c			; 
463			bnz		loop1		; 8ライン分(4回)繰り返し
464			
465			pop		OCR			; OCR値を復帰
466			pop		PSW			; PSW値を復帰
467	
468			ret					; put_chara終わり
469	
470	
471	; *-------------------------------------------------------------------------*
472	; * キャラクタのビットイメージデータ										*
473	; *-------------------------------------------------------------------------*
474	fontdata:
475			db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;0
476			db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;1
477			db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;2
478			db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;3
479			db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;4
480			db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;5
481			db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;6
482			db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;7
483			db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;8
484			db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;9
485	          
486	
487	; *-------------------------------------------------------------------------*
488	; *	ローバッテリ自動検出機能 ON												*
489	; *-------------------------------------------------------------------------*
490	BattChkOn:
491			push	PSW					; PSW値を退避
492			clr1	PSW,1				; データRAMバンク0を選択
493			
494			mov		#0,LowBattChk		; ローバッテリ検出をする(0)
495	
496			pop		PSW					; PSW値を復帰
497			ret							; BattChkOn終わり
498	
499	
500	; *-------------------------------------------------------------------------*
501	; *	ローバッテリ自動検出機能 OFF											*
502	; *-------------------------------------------------------------------------*
503	BattChkOff:
504			push	PSW					; PSW値を退避
505			clr1	PSW,1				; データRAMバンク0を選択
506			
507			mov		#0ffh,LowBattChk	; ローバッテリ検出をしない(0ffh)
508	
509			pop		PSW					; PSW値を復帰
510			ret							; BattChkOff終わり
511	
512	
513	; *-------------------------------------------------------------------------*
514	; *	ベースタイマ割り込みハンドラ											*
515	; *-------------------------------------------------------------------------*
516	int_BaseTimer:
517			clr1	btcr,1				; ベースタイマ割り込み要因クリア
518			inc		bcount				; カウンタ++
519			ret							; ユーザー側割り込み処理終了

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		

6-11 ローバッテリ検出とデータ退避


ビジュアルメモリは、ローバッテリを検出するとその旨のメッセージを表示し、自動的にスリープ状態になる機能を内蔵しています。このサンプルは、アプリケーションが独自にローバッテリを検知し、RAMのデータをフラッシュメモリに退避するものです。

このプログラムの本質は、115〜124行目のローバッテリ検出ルーチンです。ポート7のローバッテリフラグをチェックします。

ポート7割り込みを利用することも可能ですが、割り込み処理ルーチン内でシステムBIOSを呼び出さないように配慮してください。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** ローバッテリ検出とデータ退避サンプル1 **
005	;
006	; ローバッテリ状態を検出して、必要なデータをフラッシュメモリに退避する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	
016	extern	_game_end			; ghead.asm への参照シンボル
017	extern	fm_wrt_ex, fm_vrf_ex, fm_prd_ex	; ghead.asm への参照シンボル
018	
019	
020	; **** システム定数の定義 ***************************************************
021	
022								; OCR(発振制御レジスタ)設定値
023	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定(1/12)
024	osc_rcfw	equ 0cdh		;	システムクロックに内蔵RC発振を指定(1/6)
025	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
026	
027	LowBattChk	equ 06eh		; ローバッテリ検出フラグ(RAMバンク0)
028	
029	fmflag		equ 07ch		; フラッシュメモリ書き込み終了検出方式
030	fmbank		equ 07dh		; フラッシュメモリバンク切替え
031	fmadd_h		equ 07eh		; フラッシュメモリ上位アドレス
032	fmadd_l		equ 07fh		; フラッシュメモリ下位アドレス
033	
034	fmbuff		equ 080h		; フラッシュメモリ読み書き用バッファ先頭
035	
036	; *** データセグメント ******************************************************
037	
038			dseg				; データセグメント開始
039	
040	r0:		ds		1			; 間接アドレッシングレジスタ r0
041	r1:		ds		1			; 間接アドレッシングレジスタ r1
042	r2:		ds		1			; 間接アドレッシングレジスタ r2
043	r3:		ds		1			; 間接アドレッシングレジスタ r3
044			ds		12			; その他のシステム予約レジスタ
045	
046	
047	; *** コードセグメント ******************************************************
048	
049			cseg				; コードセグメント開始
050	
051	; *-------------------------------------------------------------------------*
052	; * ユーザープログラム														*
053	; *-------------------------------------------------------------------------*
054	main:
055			call	cls			; LCD表示イメージを消去する
056	
057	loop0:						; テストメインループ先頭
058	
059			; アプリケーションメイン処理
060	
061								; ** [M](モード)ボタンチェック **
062			ld		P3
063			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
064	
065								; ** バッテリ状態チェック **
066			call	ChkBatt		; バッテリの状態をチェック
067			bz		loop0		; acc=0 ならバッテリ正常でループ
068	
069								; **  ローバッテリ 処理 **
070			call	prepare		; テスト退避用のデータを用意する。
071								; 実際のアプリケーションでは退避すべきデータを
072								; 収集してフラッシュROM書きこみ用のバッファに配置
073								; するようにする。
074	
075			call	WriteData	; フラッシュメモリへバッファに用意した(退避すべき)
076								; データを書きこむ
077	
078	finish:						; ** アプリケーション終了処理 **
079			jmp		_game_end	; アプリケーション終了
080	
081			
082	; *-------------------------------------------------------------------------*
083	
084	prepare:					; **** テスト退避用のデータを準備する ****
085								; fmbuff に 10h〜8fh の 128byte のデータを用意
086	
087			push	PSW			; PSW値を退避
088			set1	PSW,1		; データRAMバンク1を選択
089	
090			mov		#fmbuff,r0	; 読み書きバッファのアドレスを r0 に
091			mov		#128,c		; ループカウンタ(128回)
092			mov		#010h,b		; 書き込むデータの初期値
093	loop4:
094			ld		b			; データをバッファに置く
095			st		@r0			;
096		
097			inc		b			; 書き込みテスト用データを変える
098		
099			inc		r0			; バッファのアドレスをインクリメント
100		
101			dec		c			; ループカウンタのデクリメント
102			ld		c
103			bnz		loop4		; 128回の繰り返し
104	
105			pop		PSW			; PSW値を復帰
106	
107			ret					; prepare 終わり
108	
109	
110	; *-------------------------------------------------------------------------*
111	; * ローバッテリ状態を検出する											*
112	; * 出力: acc = 0    : 電池状態正常											*
113	; *       acc = 0ffh : ローバッテリ										*
114	; *-------------------------------------------------------------------------*
115	ChkBatt:
116			ld		P7			; P71の状態をチェックする
117			bn		acc,1,next3	; 電池ないとき分岐
118	
119								; ** 電池ある **
120			mov		#0,acc		; acc = 0
121			ret					; ChkBatt終わり。電池ありなら acc=0 として返る
122	
123	next3:						; ** 電池なし **
124			mov		#0ffh,acc	; acc = 0ffh
125			ret					; ChkBatt終わり。電池なしなら acc=0ffh として返る
126	
127	
128	; *-------------------------------------------------------------------------*
129	; * バッファのデータをフラッシュメモリへ書きこむ							*
130	; *-------------------------------------------------------------------------*
131	WriteData:					; **** フラッシュメモリへの書き込み ****
132								
133			push	PSW			; PSW値を退避
134			set1	PSW,1		; データRAMバンク1を選択
135	
136			mov		#0,fmbank	; フラッシュメモリのバンク指定 = 0		
137			mov		#high(fmarea),fmadd_h	; 書き込み先アドレス(上位)
138			mov		#low(fmarea),fmadd_l	; 書き込み先アドレス(下位)		
139			mov		#0,fmflag	; トクルビット方式により終了を検出
140			
141			clr1	PSW,1		; データRAMバンク0を選択
142			mov		#0ffh,acc	; ローバッテリ検出をしない(0ffh)
143			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
144	
145			pop		PSW			; PSW値を復帰
146	
147			push	OCR			; OCR値を退避
148			mov		#osc_rcfw,OCR ; システムクロックを指定(RC)
149			call	fm_wrt_ex	; BIOS「フラッシュメモリへの書き込み」
150			pop		OCR			; OCR値を復帰
151	
152			push	PSW			; PSW値を退避
153			clr1	PSW,1		; データRAMバンク0を選択
154			mov		#0,acc		; ローバッテリ検出をする(0)
155			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
156			pop		PSW			; PSW値を復帰
157	
158			ret					; WriteData終わり
159	
160	
161	; *-------------------------------------------------------------------------*
162	; * LCD表示イメージを消去する												*
163	; *-------------------------------------------------------------------------*
164	cls:
165			push	OCR			; OCR値を退避
166			mov		#osc_rc,OCR ; システムクロックを指定
167	
168			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
169			call	cls_s		; そのバンク内のデータをクリア
170	
171			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
172			call	cls_s		; そのバンク内のデータをクリア
173			pop		OCR			; OCR値を復帰
174			
175			ret					; cls終わり
176			
177	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
178			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
179			mov		#80h,b 		; ループカウンタbにループ数をセット
180	loop3:
181			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
182			inc		r2			;
183			dbnz	b,loop3		; bが0になるまで繰り返す
184			
185			ret					; cls_s終わり
186			
187	
188	; *-------------------------------------------------------------------------*
189	; * データ保存用フラッシュメモリ領域										*
190	; *-------------------------------------------------------------------------*
191			org ((*-1) land 0ff80h) + 80h		; 128byte アライン
192	fmarea:
193			; 128byte フラッシュメモリ領域を確保する
194			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
195			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
196			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
197			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
198			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
199			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
200			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
201			db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
202	
203	end		

[]   [INDEX]

(C)SEGA ENTERPRISES, LTD., 1998