スプリアス割り込みの中の人も(以下略)

貴方の愛機のMFPは大丈夫?


スプリアス割り込みは、本来なら発生することのない割り込みです。
しかし、残念なことにX68Kシリーズにおいて、この割り込みが発生してしまうハード・ソフトの組み合わせが存在します。

どうやらMC68901(以下MFP)に個体差があり発生する機体とそうでない機体が存在することは確実です。

しかし、この問題はソフトウェアで解決可能であるのでハズレ機体をつかんだとしても悲観することはありません。ご安心下さい。

というわけで、MFPを操作するプログラムを作成する場合に注意しなければならない点を以下で考えてみましょう。


スプリアス割り込み発生の流れ

MFP周辺部の動作を大雑把に考えてみることにしましょう。

以下は

とでも考えて下さい。

  1. デバイス「?」からの割り込みを禁止にするため、MFPのレジスタが操作される。
    同時にデバイス「?」からMFPに割り込み要求が来る。
     
  2. MFP内部では、まだ「?」割り込みの禁止状態になっていない(動作中)。
    MFPからMPUに割り込み要求が出される。
     
  3. MFP内部で「?」割り込みが禁止状態になる(レジスタの該当ビットが変化)。
    MPUが該当するレベルで割り込み禁止状態でなければ
    割り込み応答サイクルにはいる。
     
  4. MFPはMPUが割り込み応答サイクルに入ったことを検出し
    割り込みベクタを出力しようとする。
     
  5. ところが、該当する割り込み「?」はMFP内部で既に禁止されているので
    MFPは割り込みベクタをMPUに出力できない。
    (実際なら
    出力可能なベクタはデバイスからデータバスの下位8ビット上に出力され
    さらにデバイスはDTACK信号を用いて「ベクタ出力中」とMPUに通知します。
    逆に、MPU自体は割り込み応答サイクルの間は
    デバイスからDTACK信号が帰ってくるのを待っているということです。)
     
  6. いつまで待ってもDTACK信号が帰ってこないので
    バスエラー信号が出力される。
    (例えば、メモリ空間に存在しない番地にアクセスを行なったときに
    メモリ側からDTACK信号が帰ってこない場合と処理的には一緒です。)
     
  7. MPUは割り込み応答サイクル中にバスエラー信号を受けたので
    内部で自動的にベクタ番号$18(=スプリアス割り込み)を
    発生させる。
     

ここでポイントとなるのは、MFP自体が$18のベクタを出力しているのではない、ということです。


対処方

デフォルト設定ではスプリアス割り込みが発生するとエラー処理に移行してしまいます。
Human68kではtrap#14のエラー処理ルーチン(いわゆる白窓)が起動しますし、起動中などBIOS ROM内部処理のでは再起動を要求されてしまいます。

そこで、スプリアス割り込み対策を以下に例示します。

(方法その1)
MFPでデバイス毎の割込み禁止設定をする際には
必ずSR操作で割込みレベルを上げておく。

基本的に下記のようなコードになるものと思われます。

	ori.w	#$0700,SR		*割り込み禁止
	(MFP操作命令が入る)
	andi.w	#$F5FF,SR		*割り込みレベル5(MFPの割り込みレベル6を許可)

ところで、MFPで割込み禁止した直後にSRでの割込みレベルを下げた場合でも、MFP内部で割り込み禁止状態になる前にMPUが割り込み応答サイクルに入ってしまうことが判っています。
(つまりスプリアス割り込みが発生してしまう)

具体的な例としては、X68030リリース以前に作成されたゲームなどがX68030上で動作しない原因として、この症状がいくつか見られました。

そこで、MFPを操作した後、割り込みレベルを戻す前に

	tst.b	$E9A001		*8255(ジョイスティック)の空読み
	nop			*直前までの命令パイプラインの同期
				*早い話、この命令終了までには
				*それ以前のバスサイクルなどが
				*完了していることが保証される。

を挟んでやるといいと思います。

(方法その2)
スプリアス割り込みそのものを無視する。

スプリアス割り込みの発生はMFPの動作に支障をきたすというわけでもないので
ベクタ$18の飛び先に

	rte

だけがあればそれでも構いません。


終わりに

手元で実験した限りでは、エミュレータ上ではスプリアス割り込みは発生しませんでした。エミュレータ上で作成したプログラムが実機上で不具合発生……。実機ならではの挙動の奥の深さに貴方も触れてみては如何でしょうか。

初出:Offside X680x0@29/dec/1996


一階層戻る