Z80でEI直後のDI実行後の割込み許可状態 [Z80]
Z80 の EI(割込み許可)命令は割込み処理終了時の RET の直前で EI を実行した場合にスタックがオーバーフローしないように、EI の次の命令を実行してから割込み可能な状態になります。
それでは EI の直後に DI を実行した場合、結果として割込みは可能/禁止のどちらになっているのか??
確認してみましょう。
Z80 は LD A,I または LD A,R を実行した場合、フラグレジスタの P/V フラグに割込み許可状態を示す割込みフリップフロップ(IFF)の状態がコピーされます。
IFFは
0 : 割込み禁止
1 : 割込み可能
です。
Z80 のフラグレジスタの構成を下図に示します。
ディバッガ(ZSID)を使って検証してみました。(zsidm は使用する RST 命令を変更したもの)
フラグレジスタのコピーである L レジスタの値が 40H になっていて P/V フラグは立っていない(IFF=0)ことから「Z80 では EI 直後に DI を実行した結果として割込みは禁止状態になる」と言う結果でした。
上記で使用した IFF の確認方法は NMOS 版の Z80 にはバグがあるとのことが知られています。
・Z80のバグ
今回使用した Z80 は CMOS 版( Zilog 製の Z84C0020PEC )で、何度かやってみましたが同じ結果でした。
Z80 の EI 命令は次の命令の M1 サイクルの最終クロックで割込みフリップフロップ(IFF)を1にして割込み可能にします。
このため、EI 命令直後に割込みが入ると都合が悪いので EI 命令の RFSH サイクルの最初のクロックで IFF をクリアして EI 直後に割込みが入らないように実装されています。
Twitter 情報での eX1turboZ の場合は、上記の EI が IFF を設定するタイミング( Z80 では M1 )とクリアするタイミング( Z80 では RFSH )の順番が逆転しているものと推測されます。
つまり、「 Z80 では EI,EI の後方の EI では M1 で IFF がセットされ、 RFSH で IFF がクリアされますが eX1turboZ では IFF をクリア後、セットされるので DI,EI,EI,DI で割込みを受け付ける」と考えられます。
eX1turboZ が EI,EI で EI 直後に割込みを受け付けた場合、次の命令の M1 で IFF を設定する機能がどう動くかが気になりますね(IFF:1 の状態で割込み処理が動く可能性も考えられる)。
因みに Z80 が INT 信号をチェックするタイミングは各命令の最後のクロックの立上り時点であり、INT信号が有効(low)な場合は同クロック内で IFF がクリアされます。その後、インターラプトアクノリッジの M1 サイクルが実行されます。
尚、Z80 の細かい挙動に関しては Twitter で教えてもらった The Brain Dump のサイトに詳しく書かれています。
}
それでは EI の直後に DI を実行した場合、結果として割込みは可能/禁止のどちらになっているのか??
確認してみましょう。
Z80 は LD A,I または LD A,R を実行した場合、フラグレジスタの P/V フラグに割込み許可状態を示す割込みフリップフロップ(IFF)の状態がコピーされます。
IFFは
0 : 割込み禁止
1 : 割込み可能
です。
Z80 のフラグレジスタの構成を下図に示します。
Z80 のフラグレジスタ |
|
ディバッガ(ZSID)を使って検証してみました。(zsidm は使用する RST 命令を変更したもの)
EI 直後の DI 実行結果 |
---|
a>zsidm ZSIDM Ver 1.4 #a100 0100 DI 0101 EI 0102 DI 0103 LD A,I 0105 PUSH AF 0106 POP HL 0107 NOP 0108 NOP 0109 NOP 010A . #d100 10f 0100: F3 FB F3 ED 57 F5 E1 00 00 00 52 49 47 48 54 20 ....W.....RIGHT #g100 107 *0107 #x -Z--- A=00 B=0000 D=0000 H=0040 S=0100 P=0107 ----- A'00 B'0000 D'0000 H'0000 X=0000 Y=0000 NOP # |
フラグレジスタのコピーである L レジスタの値が 40H になっていて P/V フラグは立っていない(IFF=0)ことから「Z80 では EI 直後に DI を実行した結果として割込みは禁止状態になる」と言う結果でした。
上記で使用した IFF の確認方法は NMOS 版の Z80 にはバグがあるとのことが知られています。
・Z80のバグ
今回使用した Z80 は CMOS 版( Zilog 製の Z84C0020PEC )で、何度かやってみましたが同じ結果でした。
★追記 2022/09/23 {
Twitter で DI,EI,EI,DI を実行した場合は eX1turboZ では割込みを受け付ける( Sharp 製 Z80 の LH0080 では受け付けない)との情報を頂きました( DI,EI,DI では受け付けない)。Z80 の EI 命令は次の命令の M1 サイクルの最終クロックで割込みフリップフロップ(IFF)を1にして割込み可能にします。
このため、EI 命令直後に割込みが入ると都合が悪いので EI 命令の RFSH サイクルの最初のクロックで IFF をクリアして EI 直後に割込みが入らないように実装されています。
Twitter 情報での eX1turboZ の場合は、上記の EI が IFF を設定するタイミング( Z80 では M1 )とクリアするタイミング( Z80 では RFSH )の順番が逆転しているものと推測されます。
つまり、「 Z80 では EI,EI の後方の EI では M1 で IFF がセットされ、 RFSH で IFF がクリアされますが eX1turboZ では IFF をクリア後、セットされるので DI,EI,EI,DI で割込みを受け付ける」と考えられます。
eX1turboZ が EI,EI で EI 直後に割込みを受け付けた場合、次の命令の M1 で IFF を設定する機能がどう動くかが気になりますね(IFF:1 の状態で割込み処理が動く可能性も考えられる)。
因みに Z80 が INT 信号をチェックするタイミングは各命令の最後のクロックの立上り時点であり、INT信号が有効(low)な場合は同クロック内で IFF がクリアされます。その後、インターラプトアクノリッジの M1 サイクルが実行されます。
尚、Z80 の細かい挙動に関しては Twitter で教えてもらった The Brain Dump のサイトに詳しく書かれています。
}