前回の記事ではロジックICによるハードウェア割り込みコントローラーを構成しましたが、インテル80系にはプログラマブル割り込みコントローラー 8259がありますので、こんどはそちらでシリアル2系統化してみたいと思います。
回路について
ユニバーサルボードで試作した回路図は以下のような感じです。ほぼSBC8080バスに割り込みコントローラー8259とプログラマブルタイマー8254をぶら下げたかたちになっています。
- 8259の割り込み入力のIR7とIR6へはシリアルA/Bを接続します。前回つくったロジックICの割り込み制御回路と互換性を維持するためです。(ROMをなるべくいじりたくなくて….) また、8254タイマーICの出力はIR5〜3へ接続しました。
- 8259にはアドレスバスA0が接続されています。コマンドによってI/Oアドレス40hと41hを使い分けます。
- アドレスデコーダーはいつもの74HC138で、今回はイネーブル端子(E1、E2、E3)にA7〜A6を入れてI/Oアドレス40h台に小さめに割り付けてみました。
- 74HC74 Dフリップフロップは7.3728MHzを4分周するのにつかっています。プログラマブルタイマー8254のクロックにはそのくらいの周波数の方がいいかなと。
- 8254のG端子(GATE)は全部10kΩでプルアップしちゃいました。これはPC-9801とかPC/ATとかでこんな感じの回路になっていたのを真似しました。(細かいコントロールはいらないかなと….)
- ちなみに、今回実験したのはシリアルLSI 8251×2+割り込みコントローラー8259で2シリアルで動くかというところなので、8254を動かした記録は別記事でまとめる予定です。
割り込みコントローラー8259の動き
割り込みコントローラー8259は、割り込み入力ピンIR0〜IR7に割り込み要求(Hレベル)が来ると、CPUの割り込み要求(INT)をHレベルにします。
CPUは割り込みを受け付けるとINTA出力をLレベルにして応答してきます。8259はそれを受けると割り込み入力ピン(IR0〜IR7)に応じたCall命令(CDh)+Call先アドレス下位1バイト+Call先アドレス上位1バイトの3を順にデータバスに応答します。
CPUはデータバスよりCall命令とアドレスをフェッチして該当のアドレスをCallします。前回は1バイトのRST命令をロジックICでデータバスに載せましたが、8259はCall命令を乗せることができるので64kバイトのどこのアドレスでもジャンプできます。
ただし、「どこでも」と言いつつ後述するように起点となる割り込みベクタアドレスの上位ビットをプログラムでセットするので、ジャンプできる場所は割り込み入力に対して4バイト単位、8バイト単位の範囲に限定されます。自由自在にCallアドレスを決定できるわけではありません。アドレス上位ビットをすべて0(ゼロ)にして8バイト単位に割り込みベクタを設定した場合は以下のようなイメージとなります。
割り込みコントローラー8259の初期化
割り込みコントローラー8259はデータシートを見ていただけるとわかりますが、インテル社の他のペリフェラル同様 初期設定コマンドが必要です。
前回ロジックICで作った割り込みコントローラー同様、0番地からの8バイト単位のアドレスへCallするように仕込んでみたいと思います。
以下は初期設定コマンドICW1とICW2のパラメーターです
ICW1 (Initialization Command Word 1)
ビット位置 | 説明 | 今回の設定値 |
D0 | ICW4の有無 | 0 : ICW4なし (8086モード設定などに使う) |
D1 | シングル/カスケード接続 | 1 : シングル |
D2 | Call アドレス間隔 | 0 : 8バイト |
D3 | トリガーモード | 0 : エッジトリガーモード |
D5〜D6 | 割り込みベクタアドレス A7〜Z5 | 000 : 0番地からの8バイトおきの アドレスへCallするため |
ICW2 (Initialization Command Word 2)
ICW2は割り込みベクタアドレスの上位8ビット分ですので、今回は0番地からのアドレスに割り付けるので00hとします
8259初期化のASMコード例
上記の構成で8259へ初期化をする際は以下のようなZ80アセンブラコードとなります。前回2シリアル対応したGrant’s機械語モニターやCP/M BIOSの初期化部分に追加する必要があります。
; 8259 INIT
LD A,00010010b
OUT (PICRC),A
XOR A
OUT (PICRD),A
割り込みルーチンの考慮点(EOIコマンド発行)
8259割り込みコントローラーは割り込み要求を発行したのち、EOI(End of Interrupt)コマンド待ちとなります。よってシリアル割り込みルーチンなどの最後に8259割り込みコントローラーへ 20h(EOIコマンド)を出力して割り込み処理終了を知らせてあげる必要があります。
シリアルAの割り込み処理の最後にEOI命令を追加したソース例が以下になります。この割り込み処理ルーチン自体はSBC8080データパックのソースからいただいたものです。
SERINT_A: PUSH AF
PUSH HL
IN A,(UARTRC_A)
AND 00000010B
JP Z,RTS0_A
IN A,(UARTRD_A)
PUSH AF
LD A,(SERCNT_A)
CPI BUFSIZ
JP NZ,NOTFUL_A
POP AF
JMP RTS0_A
NOTFUL_A: LD HL,(SERINP_A)
INC HL
LD A,L
CPI SERINP_A & 0FFH
JP NZ,NOTWRP_A
LD HL,SERBUF_A
NOTWRP_A: LD (SERINP_A),HL
POP AF
LD (HL),A
LD A,(SERCNT_A)
INC A
LD (SERCNT_A),A
CPI BUFFUL
JP C,RTS0_A
LD A,RTSHIG
OUT (UARTRC_A),A
RTS0_A:
;
LD A,00100000b
OUT (PICRC),A
;
POP HL
POP AF
EI
RET
試作してみた
ユニバーサル基板でこの回路を試作してみました。SBC8080バスとほぼ直結ですので、地道に配線するのみです。特に注意点はありません。
そういえば回路図を手を抜いてバイパスコンデンサを省略していました。各LSI/ICごとにいつもの0.1μFのセラミックコンデンサをVcc端子近傍に装着するのが吉です。
上記写真のうち右側は今回の8259搭載ユニバーサル基板をSBC8085と組み合わせて稼働させてみたものとなります。(さんざんZ80のコード例を掲載しておきながらCPUは80系の8085ですが…..理由は後述します。)
写真に見える赤と青のケーブルはそれぞれシリアルA、Bの割り込み用結線となります。(実際は8251シリアルLSIのRxRDY信号(データ1バイト受信したよ信号)です。)
上記のようにTeraTERMを2枚開いて、それぞれでCP/Mの起動まで確認できました。前回のロジックICの場合も一緒ですが、Grant’s機械語モニター起動時にシリアルAかBをスペースバー押下して選択し、それ以降は選択したほうのシリアルで作業を実施します。同時に2シリアルが使えるわけではありません。
ハマったポイントについて
KiCADの回路図シンボルに注意!
いつものようにここまで順調に来たかのように書いてますが、試作したときにKiCADの回路図記号を鵜呑みにしてハマりました。
一緒にユニバーサル基板に搭載した8254タイマーICはIN/OUT命令に反応してきたのですが、8259割り込みコントローラーはIN命令にいつもFFhを返してくるので 当初はLSIが壊れているのかと疑っていました。
原因を調査すべく8259のデータシートを呆然と見ていて、違和感がありまして…..RDとWRのピン番号逆ぢゃん!!! KiCAD標準でついてくる8259割り込みコントローラーの回路記号のRDとWRが逆になってました。
KiCAD4時代から治っていないらしいです。みなさん注意です。プリント基板作る前に気づいてラッキーでした。
Z80の簡易? INTA発生回路では8259はダメらしい
前回のロジック回路の割り込みコントローラーを作成したときもSBC8085と同様のINTA信号(割り込み受け付けたよ信号)を発生させる回路(ORゲート1つ追加)をKZ80-CPUBに取り付けました。Z80 CPUはペリフェラルLSIからの割り込み要求(INT)を受けるとM1信号とIOREQ信号を同時にLレベルにしてきます。それをOR回路であわせて出力するかたちとなっています。
8259割り込みコントローラーもそのINTA信号発生回路で行けると思い込んでいたのですが、どうも8085 CPUとZ80 CPUではINTA信号の発生挙動に違いがあるようです。いろいろなZ80の書物で「ペリフェラルは割り込み(INT)要求の後、データバスにRST命令かCall命令を載せ….」と書いているので完璧に信じ込んでました。
Z80 CPUが割り込み受付時にM1とIOREQの信号線をLレベルにするのは1発だけらしいのです。これだとCall命令はフェッチできてもCall先アドレスはRAMからフェッチしてしまって思った通りの挙動になりません。(X_X)>
この対応はまたちょっと一工夫必要ですので。次回 説明できたらと思います……
コメント
[…] 前回、80系割り込みコントローラー8259をSBC8080バスにつなぐボードを作りましたが、SBC8085とは正しく接続できるものの前々回のKZ80-CPUB(Z80 CPU)のINTA信号発生回路では割り込みコントローラー8259は正しく動作しませんでした。 […]