1.2 MSX turbo R 活用法 1.2.1 R800の速さを生かすプログラミング  確かにR800は速いけれど、その速さを最大限に発揮するには、つまりウェイトを避けてR800の能力を活用するには、プログラミングの工夫が必要になる。覚えておいてほしいのは、外部スロットのアクセスには3ウェイト、本体内蔵ROMのアクセスには2ウェイト、本体内蔵DRAMをページアクセスできなかったときには1ウェイトが発生することだ。  理想的には、本体内蔵RAMの番地の上位バイトが同じような256バイトの範囲(ページアクセス可能な範囲)にプログラムが置かれ、レジスターにデータが置かれてるとよい。この場合には、データのためのメモリアクセスが起こらず、CPUがプログラムを読み込みためのメモリーアクセスもページモードで行われるので、CPUにウェイトがかからない。すべてのプログラムを、こうして作るのは難しいけれど、もっとも速さを要求されるサブルーチンだけでも、この条件に近づけるといいだろう。  さて、ページアクセスの可否には、プログラム、データ、スタックの番地が関係する。たとえば、 PUSH HL 命令の実行時間は、その命令が置かれている番地の上位バイトとスタックポインターの上位バイトが一致すれば4ブロック。一致しなければ5クロックだ。ここまで考えながらプログラムを作る必要は少ないだろうけど、状況に応じて命令の実行時間が異なることは重要なので、考えておこう。 1.2.2 R800を使う上での注意事項と問題点  Z80では、ひとつの命令を実行するたびにDRAMをリフレッシュしていた。ところがR800では、31マイクロ秒ごとに280ナノ秒かけて、DRAMをリフレッシュする。注意してほしいのは、このリフレッシュに要する時間と、先ほど説明したDRAMのページアクセス可否の条件のため、R800のプログラム実行時間を正確に予測することができないことだ。  そこでプログラムの速さを調整するために、"システムタイマー"とういうものを使うことになる。あとで、このシステムタイマーの使い方と、CPUとVDPの間の速さの調整について説明するので、待ってほしい。  また、これはどの新型CPUでもいえることなのだけど、R800の問題点として考えられるのは、開発機材が不足していること。とくに、ソフトウェアを開発するときに威力を発揮する"ICE(インサーキットエミュレータ)"を、デバックに使えないことが不便だ。  そのため、turbo R 用のソフトウェアを作るためには、まず従来のMSXとZ80用のICEを使って徹底的にデバックし、確実に動くはずのプログラムを turbo R 用に直す方法がいいだろう。Z80兼用のプログラムを作って動作を確認してかあら、掛け算を使う部分のみをR800用に書き替えるわけだ。このとき、サブルーチンごとにわけて、動作をチェックするのもいい。そして、最後に全体を組み立てて動かなければ……ソースリストを見て考えるしかない。 1.2.3 追加されたBIOSとその機能説明  turbo R の新しいハードウェア機能を制御するために、CPUの切り替えと、PCMの録音再生のためのBIOSが追加された。  ここでは、BIOSの名称(ラベル)、エントリーアドレス(番地)、そして機能と各レジスターの順番で説明する。BIOSの機能を書き表すための記号は、以下のとおりだ。まず「E」とはBIOSを呼び出す前に値を設定すべきレジスター。「R」はBIOSが値を返すレジスターで、「M」はBIOSが無意味な値を書き込む、つまり元の内容が壊されるレジスターを表す。またIYHとは、IYレジスターの上位バイトを表し、下位バイトの内容は無視される。 CHGCPU 0180H番地 機能:CPUを切り替える。 E:Aレジスターのビット1と0で、次のようにモードを設定する。このうち"R800 DRAM"というのは、BIOSのROMの内容をDRAMに転送して使うモードのことだ。 b7 b6 b5 b4 b3 b2 b1 b0 L 0 0 0 0 0 M M モード かならず0を書き込む LED モード 00 Z80 01 R800 ROM 02 R800 DRAM また、Aレジスターのビット7が1ならば、どうちらのCPUが動いているかを表すLEDが変化する。逆にAレジスターのビット7が0なら、CPUが切り替えられるが、LEDは変化しない。 R:なし M:AF 注:CPUを切り替える前のレジスターの内容は、AFとRを除いて、切り替え後のCPUにそのまま引き継がれる。また、切り替えたあとは割り込みが許可される。なおCPU切り替えの注意事項については、あとで詳しく説明する。 GETCPU 0183H番地 機能:動作中のCPUを調べる。 E:なし R:動作中のCPUに応じて、Aレジスターに次のような値が返される。 0 Z80 1 R800 ROM 2 R800 DRAM M:F 注:あとで説明する方法でハードウェアが turbo R であることを確かめてから、このようなBIOSを呼び出す必要がある。 PCMPLY 0186H番地 機能:PCMの音を再生する。 E:A b7 b6 b5 b4 b3 b2 b1 b0 R 0 0 0 0 0 F F 周波数 かならず0を書き込む VRAM/MRAM EHL(データの番地) DBC(データの長さ) Aレジスターのビット7が1ならばビデオRAMに、0ならばメインRAMにPCMの音源データが置かれる。なおビデオRAMにデータがある場合にのみ、DレジスターとEレジスターの値が意味を持つ。 Aレジスターのビット1とビット0で、サンプリング周波数を設定する。ただし15.75キロヘルツは、turbo R が R800 の DRAM モードで動いている場合だけ指定可能だ。 00 15.75キロヘルツ 01 7.875キロヘルツ 02 5.25キロヘルツ 03 3.9375キロヘルツ R:キャリーフラグ 0 正常終了 1 以上終了 A(異常の原因) 1 周波数指定誤り 2 STOPキーによる中断 EHL(中断番地) M:すべて PCMREC 0189H番地 機能:PCMの音を記録する。 E:A b7 b6 b5 b4 b3 b2 b1 b0 R T T T T C F F 周波数 圧縮 トリガー VRAM/MRAM EHL(データの番地) DBC(データの長さ) Aレジスターのビット7、1、0の設定方法は、PCMPLYで説明したものと同じ。Aレジスターのビット6からビット3は"トリガーレベル"といい、録音をはじめるきっかけとなる音の大きさを指定する。この値が0ならば、ただちに録音が開始される。 また、Aレジスターのビット2が1ならば、録音データ圧縮される。0ならば圧縮されない。 R:キャリーフラグ 0 正常終了 1 異常終了 A(異常の原因) 1 周波数指定誤り 2 STOPキーによる中断 EHL(中断番地) M:すべて 1.2.4 変更および削除されたBIOSについて  turbo R で変更または削除されたBIOSは、表1.3に示したとおり。それぞれについて、簡単に説明していく。  まず、turbo R ではカセットテープインターフェースがなくなったので、従来のBIOSにあった"TAPION"、"TAPIN"、"TAPIOF"、"TAPOON"、"TAPOUT"、"TAPOOF"をコールすると、キャリーフラグがセットされ、エラーとしてリターンする。また、"STMOTR"もなくなり、コールしても何もしないでリターンする。  また、メインROMの容量を変えずに新しい機能を追加するために、パドルとライトペンのBIOSが削除された。BIOSの"GTPDL"をコールすると、Aレジスターにかならず0が入ってリターンする。同様に、"GTPAD"または"NEWPAD"で、Aレジスターにライトペンを指定する8〜11の値を入れてコールしても、Aレジスターにはかならず0が入ってリターンする。  変更されたBIOSとしては、使用中のMSXバージョンを知るためにの、"ROM version ID"。これはメインROMの002DH番地の内容でわかり、turbo R の場合は03Hに変更された。turbo R 用にプログラムを開発するなら、まずこの値が03H異常であることを確かめ、そうでなければ、MSX2用のプログラムとして動作させるか、あるいはエラーメッセージを表示して中断させるようにしよう。  なお、002DH番地の内容が03Hの場合のみに動くようなプログラムは、将来MSXがバージョンアップしたときに動かなくなってしまうので、かならず03H以上ならば動くように作る必要がある。一般的に、ハードウェアやOSのバージョンについては、自分が必要とするバージョン番号以上の値を得られれば、ソフトウェアが動作するようにプログラムしておこう。  これは過去において実際にあったことなのだけど、MSXのバージョンのチェックを誤ったために、MSX2+では動かないMSX2用プログラムや、学習機能付きのMSX-JEと組み合わせると動かないアプリケーションなどが、できてしまう。それを避ける意味でも、"03H以上なら動くようにする"ということを、忘れないでほしい。  また、BIOSと同様に、turbo R になってのBASICの機能にも追加や変更、削除があった。それらについては、表1.3や、マシン付属のBASICマニュアルを参照してほしい。 1.2.5 アプリケーション開発に関する注意点  MSX turbo R では、R800 は常にノーウェイトで動作しているわけではない。外部スロットをアクセスするときに3ウェイト、内部ROMをアクセスするのに2ウェイト、そして内部のDRAMがページブレークを起こしたときに1ウェイトかかるのだ。そこで、プログラムの高速化をはかるには、こうしたウェイトをできる限り減らすことを考えながら、作業しなくてはいけない。そのための注意点を3つほどまとめてみたので、覚えておこう。  まずひとつ目は、プログラム自体をRAMに転送してから実行させること。フロッピーで供給されているソフトウェアは、必然的にRAMで動作するので問題ないのだけど、注意したいのはスロット上にROMカートリッジで供給されるプログラム。必要な部分だけをRAMに転送してから実行させることで、かなりの高速化が可能になる。  ページブレークを起こさないようにコーディングすることも大切だ。R800では、DRAMのページアクセスをサポートする専用のバスを持っているんで、この機能を最大限に活用しよう。具体的には、アドレスの下位8ビットだけが変化するような連続したメモリー、つまり??00H〜??FFHまでの256バイトの範囲で、メモリーアクセスが行われるようにプログラムするのが効果的だ。  ちなみに、ページブレークを起こした状態とういうのは、この範囲を超えてメモリーアクセス行われた場合、つまりアドレスの上位8ビットが変化した場合のことを呼んでいる。  前にもちらっと書いたのだけど、turbo R では MSX2+ などとは違い、プログラムのコーティング段階で命令の実行時間が正確にわかるわけではない。その理由としてあげられるのが、いつ発生するか予測のつかないDRAMのページブレークと、Z80 などとは違って、命令の実行とは非同期に行われるDRAMへのリフレッシュがあるからだ。  また、turbo R と MSX2+ のどちらでも動作するようなプログラムを作るのに、ソフトウェアループによってタイミングをとることは勧められない。そこで turbo R には、3.911マイクロ秒ごとにカウントアップするシステムタイマーが、新たに搭載された。これからは、このシステムタイマーを利用して、タイミングをとるようにしよう。 1.2.6 CPUを切り替えるプログラムの例  リスト1.2は、CPU を切り替える"CHGCPU.COM"のソースリストだ。turbo R で DOS2 が動いているときに、 CHGCPU 0 でZ80 モードが、 CHGCPU 1 で R800 の ROMモードが、 CHGCPU 2 で R800 の DRAM モードが、それぞれに選択される。プログラムの内容を解析すると、DOS のワークエリア(正確には default FCB area ) の 5DH 番地からコマンドの第1パラメータの先頭の文字を得て、それじ応じて A レジスターの値を設定。そして、メインROMの180H番地のBIOS、"CHGCPU"を呼び出すというものだ。  また、プログラムにより実効性を持たせるため、DOSのバージョン番号をチェックする処理も加えてある。具体的には、まずメインROMの2DH番地の内部が03H以上である、つまりturbo R であることを確かめ、DOS のシステムコールの6FHを使って、DOSのカーネルのバージョンが2以上であることを確かめている。 【リスト1.2(CHGCPU.Z80)】  同様に、次のリスト1.3は、MSX2用のプログラムを R800 モードでだまして動かす、"GAMEBOOT.COM"のソースリストだ。このプログラムは、DOS2が起動され R800 が選択されている状態で、ほかのディスクに入っているプログラムを起動するためのもの。つまり、DOS2のシステムがふくまれていないプログラム(ゲームなど)を、強引に R800 モードで動かすためのものだ。  簡単にプログラムを解説していうと、まず画面にメッセージを表示して、ディスクが交換されるのを待つ。次に、交換されたディスクのブートセクターを読み込んで、それを交換させる。そのときの環境は、普通の方法でブートセクターが2回目にコールされるときと同じで、ページ1はDOSのROM、そのほかのページはRAM、キャリーフラグはセットされている。  さらに、エラー処理プログラムへのポインターの、ポインターを記憶するためのDOSのワークエリア(F323H番地)をHLレジスターに、またページ1をRAMからDOSのROMへ切り替えるプログラムの番地(F368H番地)をDEレジスターに、それぞれ設定している。 【リスト1.3 (GAMEBOOT.Z80)】