MZ80を起動せよ!画面バッファを利用した高速書き換えプログラム

古いPCやゲーム機のプログラミングをしていると、その描画速度の遅さに四苦八苦することが度々あります。今回のMZ80もそうで、BASICで素直に描画するととんでもなく遅く、お話になりません。

そこで、アセンブラで描画処理の部分を描いてしまえばあとはどうにでもなるのでは?というかエミュレーターでテストできるならアセンブラでガリガリ書けば速度なんとかなるのでは?
(MZ80のすごいところは、描画中にメモリアクセスのウェイトをかけていないことです。映像は乱れますが、強引かつ高速に描画を繰り返すことが可能です。)

そう考えた結果、潤沢?なメモリを搭載しているMZ80のシステムを利用し、フレームバッファを用意して、スプライト画面・背景画面を合成、描画メモリへ転送するシステムを設計してみました。

メモリ転送とアドレス管理の考察

■|そもそもMZ80はどうやってテキストを描画しているのか

上記の漫画にも記載したように、MZ80にはz80のメモリエリア上に画面に表示するテキストバッファが割り当てられている設計となっております。
そのメモリエリアはD000h~D3E7hまでの1000byteとなっております。
というのも、表示できる文字数が横に40文字、縦に25行となっているためですね。

そのため、疑似ドットグラフィックはこの2倍の(1文字に2ドット分配置されているため)縦50ドットx横80ドットの解像度として絵を表示することができるのです。
そして今のPCのようにラスターフォントで表示しているのではなく、VRAMには画面に表示するフォントのコードを書き込んでおります。そのため、任意のフォントグラフィックに書き換えて表示するといったような機能は搭載されておりません。
 VRAMに書き込まれた文字コードがそのままグラフィックを記録しているROMにアドレスとして読み込まれ、フォントデータが出力される仕組みになっております。
 そのため、搭載されているフォントグラフィックROMを差し替えれば、任意の文字グラフィックスに差し替えることが可能です。

■|書き換え速度の問題と、VRAM転送問題

 ゲームを作るうえでカギになるのはこの描画速度です。例えば、PRINT文で書き換えた場合は必ず1Fで1回しか処理されないため、描画速度がどうしても遅くなります。
ましてや、スクロール画面などの画面全体を書き換える処理が入った場合はこのような再描画は難しくなります。
 そこで、全画面の再描画をするために
「裏画面用のメモリで描画」
「描画をしたメモリをVRAMエリアに転送」
という手順で描画をし、全画面を高速に書き換える方法を使います。
そんな方法ですが、あらかじめ確保したメモリエリアからVRAMへメモリを転送してしまう、という非常に単純なお話です。
転送の際にZ80のブロック転送命令
LDIR
を使用することで、思考プロセスをシンプルにしています。本来ならより高速な転送プログラムを使用すればループ自体の速度を抑えることができるようになるでしょう( ..)φメモメモ

■|実際に動くプログラムデータへ変換する

さて、先ほど作成したアセンブラのままではプログラムとしては動かないので、MZTファイルという拡張子のデータに変換する必要があります。
アセンブラのコンバート・MZT化にはこちらのツール
を使用させていただきました。本当にありがとうございます。
こちらのEXEファイルをコマンドプロンプトで使用し、MZ80向けにMZTファイルとして出力すればエミュレータにて実行することができます。


あとは画面裏バッファでの書き込み座標を計算し、メモリアドレスを正しく指定することができればXY位置を指定してグラフィックを書き込むことができる、というわけです。

問題は複雑なグラフィックの書き込み処理などですね。結局、保持できるのはキャラクターフラフィックスのパターンだけなので、用意したパターンデータを書き込むプログラムシステムは自分で考える必要があります。そこらへん、スプライト番号さえ指定してしまえば表示できるようになっているファミコンやMSXはやはり非常に優秀なシステムなんですよね~

そして出来上がったのがこちら。
妙にもっさりしているのは背景用にバッファを用意していないためですね。




そしてこちらがバッファなどを追加したバージョン。スクロールの時にのみ書き換え処理を挟んでいるので、とても軽くなっております。メモリはバク食いしますが、48KBもあるから多少は贅沢していいでしょう。少なくともIchigoJamよりはメモリが潤沢です。

ということでMZ-80のセミグラフィックでもかなりグラフィカルなアクションゲームが作れそうだということが分かったところで今回はここまで。スタックポインタとかグラフィックデータとかマップデータの管理とかいろいろ一気に増えたので、プログラミングの難易度が一気に跳ね上がってしまいどうしたものか…
またいい感じに進捗が進んだら更新させていただきます。

次の記事:

前の記事:

コメント

このブログの人気の投稿

ファミコンの完全自作ROM&カセットを作ろう!!その1~立ちはだかるコンパイラの壁~

ファミコンの完全自作ROM&カセット作ろう!〜cc65で起動ROMをつくる〜

74HC595を使ってarduinoの16ビットパラレル出力に挑んでみた