割り込み

割り込み周りのハードウェア構成

 MZ-700の割り込み源は、8253のチャネル2からのタイマ割り込みのみです。15.7kHzのクロック入力をチャネル1で分周したものをさらにチャネル2で分周し、その周期で割り込みをかけることができます。8253からの割り込みは、8255 ポートCのINTMSKビットによってハードウェア的に許可/禁止することができます。

 INTMSK = 1 の状態で8253のチャネル2の出力がHになると、CPUに割り込みがかかります。

 8253をタイマ割り込み源として使用する際は、チャネル1をモード2に設定、チャネル2をモード0に設定します。割り込みの周期は 約15.7kHz を (チャネル1のカウント設定値)×(チャネル2のカウント設定値+1) で割ったものになります。チャネル2のカウント設定値が+1される理由は、モード0ではカウント値をチャネルに書き込んだ後の最初の入力クロックの有効エッジで書き込んだカウント値がカウンタにロードされ(注)、次の入力クロックの有効エッジで初めてカウントダウンされるためです。
 1, 2の両チャネルで最低でも2分周されるため、最短の割り込み周期は15.7kHzの1/4、約 3.925kHz となります。

Z80の割り込みモード

 MZ-700では、Z80の割り込みモードは常に 1 を使用します。割り込み源となるデバイスが8253しかなく、モード2の割り込みベクタを発生するようなデバイスも存在しないためです。割り込みモード1では、割り込みサービスルーチンは0038hに固定となります。
 また、MZ-700にはZ80ファミリの周辺LSIが使われていないので、割り込みからの復帰に RETI 命令を使う必要はありません。RET 命令でOKです。

 モード1における割り込みの応答時間は 13CPUクロック(RST 38hの実行に11クロック+ウェイト2クロック)です。

ROMモニタ(1Z-009A/B)での割り込み

 ROMモニタでは、チャネル1に15700を、チャネル2に43200(=60*60*12)を設定し、約12時間ごとに割り込みをかけて午前/午後の切り替えを行うことで、8253を計時用のタイマとして使用しています。

 ROMモニタの0038h番地には“JP 1038h”が置かれており、割り込みが発生すると1038hにジャンプします。

割り込みの初期化


	DI                  ; 割り込みを禁止
	IM    1             ; Z80 割り込みモード1

	LD    HL, 0E007h    ; 8253 コントロールポート
	LD    (HL), 0B0h    ; チャネル2, モード0, 下位バイト→上位バイトの順にカウンタを設定        
	LD    (HL), 074h    ; チャネル1, モード2, 下位バイト→上位バイトの順にカウンタを設定        
	DEC   L             ; 8253 チャネル2
	LD    (HL), CNT2L   ; チャネル2のカウント値の下位バイトを設定
	LD    (HL), CNT2H   ; チャネル2のカウント値の上位バイトを設定
	DEC   L             ; 8253 チャネル1
	LD    (HL), CNT1L   ; チャネル1のカウント値の下位バイトを設定
	LD    (HL), CNT1H   ; チャネル1のカウント値の上位バイトを設定

	LD    A, 05h        ; INTMSK = 1 に設定し、8253からの割り込みを許可する
	LD    (0E003h), A   ; 8255 ビットセット

	EI                  ; 割り込みを許可

割り込みルーチンでの処理

 チャネル2にカウント値を再設定します。これにより8253のチャネル2の出力がLに戻り、Z80への割り込み要求が止まります。

	(レジスタ保存)

	LD    HL, 0E006h    ; 8253 チャネル2
	LD    (HL), CNT2L   ; チャネル2のカウント値の下位バイトを設定         
	LD    (HL), CNT2H   ; チャネル2のカウント値の上位バイトを設定

	(割り込み処理)

	(レジスタ復帰)
	EI                  ; 割り込みを許可
	RET                 ; メインの処理に戻る

垂直ブランキング割り込みの代用

 MZ-700は垂直ブランキング信号による割り込みを持っていません。しかし、タイマ割り込みのクロック源である15.7kHzに水平ブランキング信号が使用されているため、カウント値を設定するタイミングを合わせることで、タイマ割り込みを垂直ブランキング割り込みの代わりとして利用することができます。カウント値は次のように設定します。
チャネル設定値備考
11311画面分のラスタ(262本)の1/2
21モード0で設定可能な最小カウント値(2分周)

 8253を垂直ブランキング割り込み源として設定するサンプルを以下に示します。

	LD    HL, 0E007h    ; 8253 コントロールポート
	LD    (HL), 90h     ; チャネル2, モード0, 下位バイトのみでカウンタを設定        
	LD    (HL), 54h     ; チャネル1, モード2, 下位バイトのみでカウンタを設定
	DEC   L             ; 8253 チャネル2
	LD    (HL), 1+1     ; チャネル2のカウント値+1を設定 (注)

	XOR   A
	LD    L, 02h        ; 8255 ポートC
 L1:	OR    (HL)          ; /VBLKをチェック
	JP    P, L1         ; /VBLK=Hになるまで待つ
 L2:	AND   (HL)          ; /VBLKをチェック
	JP    M, L2         ; /VBLK=Lになるまで待つ

	LD    L, 05h        ; 8253 チャネル1
	LD    (HL), 131     ; チャネル1のカウント値を設定


(注) カウント値の反映されるタイミングについて

 モードセット後に書き込んだカウント値、およびモード0で再設定したカウント値が反映されるタイミングは、クロック入力の次の立ち下がり(H→L)ではなく、クロック入力の次のパルスの立ち下がり(L→H→L)のようです。つまり、クロック入力がLの期間にカウント値を書き込んだ場合はクロックの次の立ち下がりで反映されますが、クロック入力がHの期間にカウント値を書き込んだ場合はクロックの次の次の立ち下がりで反映されます。

 垂直ブランキング割り込みの代用など、カウント値を設定するタイミングを調整することで表示回路に同期する割り込みをかける場合、上記の仕様を考慮しないと期待どおりの結果になりません。垂直ブランキング割り込みのサンプルでは、チャネル2のカウント値設定時には入力クロックがHであるため、カウント値を+1して設定しています。また、割り込み応答直後は入力クロックがLであるため、Hになる前に素早くカウント値を再設定する必要があります。(約140クロック以内)


戻る