Last Update 2002/6/3
グラフィックVRAMの構造についてです。
この文章は、グラフィックVRAMの並び方を Windyが独自に調べた結果です。 SRのグラフィックVRAMの構造は、元々かなり難解なので、これが100%合っているわけではないかも知れないことを、ご留意下さい。 よろしくおねがいします。
まず、通常、VRAMから読み出すときを おさらいしてみましょう。 下記のように、VRAMウインドウを通して、アクセスします。
(0,0) |
(0,1) |
(0,2) |
(0,3) |
(0,4) |
(0,5) |
(0,6) |
(0,7) |
(0,8) |
(0,9) |
一升が1バイトで、画面上では、1ドットを表します。 読み出すときは、下位4ビットのみが有効ですので、 and 0xf する必要が有ります。
つまり、1バイトあたり 1ドットを表すので、パックトピクセル方式(?)というのでしょうか。 但し、Y座標を変えるときは、いちいち I/Oにアクセスをして、いちいちバンク切り替えをする必要があります。
それにしても、何故、いちいちバンク切り替えをする方法になってしまったのでしょうか? その答えは、どうやら、VRAM本来の構造に有るようです。
それでは本題です。
VRAMの並び方は 本来、理論整然とした並び方であるべきです。 しかし、32KBもの巨大なVRAMになったためか、 このVRAM本来の並び方は、かなり難しい並び方になっています。
VRAMを、VRAMウインドウに投影するときに、(アクセスしやすいように)並び替えているようです。 しかし、 もともと、分かりやすい並び方なら、何もしなくても 直接アクセスできたのではないか? ゲームも作りやすかったのでは? と惜しまれるところです。(汗)
(もしかすると、ハードウエア上の制約だったのかも知れませんが・・。)
グラフィックVRAMの並び方は ビットマップモードだと 上記のようなアクセス方法になってしまいますが、テキストモードなら、素のデータを読めるので、調べることが出来ます。ということは、SCREEN 2,2,2として、絵を描き込んでから、SCREEN 1,1,1で MONして、メモリダンプすれば、VRAMの本来の構造が見て取れます。
下記の図は、(0,0)からの座標から取り出した VRAM本来の並び方です。
1A00h (偶数) | 1A02h (奇数) | 1A04h (偶数) | 1A06h (奇数) | 1A08h (偶数) |
(0,0)(1,0)(2,0)(3,0) |
(0,1)(1,1)(2,1)(3,1) |
(4,0)(5,0)(6,0)(7.0) |
(4,1)(5,1)(6,1)(7.1) |
(8,0)(9,0)(10,0)(11,0) |
一升は、1ワードです。そして、1ワードに、4ピクセル分格納されています。
但し、普通と違うのは、順番に格納されているのではなく、 偶数に当たるワードは、今のY座標のデータが格納されるのに対して、 奇数にあたるワードは、一つ下のY座標のデータが格納されます。 ややこしいですが、何故こうなったのかは、不明です。(汗)
さらに、1ワード を分解すると下記のようになります。 ( SCREEN 2の場合)
b15 |
b14 |
b13 |
b12 |
b11 |
b10 |
b9 |
b8 |
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
X= 3 |
X= 2 |
X= 1 |
X= 0 |
ただし、メモリーに書き込むときに、ザイログやインテル系のCPUは、順番が変わってしまうので注意が必要です。メモリー上では、下記のように書き込まれています。
X= 1 |
X= 0 |
X= 3 |
X= 2 |
上記では省略されていましたが、右端まで行ったら、一体どうなるのでしょうか?
普通の並び方なら、左上から始まったデータが、そのまま右端まで行き、つぎに下のラインに行き、また右端まで行き・・。という事を想像すると思いますが、ちょっと違います。
SCREEN 2では、X方向に320ドットありますが、この画面を縦に左右に切ってください。左側256ドット、右側64ドットになります。 何故かというと、VRAMもこの部分で左右分けて格納されているからです。
ということは、左側は x=0から x=255まで行くと下のラインに移動するということです。右側は、x=256から、x=319まで行くと、下のラインに移動します。
あと、開始アドレスも、それぞれ独特な開始アドレスになっています。 左側は、1A00hから始まっています。 右側は、0000hから始まっています。
ということは、VRAM全体からすると、(256,0)から始まって、(319,203)まで行き、(0,0)に飛んで、(255,203)まで行くという構造になっています。
adr= 0x1A00adr=0x0000
(0,0)(255,0) (319,0)
それでは、VRAMのデータから 画面に表示してみましょう。(RefreshScr62 /RefreshScr63 の説明でもあります。)
右側も、左側と同じだと思っていましたが、実はちょっと違うようです。
左半分のピクセルデータの開始アドレスは、下記の通りです。
これは、まだ素直な並び方をしています。
アドレス |
Y座標 |
アドレス |
Y座標 |
|
1A00 |
Y=0 | 1A02 |
Y=1 |
|
1B00 |
Y=2 |
1B02 |
Y=3 |
|
1C00 |
Y=4 |
1C02 |
Y=5 |
|
1D00 |
Y=6 |
1D02 |
Y=7 |
|
1E00 |
Y=8 |
1E02 |
Y=9 |
|
1F00 |
Y=10 |
1F02 |
Y=11 |
|
2000 |
Y=12 |
2002 |
Y=13 |
|
2100 |
Y=14 |
2102 |
Y=15 |
右半分のピクセルデータの開始アドレスは、下記の通りです。
こちらは、あっちこっちに飛んでいます。(Y座標の並び方に注目してください)
アドレス |
Y座標 |
アドレス |
Y座標 |
|
0000 |
Y=0 | 0002 |
Y=1 |
|
0040 |
Y=4 |
0042 |
Y=5 |
|
0080 |
Y=8 |
0082 |
Y=9 |
|
00C0 |
Y=12 |
00C2 |
Y=13 |
|
0100 |
Y=2 |
0102 |
Y=3 |
|
0140 |
Y=6 |
0142 |
Y=7 |
|
0180 |
Y=10 |
0182 |
Y=11 |
|
01C0 |
Y=14 |
01C2 |
Y=15 |
|
0200 |
Y=16 |
0202 |
Y=17 |
何故、ここまで飛んでいるんでしょうか? よく分かりません。
それに、右と左で、並び方が違うとなると、実装するのが大変です。 というわけで、白状すると、大変申し訳ないのですが、今公開中の 5月25日版では、この右側の特殊な並び方は、サポート出来ていません。 右側も、左側並び方と、同じにしています。
とりあえず、左右同じでも、あまり問題はないようです。 しかし、起動メニューの下記の画面に影響が有るようです。
これも、ゆくゆくは 解消したいと思っていますが・・。
こんな つたない説明で、おわかりいただけたでしょうか?(汗) もし、分からないところや、間違いがありましたら、メールなどでお知らせ下さい。(_)
それから、SCREEN 3も、1ワードの中身が違うだけで、上記とほとんど同じ説明が適用されるようです。それでは、よろしくおねがいします。