MSX Datapack wiki化計画

2章 割り込み

 この章では、MSXの割り込みについて解説します。
 MSXはZ80の「モード1割り込み」と呼ばれる割り込みを使用しています。これは、割り込みがかかると必ず38H番地をコールするという割り込みモードです。MSXのMAIN ROM内の割り込みルーチンで処理していることを、以下に解説します。

リスト2.4 割り込みシーケンス

   全てのレジスタ(裏レジスタ、IX、IY共)をセーブ
   H.KEYIを呼ぶ
   ライトペンの処理
   VDPのステータスレジスタを読む
   if 垂直帰線割り込み {
          H.TIMIを呼ぶ
          割り込みの許可
          STATFLの設定            /* 【STATFL(0F3E7H)】 */
          ON SPRITEの処理
          ON INTERVALの処理
          JIFFY = JIFFY + 1       /* 【JIFFY(0FC9EH)】 */
       PLAY文の処理
          SCNCNT = SCNCNT - 1     /* 【SCNCNT(0F3F6H)】 */
          if SCNCNT = 0 {
                 SCNCNT = 2
                 ON STRIGの処理
                 キーボードのスキャン
          }
   }
   全てのレジスタ(裏レジスタ、IX、IY共)をリストア

 MSXの割り込み源のうち、システムが管理するのは垂直帰線割り込みだけです。周期はNTSC版の場合1/60秒、PAL/SECAM版の場合1/50秒です。日本版はNTSCですから、1/60秒になります。
 また、VDPのステータスレジスタを読む際には、単にポート099Hを読むだけですから、ステータスレジスタポインタが0以外だと、割り込みがかかりっぱなしになり、MSXは暴走することになります。ステータスレジスタポインタを0以外に変更するときには必ず割り込みを禁止してください。そして、0に戻してから割り込みを許可してください。

 【JIFFY(0FC9EH)】は垂直帰線割り込み毎にインクリメントされる1ワードの変数ですので、時間をカウントするのに使用することができます。

 【SCNCNT(0F3F6H)】はキーボードおよびジョイスティックのスキャンを間引くためのものです。MSXでは2回の割り込みで1回スキャンされることになります。

 ON STRIGの処理を行うためジョイスティックがスキャンされますが、このときジョイスティックポート1、2ともに、6、7番ピンがHIGHに、8番ピンがLOWになります。ジョイスティックポートに接続するための周辺機器を設計して、これらのピンを出力ピン(MSXから見て)として使用する際、このことに充分注意してください。

 具体的には6、7番ピンはHIGHが、8番ピンはLOWが定常状態となるように設計して、アクセスするときは割り込みを禁止して行う設計にしてください。

 【H.KEYI(0FD9AH)】は割り込みがかかると必ず呼ばれるフックです。垂直帰線割り込み以外の割り込みを処理するようなルーチン(RS-232Cや水平帰線割り込みなどのハンドラ)は、このフックを使用します。【H.TIMI(0FD9FH)】は垂直帰線割り込みがかかると呼ばれフックです。

 割り込みフックの使用法には次の2種類があります。

1.JP命令を書く

 ゲームなどのプログラムでは、一番効率の良い方法です。
 
 前提条件としては、いつ割り込みがかかっても割り込みハンドラがCPU空間に出ていなければならないことです。つまり割り込みハンドラが「スロットが切り替わる可能性のあるページ」にいてはならないことになります。

 割り込みハンドラからリターンするときには、

1) そのまま「RET」命令を実行する
2) スタックを1段ポップして、すべてのレジスタをリストアして「RET」命令を実行する
3) セーブしてある、以前のフックにジャンプする

などの方法があります。

 1)では、MAIN ROMの割り込み処理が続行しますので、上で述べた処理(キーボードのスキャンなど)が必要なときは、この方法を採用します。ただし、割り込みフックを設定する前に、他のプログラムが既にこのフックを使用していたときは、それは無視されます。

 2)では、MAIN ROMの割り込み処理は完全に無視されます。最高の効率が必要な場合はこの方法を採用します。ただし、MAIN ROMの割り込み処理が前提となっているような機能(BIOSのCHSNS、CHGETなど)のサービスは受けられません。また、以前の割り込みフックは無視されます。

 3)では、MAIN ROMの割り込み処理、以前の割り込みフックともに、実行されます。具体的には、フックを設定する前に、5バイトのセーブエリアにフックの内容をコピーして、それからフックを設定することが必要です。割り込みハンドラが終了したら、このセーブエリアにジャンプします。これを割り込みのチェーンと呼びます。

2.RST 30H (FAR CALL)命令を書く

 システムの一部として組み込まれる機能(例えば、RS-232C)を処理する割り込みハンドラは必ずこのようにしなければなりません。システムとして動いているときは、スロットが頻繁に切り換わるためです。

 また、割り込みのチェーンも完全に行わなければなりません。よく、「ディスクのアクセスランプが光ったままになってしまう」という現象がありますが、これは割り込みのチェーンを行っていないプログラムが動いているからです。ほとんどのディスクドライバは垂直帰線割り込みを使用して、モーターON・OFF(アクセスランプのON・OFF)を行っています。

 添付のフロッピーディスクに、「INT.MAC」という名前のサンプルプログラムが入っています。