4.5 V9958とMSX2+  MSXの画面表示を制御する部分を"Video Display Processor"、略してVDPという。MSX2のVDPは"V9938"というものだったけど、MSX2+以降の、マシンでは"V9958"に機能アップされた。ここでは、そのV9958に追加された機能を紹介する。 4.5.1 スクリーンモードは全部で12種類  スクリーンモードとは、BASICのSCREEN命令で切り替えられる画面の状態。たとえば、横40桁表示でBASICのプログラムのプログラムを書きたい場合は、  SCRREEN 0 : WIDTH 40 によって画面をテキス(文字表示)モードに切り替え、グラフィックを描きたい場合は、  SCREEN 8 などで、グラフィック(図形表示)モードに切り替える。スクリーンモードが多いとなにかと面倒なので、少なくてすむならそれにこしたことはない。でもMSX2+のすくローンモードが多いことには、それなりの理由がある。  第1番目が速さの問題。グラフィックモードの画面に文字を出力すると、表示に時間がかかってしまう。だからプログラムを入力するようなときは、図形や漢字を使えない代わりに表示が速い、テキストモードが便利だ。  第2の理由は、機能が高い(表示できるドット数や色が多い)画面ほど、たくさんのデータを必要とすること。たとえばSCREEN 8の画面データは1枚で54,272バイトもあり、これでは1枚のディスク(2DD)に12枚の絵しか記録できない。そのためROMカートリッジのゲームでは、色数に制限があるかわりにデータが少なくて動作が速い、SCREEN 2を使ってメモリーを節約することが多くなっている。  第3に、互換性を保ちながら機能を追加したために、多くのスクリーンモードが必要になったこと。最初のMSXでは、SCRREEN 0から3までの4種類のスクリーンモードしかなかった。それがMSX2になり、高解像度グラフィック表示のためSCREEN 4から8が追加。さらにMSX2+では、色数を増やすためにSCREEN 10から12が追加されたというわけ。  これからのスクリーンモードをまとめたのが表4.7。でも実際にはスクリーンモードの問題はこれで終わりではなく、縦方向の解像度を2倍に増やすインターレースモードや、MSX2+で新しく追加された漢字モードなどがある。 4.5.2 VDPのレジスターをコントロールする  MSXの画面表示を制御するVDPの中には、マシンの心臓部であるCPUと土用に同様に"レジスター"というものがある。そしてこのVDPのレジスターは、I/OポートをとおすことでCPUが操作できるものだ。中でも、CPUがVDPを制御するために使うレジスターを"コントロールレジスター"、CPUがVDPの状態を知るために使うレジスターを"ステータスレジスター"と呼んでいる。このほかにも、VDPに高度な命令を実行させるためにCPUが操作する"コマンドレジスター"があるけど、本書のプログラムでは使用しないので、説明は省略する。  CPUとVDPを接続するI/Oポートの番地は、普通は98Hから9BHまでを使っている。でも正確には表4.8に掲載したように、ROMの6番地と7番地の内容で決まってくる。これは、MSX本体の外にVDPを増設できるようにとの配慮から。なお、同じポート0でも、書き込む場合と読み出す場合とでは、I/Oポートの番地が異なっていることがあるので注意しよう。  さて、VDPのコントロールレジスターの値を設定するためには、まず、表4.8のポート1に設定したいデータを書き込み、続けて同じポート1に"レジスター番号+128"を書き込む。この"続けて"という条件は意外と重要で、2回の書き込みの間に割り込みが起こるとVDPが混乱してしまうんだ。だからこの場合は、まず"DI"命令で割り込みを禁止しておいてから、ふたつのデータを続けて書き込む方法が一般的に使われている。  ところで、コントロールレジスターーというのは書き込み専用のもの。一度設定された値は、読み出すことができない。だから、レジスターの設定のビットだけを書き替えたいなんて場合は都合が悪くなってしまう。そこで通常は、コントロールレジスターに書き込む値を、表4.9のようなシステムワークエリア(RAM)にも書き込んでおくという方法をとる 。たとえば、コントロールレジスター1のビット4を1に変えたい場合には、RAMのF3E0H番地の内容を読んでビット4を1に変え、その値をコントロールレジスター1とRAMのF3E0H番地に書き込むという具合だ。あとで紹介するリスト4.9の走査線割り込みのサンプルプログラムの中では、"WRTCDP"というサブルーチンがこれと同じ動作を行っている。  次にステータスレジスターの値を読み込むための方法を説明する。これは、コントロールレジスター15に読み込みたいステータスレジスターの番号を設定し、VDPのポート1の値を読み、コントロールレジスター15を0に戻すという手続きを、割り込みを禁止したままで行うというもの。リスト4.9のサンプルプログラムの中では、"_VDPSTA"というサブルーチンがこれにあたる。  もっとも、MSX2や2+のROMにはこれあらのサブルーチンと同じ機能のBIOSがあるので、普通は自分でサブルーチンを作らずにBIOSを使えばいい。でも、これらのBIOSはサブROMにあったり、処理中にサブROMを呼び出したりするので、多少時間がかかるとうい難点がある。そのため、走査線割り込みのような処理には都合が悪いので、あえてBIOSを使わないわけだ。  表4.10〜4.12に、そのほかのシステムワークエリアをまとめておいたので、参考にしてほしい。 4.5.3 V9958のレジスター  図4.3に掲載したのは、V9958に追加された3個のコントロールレジスター。これらのレジスターは書く込み専用のもので、書き込まれた値を表4.9のシステムワークエリアに記録する。コントロールレジスタ24がないことや、レジスター番号とBASICのVDP関数の番号が異なることに注意しよう。  V9958で追加された機能の大部分は、コントロールレジスター25で制御される。有名なYJK(自然画)表示と横スクロールは後回しにして、残りの機能から紹介するぞ。  レジスター25のビット7には、かならず0を書き込もう。ビット5は"VDS"と呼ばれ、VDPの端子8の機能を制御する。けれども、普通のプログラムがこのビットを書き換えることは禁止されている。  またビット6に0を書き込めば、V9938と同様にSCREEN 5から8の画面に対してのみ"VDPコマンド"が使えるようになる。これとは逆に1を書き込めば、全画面モードでVDPコマンドが使えるわけだ。このVDPコマンドとは、BASICのCOPY命令やLINE命令のような仕事を、VDPにさせる機能。細かい話になるけれど、SCREEN 5から8以外の画面に対するVDPコマンドでは、128キロバイトのビデオRAMの中の場所を、SCREEN 8のようにX座標が0から255、Y座標が0から511の値で指定する。  さらにビット2に1を書き込むと、VDPの"ウェイト機能"が有効になる。これはCPUがビデオRAMを読み書きするとき、CPUの動作が速すぎればVDPがCPUに"WAIT信号"を送って待たせる機能だ。ただし、パレットレジスターへの書き込みと、VDPコマンドによる転送には、ウェイト機能がない。 4.5.4 VDPによる横スクロール  横スクロールには、1画面分の画像データを使う方法と、2画面分の画像データを使う方法がある。それぞれの場合について、順番に説明していこう。  まず、コントロールレジスター25のビット0"SP2"が0の場合には、図4.4の上のように1画面分のデータによる横スクロールが起こる。スクロールのドット数は、レジスター26と27で指定することができる。レジスター26に0から63の値を書き込むと、その値×8ドット単位で画面が左にスクロールし、レジスター27に0から7の値を書くとその数だけ右に移動する。ただしSCREEN 6と7では、指定した数の2倍ドット数のスクロールが起こるから注意しよう。ドット数を0から255まで順番に増やしていくと、画面が左へスクロールし、はみだした部分が右端から現れてくる。  一方レジスター25のビット0が1の場合には、図4.4の下のように、2画面分の画像データから指定された部分が表示され、横スクロールがはじまる。  このときの画像データは、ビデオRAMのページ0と1または2と3に記憶されている。ページ0と1の場合はディスプレーページを1に、2と3の場合にはディスプレーページを3に設定しよう。横スクロールのドット数は0から511(つまり1画面スクロールの2倍)になる。  また、レジスター25のビット1を1にすると、画面端の8ドット(SCREEN 6と7では16ドット)が表示されず、変わりにその場所に画面の周辺色が表示される。これは横スクロール、とくに1画面分のデータによる横スクロールをする場合、画面からはみ出した部分がすぐに反対側から現れるのを隠すのに便利だ。リスト4.1に横スクロールのプログラム例を掲載しておくので、参考にしよう。 4.5.5 何があっても裏技は使っていけないぞ  VDPレジスターの中には、かならず0を書き込めとか、かならず1を書き込めとか指定されているビットがある。この指定を無視して変な値を書き込むようなことは、何が起こるかわからないので、絶対にやってはいけない。  また、YJK=0とYAE=1の組み合わせのように、VDPの動作が仕様書で決められていない設定があるけど、こうした仕様書に書かれていない"裏技"も、使ってはいけない。たとえば自分が持っているマシンで問題なく動いたとしても、それはたまたま動いただけのこと。ほかのMSXマシンで正常に動作するという保障はどこにもない。また、現在のV9958に対しては有効な裏技であっても、今後VDPが改良されたり、ヤマハ以外のメーカーがV9958互換のVDPを作ったりすれば(いまのところV9958はすべてヤマハ製)、同じ裏技が有効とは限らない。  これと同じように、CPUの裏技(正式には"未定義命令"という)も一切使ってはいけない。過去の例でも、Z80の裏技を使ったために、ビクターのHC-95のターボモード(Z80の上位互換CPUであるHD64180を使っている)で暴走したソフトウェアがあった。