[1chipMSX改]
V9958調査資料 〜割り込み系〜
V9958 には、下記の2種類の割り込みを発生させる機能がある。
(1) 垂直同期割り込み
(2) 水平同期割り込み
(1) は、表示モニタのブランキング期間が始まるタイミングで発生していると思われる。
つまり、割り込みの発生時点は、かならずモニタはブランキング期間であるといえる。
厳密には、"割り込み発生時" とは、V9958 が INT_N を L にするタイミングのことであり、CPU がそれを認知して割り込み処理ルーチンへ
ジャンプするタイミングのことではない。
なぜならば、Z80 が DI 状態の場合は、V9958 が割り込み信号を発生させても CPU は割り込み処理ルーチン(0038h)へジャンプしないからだ。
その場合、EI 状態になり次第、割り込み処理ルーチンへ飛ぶため、非ブランキング期間であるケースもある。
MSX-BASIC や、MSX-DOS などのシステムでは、この垂直同期割り込みを様々な用途に利用している。
たとえば、キーボードの状態は、PPI によってポートに現れているだけで、割り込みやDMAのようなものは装備していないため、
CPU からポーリングする必要がある。上記システムでは、垂直同期割り込みの中でポーリングを実施して、システムワークエリアの
決まったアドレスに値をコピーしたり、キーバッファを処理したりしている。
この割り込み処理ルーチンが、VDP R#15 が 0 であること(ステータスレジスタ0 を指していること)を期待しているため、
R#15 を 0 以外に書き換えて割り込み許可するとシステムは暴走してしまう。
本来ならば、タイマー割り込みを使ったり、キーボード割り込みを使って処理するのが今時の普通だと思うが、MSX には、タイマー割り込みや
キーボード割り込みが存在しないため、VDP の垂直同期割り込みをタイミング制御に使うのが一般的となっている。
モニタの垂直同期信号をトリガにするため、NTSC-60Hz の環境では 60Hz、PAL-50Hz の環境では 50Hz のタイミングで割り込みが発生する。
そのため、NTSC と PAL では割り込み間隔が異なり、たとえば垂直同期割り込みでタイミングをとってる BGM ドライバソフトなどは、
NTSC と PAL の環境で演奏テンポが変わってしまったりする弊害がある。
NTSC よりも PAL の方がブランキング期間が長いため、それを利用した海外製ソフトもある。そういうソフトは、単純に NTSC で表示させても
処理が間に合わなくて正常動作しないケースがある。
1chipMSX[KAI] では、VGA出力時に強制的に NTSCモード固定にしている。
VGA出力は、60Hz(多少のマージンはある)で動作するため、50Hz で表示更新しても正常に画像が表示されない。
かといって、VDPの動作タイミングは 50Hz で、表示は 60Hz とすると、VRAM へのアクセス頻度が上がり、結果として DRAMバンド幅不足に陥り
破綻してしまう。
Altera DE1 のように、別途SRAM が搭載されている場合は、SRAMをフレームバッファとすることで解決はできる可能性があるが、
私にはそこまでして PAL専用アプリを動かしたいという気持ちはないため、今のところそのような機能を実装する予定はない。
(2) は、別名「走査線割り込み」と呼ばれるものである。
VDP R#19 に走査線番号を指定すると、モニターがその走査線を表示しているタイミングで割り込み発生させる機能である。
割り込み発生ラインは1つしか指定できないため、画面の複数箇所で発生させたい場合は、割り込み処理ルーチンで次のライン番号を再設定
する必要がある。
MSX は、割り込み信号をキャッチしてから、割り込みルーチンへジャンプするまで 10usec程度かかるようで、一般的な命令もそれほど速くないため
走査線割り込みですぐ次のラインを指定しても間に合わないことが多い。
少なくとも、MSX-BASIC などで利用される標準の割り込み処理ルーチンを生かしたまま、割り込みフックで処理しようとすると数ライン下のライン
でも割り込みが間に合わないことに注意しなければならない。
頻繁な走査線割り込みを望むなら、page0 を DRAM に切り替えて、軽量な自作割り込みルーチンを 0038h に置くべきである。
走査線割り込みでもう一つ注意すべき点は、ブランキング期間に相当するライン番号を指定しても、割り込みが発生しない点である。
一定ライン間隔で走査線割り込みを発生させることで、1/60秒よりも高精度なタイマー割り込みとして使えるが、その際にその割り込み非発生エリア
のラインを指定してしまうと、うまく処理が回らなくなるので要注意だ。
具体的には、R#23 = 0 (垂直スクロールなし)の状態で、垂直192ラインモードなら、235〜255ラインを指定しても割り込みが発生しない。
垂直212ラインモードなら、245〜255ラインを指定しても割り込みは発生しない。
また、R#18 (SetAdjust) によって垂直方向に画面位置をずらしていても、この非割り込み発生エリアの範囲・位置は変わらない。
1chipMSX[KAI] のアーカイブの test_program/bench にその確認プログラムを入れていある。
オリジナルの 1chipMSX や、一部のエミュレータなどは、この辺の挙動が若干本物と食い違っているようで、モニタの絶対的な表示位置によって決まって
いるようだ。そのため、R#18 によって垂直位置をずらすと、割り込み非発生エリアのライン番号が影響される。そのような環境でも動く予定のソフトは、
その辺を踏まえて SetAdjust の極端な設定値のケースをテストしておくべきだ。
[▲上へ]