VRAMについて説明します。
MSXにはRAMとVRAMがついています。
普通にBASICを書いた場合、プログラムはRAMに入ります。
VRAMはどんなデータが入るのかといいますと、
画像についてのデータが入ります!
僕が小学生の頃は、恥ずかしながら、VRAMを知りませんでした^^;
BASICを書く場合、VRAMを知らなくても、ある程度書けてしまうんですよね〜。
でも地形ブロックとの当たり判定をする場合に、
必ず、
VRAMの知識が必要です!
(だから小学生の頃は、地形(壁)があるゲームは作れませんでした( ̄^ ̄) )
その他、MSX BASICの基本のページについての
目次はこちら
MSXの、テレビに写す映像は、
CPU -> VDP ->表示
こういう感じで表示されます。
VDP(ブイディーピー)というのはビデオプロセッサのことです。
CPUはVDPに指示をだし、VDPが画像を表示します。
そのVDPは、VRAM(ブイラム: ビデオラム)のデータをチェックしながら、
画像を表示します。
(VRAMがRAMの他に装備されています。MSX1の場合は16Kバイトです。)
MSX1は、CPUがZ80A、
VDPは、TMS9918A
(TMS9918とTMS9918Aは 違っていて、MSXはTMS9918Aだそうです。訂正させていただきます。ご指摘ありがとうございます^ ^)
TMS9918(TMS9918A)という名前は
よく出てきます。
みんな、TMS9918(TMS9918A)と
いいたいのです^^
なんかかっこいいですよね!
ちなみにMSX1でRGB21ピン端子を備えた機種は、
TMS9928(TMS9928A?)だったりします。
(基本的には同じ。TMS9918AにはできないRGBの出力ができます)
VRAMは、RAMなので、データが入っています。
番地もあります。
番地など、RAMについての説明を先に読んで頂くと、よく分かります^^
どの番地に、どんなデータが入っているかで、
表示される画像が変わります。
大雑把にいいますと、
・文字の形のデータ
・画面のどこに何を表示するかのデータ
(1画面は、32x24文字表示なので、これだけの文字が順番に書いてあります)
・スプライトの座標とか色のデータ(8x8ドットのものが、128個分)
・文字の色データ
・スプライトの形のデータ
などとなります。
0000H番地 ~ 07FFH番地(Hは16進数のことです)は、
文字の形のデータ、などと
決まっています。
(ちなみに上の番地を10進数で書くと、
0番地 ~ 2047番地は文字の形のデータとなります)
ちなみに数字というのは、16進数、10進数、2進数と表現方法を
かえることができます。
07FF(16進数表現) = 2047 (10進数表現) = 11111111 (2進数表現)
全部同じ数字です。
16進数、10進数、2進数については、こちらに説明しています。
MSX BASIC 基礎その16 初心者のためのMSXのRAM(メモリ)についての説明! - ニャオニャオ21世紀
このようにVRAMの内容は、決められています。
VRAMマップといいます^^
SCREEN 0、SCREEN 1、SCREEN 2、SCREEN 3と
画面モードによって、
VRAMマップが少し違ってきます。
スクリーンモードによって、
文字の形データが3倍の大きさになったり、
文字の色データが192倍になっていたり(°▽°)
します。
ゲームによく使われるSCREEN1、2のVRAMマップについて説明します。
ネットでMSXのハードやソフト、雑誌などを買うならこちら
何かあたらしいものが入荷しているかもしれません^^
SCREEN1のVRAMマップ(構成)
SCREEN1のVRAMマップ
0000H番地〜 キャラクターパターンジェネレータ
1800H番地〜 パターン名称テーブル
1B00H番地〜 スプライトアトリビュート
2000H番地〜 カラー
2020H番地〜 パレット
3800H番地〜 スプライトパターンジェネレータ
VRAMは16Kバイト(4000H)
キャラクターパターンジェネレータ
キャラクターパターンジェネレータ
0000H番地 ~ 07FFH番地(16進数)
(10進数だと0000番地 ~ 2047番地)
大きさ:800Hバイト(10進数だと2048バイト)
(雑誌のMSXFANなどのBASICプログラムなんかだと
VRAMの番地を16進数で書いてあったり、10進数で書いてあったりします。
どちらでも同じです。分かりやすい方でどうぞ( ・∇・)
でも一般的には16進数の方が多いですかねぇ^^)
パターンジェネレータというのは、文字の形のデータのことを表しています。
VRAMの一番最初の番地のデータは、文字の形についてなんです^^
なんで文字の形のデータが入っているの?と思う人もいるかもしれません。
MSXは文字の形を変えることでゲームの地形(壁)やバックの絵を表現しているのです。
例えば、
このように#という文字を使って、
迷路を書いたとします。
VRAMの中の、文字の形のデータを書き換えてやると、
このようにすることができます。
(色は変わりません、ちょうどいい画像がなかったので^^;)
MSXの文字は256文字あります。
SCREEN1のパターンジェネレータのデータの大きさは、
800H (10進数で2048バイト)です。
じつは文字の形には、1文字あたり、8バイト使われています。
文字は8x8ドットなので。
(256文字 * 8バイト = 2048バイト)
そのあたりの説明はこちらをご覧ください。
MSX BASICの基礎その4 文字の形をブロックの絵に変える方法。出来ると一番楽しいところ! - ニャオニャオ21世紀
パターン名称テーブル
パターン名称テーブル
1800H番地 ~ 1AFF番地 (16進数)
(10進数では6144番地 ~ 6911番地)
大きさ:300Hバイト(10進数では、768バイト)
パターン名称というのは、画面構成のデータが入っています。
MSXは、1画面、32x24文字の表示ができます。
(横32文字 x 縦24文字)
画面の構成データというのはどういう意味かといいますと、
画面に表示されるデータがまるまる入っているのです。
こういう画面が表示されているとします。
1800H番地 ... A
1801H番地 ... B
1802H番地 ... C
1803H番地 ... D
~~
180AH番地 ... K
~~~
VRAMにはこのように入っています。(パターン名称)
仮に、画面がこのように変わったとします。
そうすると、このようになります。
1800H番地 ... #
1801H番地 ... #
1802H番地 ... #
1803H番地 ... #
~~
MSXの画面の左上のアドレスが&h1800で、
右に1つずつずれていき(次は&h1801に)、
右端(x=32)まできたら、ひとつ下にいきます。
座標でいうと(X,Y)=(1,1)が、&h1821 (=&h1800+33)
となります。
画面座標のアドレスはこのように算出できます。
&h1800+Y座標*32+X座標
(この式は、&h1800は16進数、Y座標以降は10進数です^^)
例えば
これを利用すると、
画面を表示するときに、LOCATE(座標を設定する命令)とPRINT文を
使わなくても画面に文字を表示することができます。
LOCATE 5,10:PRINT"A"は、
VPOKE &h1800+10*32+5,65
と同じです。
(Aはアスキーコードで65)
(VPOKEは、指定のVRAMアドレスにデータを書く命令、
65はAのアスキーコード:文字ナンバー。)
ちなみにVPEEKはVRAMの値を読む命令。PRINT VPEEK(&H1800)などと使います。
面白いですね〜(๑╹ω╹๑ )
マップを描くときなんかにいいですね^^
(LOCATEだと一番右下(32,24)に表示をすると改行されてしまうので、
このVRAMの方法をとるといいかもしれません。)
ただ色々検証してみると、マップを描くときは、
10 SCREEN1,3:WIDTH32
20 LOCATE 0,0:PRINT"################################"
30 LOCATE 0,1:PRINT"# #"
40 LOCATE 0,2:PRINT"# #"
50 LOCATE 0,3:PRINT"# # ######### ############ #"
60 LOCATE 0,4:PRINT"# # # # #"
70 LOCATE 0,5:PRINT"# # # # #"
80 LOCATE 0,6:PRINT"# ######### # ############ #"
90 LOCATE 0,7:PRINT"# # # # #"
100 LOCATE 0,8:PRINT"# # # # # #"
110 LOCATE 0,9:PRINT"# ## ##### # # ### # #"
120LOCATE 0,10:PRINT"# ## ##### # # ### # #"
130LOCATE 0,11:PRINT"# ## ##### # # # ### # #"
140LOCATE 0,12:PRINT"# ## ##### # # # #"
150LOCATE 0,13:PRINT"# # # # #"
160LOCATE 0,14:PRINT"# # # ######### #"
170LOCATE 0,15:PRINT"# ## ######## # #"
180LOCATE 0,16:PRINT"# ## # # # #"
190LOCATE 0,17:PRINT"# ## # # ############# #"
200LOCATE 0,18:PRINT"# # #"
210LOCATE 0,19:PRINT"# # #"
220LOCATE 0,20:PRINT"################################"
230 LOCATE 0,21:PRINT" HIT ANY KEY "
250 '
260 I$=INPUT$(1)
270 END
とこんな感じのプログラムの方が表示が速いです^^;
1文字を表示するだけなら、
PRINTよりもVRAMを使う方が速いのかもしれません。
おそらく、PRINTで""で括られた複数文字を表示するときは、
一括表示(転送)しているのでしょう^^
VRAMのマップ表示方法は、
BASICだと遅いのですが、
マシン語でマップを表示するときは、
VRAMのパターンネームテーブルを書き換える方法でやりますので、
覚えておきたいところです^^
それと、地形との当たり判定はこのパターンネームテーブルを使います。
僕の言う地形とは、迷路などの壁のことです^^
壁にぶつかると進めなくなるというゲームを作るときに使うということですね。
詳しくはこちらで。
ちなみに32文字x24文字= 768文字となるので、
パターンネームは768バイトとなります。
スプライトアトリビュート
スプライトアトリビュート
1B00H番地 ~ 1B7F番地(16進数)
(10進数で、6912番地 ~ 7039番地)
大きさ:80H (10進数だと128バイト)
1B00H番地 : スプライト0のY座標
1B01H番地 : スプライト0のX座標
1B02H番地 : スプライト0のパターン番号
1B03H番地 : スプライト0の色
1B05H番地 : スプライト1のY座標
1B06H番地 : スプライト1のX座標
1B04H番地:スプライト1のY座標?
1B05H番地:スプライト1のX座標?
間違えているかも^^;
~~~
MSX1は、スプライトが32枚表示可能です。
スプライトアトリビュートは、
スプライトの座標や、パターン番号、色のデータのことで、
スプライト1枚につき4バイトです。
全部で128バイト(=32x4)です。
注意したいのが、Y座標が先にはいっていることですね^^
ちなみにスプライトアトリビュートの3バイト目ですが、
16x16ドットのスプライトの場合ですと、
4単位ごとになります。
0、4、8、12、16、、、
このように数値をセットしてやれば、
スプライトのパターン番号0番、1番、2番、3番と
扱うことができます。
(8x8ドットのスプライトを4枚使うという扱いなのかな?)
スプライトの色ですが、MSX1は1枚あたり1色なのです^^;
MSX1の市販のゲームは、キャラクターが2色だったりしますが、
それはスプライトを2枚重ねて使っています。
(スプライトを同じ座標に2枚表示させています)
VPOKEでVRAMの値(スプライトアトリビュート)を書き込むことにより、
スプライトを動かしたり、パタパタアニメーションさせたりできます。
(X,Yを動かすきは、PUT SPRITEの方が速いという情報もあり^^;
X座標だけの変更ならVPOKEでやった方が速いらしい?です( ´Д`)y━・~~
こちらもPRINTのときと同様に、
PUT SPRITEは一括して転送しているんですかねぇ^^)
スプライトアトリビュートの4バイト目は色です。
&h01とか、&h02とか書き込んでください。(&h01は黒です。)
カラーテーブル
カラーテーブル
2000H番地 ~ 201FH番地(16進数)
(10進数で、8192番地 ~ 8223番地)
大きさ : 20H (10進数だと32バイト)
文字の色を変えます。
SCREEN1の場合は、8文字単位でしか変えることができません^^;
よって、
32バイト( = 256文字 / 8)になります。
8文字単位で同じ色になるっていうのは最近知りました( ´Д`)y━・~~
ゲームでSCREEN1を使う場合は注意しないといけません。
1文字あたり2色(文字の色と、背景色)なのは言うまでもないですが、
8文字単位ということをお忘れなく!
(市販のゲームのようなカラフルな地形ブロックはできません。
1ブロック当たり2色です。
カラフルなのはSCREEN1.5を使います。)
https://msxpen.com/codes/-LXwVTbvUNtecHMgvhHn
2000H番地から1バイトごとにデータを変えていきました。
2000H番地を21H、2001H番地を31H、2002H番地を41H、
2003H番地を51H、、、と。
これは、例えば、VRAMの2004H番地の値を&h21と書き込んでやると
!"#$%&'
(この文字の色がすべてcolor2、背景がcolor1になります。)
()*+,-./は、VRAMの2005H番地、
01234567は、VRAMの2006H番地に色を書き込んでやります。
詳しくはMSXのアスキーコードを参照してください。
VRAMに書く1バイトは、文字の色 + 背景の色です。
例えば、カラーを21Hと書き込むと、文字の色が2で、背景の色が1です。
&H2000+その文字のアスキーコード ¥ 8
で特定の文字の色を変えることができます。
(8文字単位でしか無理ですが)
¥は、割った時の商をだします。
10¥8=1
12¥8=1
20¥8=2
36¥8=4
などといった感じです。
8文字単位では不便ですが、
SCREEN1.5だと1文字単位(1ライン単位で、1ライン2色で設定できます)で出来ます。
SCREEN1.5 (多色刷り)というのは、
造語なのですが、
本来文字を扱わないSCREEN2をSCREEN1のように文字を扱えるようにするという
裏技?^^のようなものです。
多色刷りについてはこちらへ。
パレットテーブル
パレットテーブル
2020H番地 ~ 203FH番地(16進数)
(10進数で、8224番地 ~ 8255番地)
大きさ:20H (10進数だと32バイト)
このパレットテーブルというのはほとんど使われません。
一応説明すると、
カラーパレットの内容の保存場所だそうです。
2バイトで1セットで、
1バイト目が、赤成分X16 + 青成分
2バイト目が、緑成分
となります。
ごめんなさい^^; 実はよく分かりません。
MSX1のSCREEN1にはない機能で...と書かれています。
画面をBSAVEで保存した時のパレットの切り替えなどで使用。
パレットの切り替えは、
COLOR=RESTOREで行うと、MSXFANに書いてあります。
興味のある方は調査してみてください。
普通は使わないのかなぁ〜^^
スプライトジェネレータ
スプライトジェネレータ
3800H番地 ~ 3FFFH番地(16進数)
(10進数だと、14336番地~16383番地)
大きさ: 800H (10進数だと2048バイト)
スプライトの形が入っています(定義できます)。
16x16ドットのスプライトの場合、
3800H番地に左上からの1ライン(8ドット)、
3801H番地は、左の2列目(8ドット)。
3802H番地は、左の3列目(8ドット)。
〜
3810H番地は、右上の1ライン(8ドット)
3811H番地は、右の2列目(8ドット)。
3812H番地 ~
~
このあたりはこちらが少しだけ参考になるかも。
やりかたは違うのですが、
16x16ドットのスプライトの設定についての考え方がわかると思います。
3800H番地 ~ 381FH番地でスプライト番号0の形を定義します。(32バイト)
3820H番地 ~ 383FH番地でスプライト番号1の形を。(32バイト)
このように順番に入っています。
注意しないといけないのが、これはスプライトパターンだということ。
実際にスプライトを使うときは、
スプライト0にこのスプライトパターンを設定して使います。
PUT SPRITE 0( x,y ),カラー,スプライト番号
(このように設定します。
なぜスプライト番号などを設定するのかといいますと、
スプライトでウォーキングアニメーションさせる時などに、
スプライト番号を変えてやればいいからです。)
(実際に動かすスプライトは、スプライト0~スプライト32までで、
それにスプライトジェネレータに登録してあるスプライト番号を
設定するという使い方をします。
同じ形のキャラクターを大量に表示することなどができますね^^)
スプライトジェネレータは、16x16ドットのスプライトだと、64個定義できます。
(16x16ドットのスプライトを使う場合、
10行(最初の方)にSCREEN1,2としておきます。)
10 cls:width32:screen1,2
20 a=&hff
30 for i=&h3800 to &h381f
40 vpoke i,a
60 next
70 put sprite0,(100,100),15,0
3800H番地 ~ 381F番地(10進数で14336番地 ~ 14367番地)に
&hffを書き込んでいます。
16進数のffは、
2進数で、11111111です。
ネットでMSXのハードやソフト、雑誌などを買うならこちら
何かあたらしいものが入荷しているかもしれません^^
SCREEN2のVRAMマップ
SCREEN2のVRAMマップ
0000H番地〜 キャラクターパターンジェネレータ(文字の形) 1800H(6144バイト)
1800H番地〜 パターン名称テーブル (画面表示・構成) 300H(768バイト)
1B00H番地〜 スプライトアトリビュート(Y、X座標他) 80H(128バイト)
1B80H番地〜 パレット 20H(32バイト)
2000H番地〜 カラー (文字の色) 1800H(6144バイト)
3800H番地〜 スプライトパターンジェネレータ(スプライト形) 800H(2048バイト)
VRAMは16Kバイト(4000H)
キャラクターパターンジェネレータ
0000H番地 ~ 17FFH番地(16進数)
(10進数だと0000番地~6143番地)
大きさ:1800H (10進数だと6144バイト)
文字の形なのですが、
SCREEN1と違うのは3倍の大きさになっていることです。
これは、SCREEN2(SCREEN1.5)は、画面を上・中・下と分けて
それぞれ文字を設定するのです。
ちょっと意味がわからないと思います^^;
詳しくはこちらへ。
使い方を工夫すると面白いかもしれないですね( ・∇・)
アドベンチャーゲームやRPGで画面の下部は文字を表示するとか、
横スクロールシューティングゲームだとより華やかなグラフィックに
できるかもしれません^^
カラー
2000H番地 ~ 37FFH番地(16進数)
(10進数だと、8192番地~14335番地)
大きさ:1800H (10進数だと6144バイト)
文字の色です。
SCREEN1と違うのは、大きさが1800Hバイト(6144バイト)と、
192倍になっています(๑╹ω╹๑ )
1文字単位で色をつけることができるということと、
それだけではなく、
横1ラインごとに2色の色を設定できるのです!
MSX1のゲームで特徴的なのが、
この8ドット横ライン2色という制限だったりします。
僕は小学生の頃は、この制限を知りませんでした^^;
普通に1ドットごとに16色使えるのだと思っていました( ̄^ ̄)
その制限のため、MSX1でグラフィックを描くのはコツがいります。
ただ今となっては、この制限が味となっていると思います(๑˃̵ᴗ˂̵)
僕がMSX1に拘るのは、この制限のあるグラフィックが好きなのかも
しれません^^
MSX2は、ドット単位で色がつけられますが、
それだと今のPCに近い表現になってしまいます。
僕は、わざわざ8bitで色々やるなら、
特徴があるMSX1の方が楽しく感じてしまいます^^
(MSX2を持っていませんでしたし( ;∀;))
こちらのVRAMの詳しい使い方はこちらへどうぞ。
SCREEN2とSCREEN1の違いは、この2つと、
パレット(あまり使わない^^;)の位置が違うことです。
SCREEN1のVRAMは、
1BA0H番地 ~ 1FFFH番地 (10進数で、7072番地~8191番地)が、
使われていなんですね!
1120バイトも使われていない!!
1画面の情報量が768バイトなので、VRAMのこの空いているところへ、
画面情報を書き込んで、地形(壁)・敵スプライトとの当たり判定に使ったり
できそうですね!
(この方法でいつか何か作ってみたいです。)
他にも、何かデータを置いて置くこともできそうです^^
(VPOKEでデータを書き込んで、必要な時にVPEEKで読み込むという方法です)
1Kバイト以上も使えるので、何かに使いたいところです。
まとめ
このようにVRAMを使いこなせば、
MSXBASICでも、少々レベルの高いことができそうです^^
BASICでは、文字の表示やスプライトの設定や、スプライトの移動は、
VRAMを使う必要はないかもしれません。
しかし、マシン語(アセンブラ)だと、VRAMを使う方法をとるので、
ぜひ覚えておきたいところです。
文字の形を変えてグラフィックを描いたり(地形ブロックなど)、
地形ブロック(壁)とスプライトとの当たり判定などは、
VRAMを使用しないといけません。
VRAMを知れば、ワンランク、レベルアップしたゲームを作ることができます。
いまさらMSXについて勉強しても?と思う方もいらっしゃるかもしれませんが、
現在のPCの基本的なことがとてもよく分かるので、
学んで損はないと思います^^
なによりMSXは楽しい!これに尽きます(๑˃̵ᴗ˂̵)
ネットでMSXのハードやソフト、雑誌などを買うならこちら
何かあたらしいものが入荷しているかもしれません^^