今回はVRAMからメモリへのブロック転送です。
前回とは逆になります。
どんな時にこれらのBIOSルーチンを
使うのかと言いますと、
画面のデータをメモリへ写して、そこで改変して、再びVRAMへ
戻してやるような時です。
前回スクロールに使うと書きましたが、
よくよく考えてみると、スクロールに必須な命令というわけでも
ないような気がします。
うーん。
前回のページです。
LDIRMV VRAMからメモリヘブロック転送する
BIOSルーチンのLDIRMVをコールするだけで、
VRAMからメモリへブロック転送してくれます。
ただ、どのデータをどこへコピーするかが分からないとできません。
そこであらかじめレジスタにその値を入れておきます。
前回はメモリ -> VRAMでしたが、
今回はVRAM -> メモリとなります。
レジスタ HL 転送元のメモリ(VRAM)の先頭アドレス
レジスタ DE 転送先のメモリの先頭アドレス
レジスタ BC 転送するメモリ内容の数(バイト)
(以下の、具体的なマシン語なのですが、
MSX FANの方がわかりやすいのでそちらを参考にします。)
<駿河屋>
MSX FAN 1991年6月号に詳しく載っています。
リスト
LD HL, 1800H
LD DE, (F7F8H)
LD BC, 0300H
CALL LDIRMV
RET
説明:
LD HL, 1800H
次の2バイトの数値をHLレジスタにセットします。
HLレジスタは、転送元のメモリ(VRAM)の先頭アドレスをいれるのでした。
&H1800はなにかといいますと、
VRAMの、&H1800以降は画面のデータ(パターン名称テーブル)が
入っているアドレスです。
具体的にマシン語で書くと
&HD000 21
&HD001 00
&HD002 18
(プログラムに書く時は先頭のアドレスは書きません。 210018と書いていきます)
よくマシン語のプログラムに16進数が載っていますね。
LD DE, (F7F8H)
これは、次の2バイトが指し示すアドレスにある数値を
DEレジスタにセットします。
&HF7F8そのものをセットするのではないところが味噌ですね。
アドレス&HF7F8に入っている値です。
ED5Bを使います。
(ps 初期の頃、間違えてED58と書いていました。申し訳ありませんm(_ _)m)
&HD003 ED
&HD004 5B
&HD005 F8
&HD006 F7
&HF7F8はなにかといいますと、BASICのUSR関数の引数が入っている
アドレスとなります。(MSX FANではそう書いてある)
LD BC, 0300H
次の2バイトの数値をBCレジスタにセット。
BCレジスタは、転送するメモリ内容の数(バイト)が入ります。
&H0300は10進数でいうと、768です。
768バイトはscreen1の1画面分のデータ量をさします。
X座標32文字 x Y座標24文字 x 1バイト(1文字) = 768バイトです。
&HD007 01
&HD008 00
&HD009 03
ここは前回と同じです。
CALL LDIRMV
VRAMからメモリへブロック転送するBIOSルーチンを呼ぶ。
前回のLDIRVMとは違っているところに注意してください。
(前回)LDIRVM と (今回) LDIRMV
赤文字のところが違っています。
VはVRAMで、 Mはメモリのことだと思います。
&HD010 CD
&HD011 59
&HD012 00
CDがコールで、&H0059のアドレスを呼ぶと、LDIRMVが
呼ばれます。
RET
リターンです。メインルーチンに戻る。
&HD013 C9
BASICプログラムからマシン語を使う場合は、
C9
で、BASICプログラムに戻っていきます。
BASICではDATA文にいれて使います。
DATA 210018ED5BF8F7010003CD5900C9
という風にです。
前回とほとんど同じで、
気をつけるのは、
レジスタ HL 転送元のメモリ(VRAM)の先頭アドレス
レジスタ DE 転送先のメモリの先頭アドレス
のところで、HLにはVRAMのアドレス、DEにメモリのアドレス(USR関数の引数)が
くるということですね。
VRAMとメモリのところが、前回と逆になっています。
例によって、ハンドアセンブルしておりますが、
こちらの表を参考にしてください。
まとめ
今回は、VRAMからメモリへのブロック転送でした。
以前、どっかでみたスクロールのサンプルプログラムでは、
(マップデータ)
VRAM->メモリ(改変)->VRAM
という形でやっていました。
素人考えですが、いちいちVRAMからメモリへ
データをブロック転送しなくても
メモリでマップデータを作って、VRAMヘ送るだけではダメなんでしょうか?
うーん。
表示されているデータを改変した方が、 正確だとは思うのですが、
かなり遅くならないのかなぁ。
その程度の処理ならスピードは気にならないのかもしれないですね〜;
まぁ、やり方は様々なので色々試してみたいと思います。
今回のは、画面データを持ってくるというので、色々と使い道があるのでは
ないでしょうか?
MSX BASICゲームで使うところは、前回と今回のところなので、
またしばらくは、
"WebMSXでBASICのゲームを作ろう!"のページを
書いていくことになると思います。
(実際にマシン語をBASICの中で使いました。ソースコードはこちら。)
WebMSXでMSX BASICのゲームを作ろう!第十弾。 圧倒的速さ!マシン語で画面切り替え!(URLクリックで実行できます) - ニャオニャオ21世紀
でもMSX BASICは、地形との当たり判定や、最初のキャラクターの定義とかで
かなり時間を取られるので、
いつかそこらへんもマシン語でやれたらいいなぁなんて思っています。
それでは〜。