Z80 PIOの割り込み使用時は割り込みモードとリセット回路に注意
はじめに
先日記事を投稿したZ80ワンボードコンピュータでZ80 PIOを用いた割り込みを掛けようとしたとき、ハード・ソフト両面で工夫が必要であることが分かったので、備忘録を兼ねて執筆する。
PIO割り込みがかからない
PIOの割り込みを使ってみるべく、以下のツイートのようなプログラムを書いてみた。このプログラムでは、PIOのBポートに接続したスイッチのうち、いずれかがON (Lレベル)を検知したら割り込み処理に移行し、Lレベルを検知したビットに対応するLEDを5回点滅させる、というプログラムである。
このプログラムを、件のワンボードコンピュータで実行しようとしたところ、スイッチ入力によってプログラムが停止する、という現象を確認した。
この不具合の現象確認として、INT信号の波形をオシロで検出しようとしたところ、割り込みがかかるタイミングでINT信号が出ていないことが分かった。
原因と対策
上記の確認通り、PIOからINT信号が出ていないことが問題である。このINT信号が出ない原因をソフト・ハードの両面で調査を進めたところ、以下の原因であることが分かった。
ソフトの問題
まずソフト面の原因としては、割り込みモードをモード2にしていたことにあることが分かった。Z80 CPUの割り込みには3種類のモードがあり、割り込み時にCPUは以下のように動作する。
- モード0:INT信号がLになったのを検出したとき、CPUから制御信号をペリフェラルに送り、ペリフェラルから命令コードを受け取って実行する割り込み。Intel 8080と互換性のある割り込みモードである。
- モード1: INT信号がLになったのを検出したとき、固定で0x0038番地にジャンプする割り込み。
- モード2: Z80ペリフェラル用割り込み。INT信号がLになったのを検出すると、CPUから制御信号をペリフェラルに送り、ペリフェラルから返ってきた割り込みベクトルと、Iレジスタによって指定されるアドレスにジャンプする。そして、ジャンプした先に書かれた割り込み開始アドレスにさらにジャンプし、ジャンプ先で割り込み処理を実行する割り込み。
当初作成していたプログラムでは、モード2の割り込みを使用していたのだが、モード1の割り込みを使用することで割り込み動作ができることを確認した。
本来は、モード2の割り込みでも正常に実行できるはずなのだが、著者の力量不足により実現できなかった、というのが実情である。つまり、ソフト面については妥協することで解決(?)した。
ハードの問題
前節の通り、割り込みモードをモード1に設定することにより、INT信号がLになることでCPUで割り込みを検出できるようになったのだが、以下の2条件で割り込みがかからないことが分かった。
- 割り込み処理中にリセットがかかった場合
- 割り込みがかかる状態のままメインルーチンに戻った後、リセットがかかった場合
このことから、Z80 PIOのリセット方法を確認したところ、以下のツイートのようなリセット回路が必要であることが分かった。
この回路は、PIOのリセットがM1端子にクロックが2周期以上入ることが条件になるためである。このため、ワンボードコンピュータの回路を、下図のように変更した。
この回路変更により、不具合が起きていた2条件に対しても、割り込みが掛けられることを確認した。
まとめ
当初PIOの割り込みが掛けられなかった原因として、主に2つの原因があることが判明した。
- ソフト面:モード2の割り込みを使用していた。
- ハード面:PIOのリセット回路が不適切だった。
ソフト面の原因は、筆者の力量不足によるところなので今後の改善に期待するとして、問題なのはハード面である。Z80 PIOは、同時期に発売されたパラレルI/O LSIと比較し、非常に多機能であった反面、リセット回路が外部回路だよりになっている。このため、Z80シリーズを使用する際は、データシートをよく読み、適切な回路設計を行うことが必要となる。(Z80に限った話でもないが…)
参考文献
[1] 横田英一, Z-80の使い方, オーム社, 1993
[2] 額田忠之, Z80ファミリ・ハンドブック, CQ出版, 1985
投稿者の人気記事
-
4558D
さんが
2023/10/27
に
編集
をしました。
(メッセージ: 初版)
-
4558D
さんが
2023/10/27
に
編集
をしました。
-
4558D
さんが
2023/10/27
に
編集
をしました。
ログインしてコメントを投稿する