第6章 サンプルプログラムリスト |
ここでは、ビジュアルメモリSDKに付属のサンプルプログラムを掲載します。
インフォメーションフォークのソースファイル“IFORK.ASM”の説明、“GHEAD.ASM”の詳細は割愛します。
![]() すべてのサンプルプログラムは、タブ(09H)を4(バイト)にしてご覧ください。 |
このサンプルでは、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
このサンプルでは、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
ベースタイマーからかかる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
●B_TIMER1.ASM001 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
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 ; (ユーザー側)割り込み処理終了
ビジュアルメモリのボタン押下状態(リセットボタンと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
高い音(約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
タイマー0を使って1秒ごとの割り込みを発生させます。割り込みが発生したことは、音で知らせます。
このプログラムの本質は、78〜93行目のT0Mode2Initルーチンです。タイマー0のモード2、プリスケーラ付き16ビットカウンタを利用します。タイマーには32KHzが入るので、それをプリスケーラおよびカウンタで約1秒ごとにオーバーフローを起こすように設定します。
タイマー0はオーバーフローで割り込みを発生するので、その割り込みハンドラを用意します。割り込みハンドラ内では、カウントアップを行い、割り込み要因フラグを0にリセットして、割り込み処理を終了します。
メインルーチンでは、カウンタの値が偶数か奇数かを判定し、高い音と低い音を交互に出力します。61行目では、CPUをHALTモードにし、割り込みが発生するまで動作を停止します。タイマー0割り込みやポート3割り込みが発生すると、次の行から動作を開始します。 ●GHEAD.ASM
●TIMER1.ASM001 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
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
シリアルインターフェイスを使って、0〜99のデータを送信します。
![]() シリアル通信は、水晶発振で動作させてください。 |
受信は、次に掲載されいる「シリアル通信(受信側)」で行ってください。
53行目ではローバッテリ自動検出を禁止しています。実体は158行目以降のBattChkOnとBattChkOffです。
56行目では、シリアルインターフェイスの初期化を行っています。初期化の実体は95行目以降のルーチンです。非常に手間がかかるので、このロジックをそのままコピーして利用することをお勧めします。
初期化を行った後は、0.5秒ごとに発生するベースタイマー割り込みでカウンタをインクリメントします。このカウンタの数値をシリアルインターフェイスで送信します。
MODEボタンによりプログラムが中断されると、シリアルインターフェイスを規定の値に書き戻し(126行目からのSioEndルーチン)、ローバッテリ自動検出を有効にしてプログラムを終了します。 ●GHEAD.ASM
●TIMER1.ASM001 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
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 ; ユーザー側割り込み処理終了
シリアルインターフェイスを使って、データを受信します。
このプログラムは、シリアル通信の本質を説明するため、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終わり
ポート3割り込みを利用したバッファ付き汎用シリアルドライバを使った、シリアル送受信プログラムです。
このプログラムを2つのビジュアルメモリで実行させると、お互いにデータを送信/受信し、その内容をLCDに表示します。
メインルーチンでは、受信バッファをチェックしデータがある限り最優先で、受信データをLCDに表示します。バッファが空になると、送信するデータ(0〜99)を出力します。送信するデータは、ベースタイマー割り込みにより0.5秒に1回カウントアップされます。
128〜161行目のSioInitルーチンは、ビジュアルメモリの接続確認、インターフェイスの初期化に加え、バッファ(RAM)を初期化し、SIO割り込みを有効にしています。203〜245行目のSioGet1ルーチンは、受信バッファに溜っているデータを1バイト取り出します。
SIO割り込みを受けて動作するSIO受信ハンドラは、278〜317行目のint_SioRxルーチンです。受信したデータをバッファに溜めていきます。
![]() このサンプル同士で通信を行う場合は、データの取りこぼしはありませんが、連続したデータ転送を行う場合は、送信後一定時間のウェイトを置くなどしてください。 先のサンプル「シリアル通信(受信側)」にデータを送信すると、データの取りこぼしが発生し、うまく通信できません。 |
●TIMER1.ASM001 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
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 ; ユーザー側割り込み処理終了
フラッシュメモリへの書き込み、読み込み、ベリファイを行い、各フェーズが終了するごとに“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
ビジュアルメモリは、ローバッテリを検出するとその旨のメッセージを表示し、自動的にスリープ状態になる機能を内蔵しています。このサンプルは、アプリケーションが独自にローバッテリを検知し、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