超小型Z80マイコン(その5)Z80 INIR命令の中断 [Z80]
以前、PIC24 を使った 3 チップ構成の Z80 シングルボードを開発した際に「レトロマイコンZ80ボードの構想(その10)CP/M80 BIOS検討2 」の記事で Z80 が HALT 状態( HALT 命令を繰り返している状態)の時にメモリ上の HALT のコードを別のコード(例えば NOP )に書き換えることで HALT から抜け出せないか実験したことを書きました。メモリ上の HALT コードを書き換えても HALT 状態は継続されるという結果でした(コメント欄に書いたように適切なタイミングでリセット信号をアクティブにすると HALT から抜け出せる: Z80 スペシャルリセットと言うようです)。
今回の開発では「超小型Z80マイコン(その3)hello表示」の記事に書いたように I/O 入力データを HL の示すメモリに書き込む動作を B レジスタ 分繰り返す INIR 命令のコードを PIC がデータバスに直接出力することで Z80 の初期起動( boot )を実現しています。
ここで素朴な疑問が湧いてきました。
INIR 命令実行中にメモリの内容を別の命令に書き換えたら Z80 はどう動くのか?
気になりますねぇ ・・・ 確かめてみました。
今回開発中の Z80PicCompact では ROM を実装していないため、Z80 を boot する際に PIC 側から INIR のコードをデータバス上に出力して Z80 に実行させています。Z80 が I/O 入力した際も PIC がロードしたいプログラムのコードをデータバス上に出力しています。
boot 処理用のデータを下記のように B レジスタの値を実際にロードするコードより 32 増やした状態にして INIR の命令を 4 回目に実行するタイミングで、Z80 に対して JP 0100H( C3H,00H,01H )の命令を渡した場合( Z80 からはメモリ上のコードが突然ジャンプ命令に変わったように見える)の挙動を確認してみました。
下図が上述したことを実行した際のロジアナ波形です。
黄色い矢印部分がそれぞれ INIR 命令を実行している箇所です。この 3 回の INIR 命令によってメモリ上の 0x0100 のアドレスに JP 0100H のコードが書き込まれます。カーソルで囲った部分で PIC が INIR 命令の代わりに JP 0100H 命令( 0xc3, 0x00, 0x01 )をデータバスに出力しています。
その直後の 0.84 us と時間表示されている部分がメモリの 0100H 上にある JP 0100H を始めて実行している部分で(Z80 は 12MHz 動作で JP は10クロック必要)、その後ジャンプ命令でループしています。
従って確認結果は「Z80 は INCR 命令を連続して実行中にフェッチコードが別の命令になった場合にはフェッチした命令を実行する」と言うことになります。
Z80PicCompact の boot 処理では、 INIR 命令を実行する前に B レジスタを設定していました( I/O アドレスは何でもいいので C レジスタは設定していません)。
しかし、今回の結果から B レジスタ自体の設定も不要であり、ロードするコードのバイト数も 256 バイト以上でも問題ないということが判りました。面白いですね。
[TOP] [ 前へ ] 連載記事一覧 [ 次へ ]
今回の開発では「超小型Z80マイコン(その3)hello表示」の記事に書いたように I/O 入力データを HL の示すメモリに書き込む動作を B レジスタ 分繰り返す INIR 命令のコードを PIC がデータバスに直接出力することで Z80 の初期起動( boot )を実現しています。
ここで素朴な疑問が湧いてきました。
INIR 命令実行中にメモリの内容を別の命令に書き換えたら Z80 はどう動くのか?
気になりますねぇ ・・・ 確かめてみました。
今回開発中の Z80PicCompact では ROM を実装していないため、Z80 を boot する際に PIC 側から INIR のコードをデータバス上に出力して Z80 に実行させています。Z80 が I/O 入力した際も PIC がロードしたいプログラムのコードをデータバス上に出力しています。
boot 処理用のデータを下記のように B レジスタの値を実際にロードするコードより 32 増やした状態にして INIR の命令を 4 回目に実行するタイミングで、Z80 に対して JP 0100H( C3H,00H,01H )の命令を渡した場合( Z80 からはメモリ上のコードが突然ジャンプ命令に変わったように見える)の挙動を確認してみました。
Z80PicCompact の boot処理用のデータ(抜粋) |
---|
#define PROG_START 0x0100 // program start address #define PROG_SIZE ( sizeof( Prog ) / sizeof( uint8_t ) ) // program size const uint8_t Prog[] = { // must be smaller than 0x0100 0xc3 ,0x00 ,0x01 }; const uint8_t LoadCode[] = { 0x21 // LD HL,PROG_START ,PROG_START & 0x00ff ,PROG_START / 256 ,0x06 // LD B,PROG_SIZE ,PROG_SIZE + 32 // ,0xed // INIR // ,0xb2 }; |
下図が上述したことを実行した際のロジアナ波形です。
INIR 命令を JP 命令に変更した際の挙動(サンプリング:25MHz) |
|
黄色い矢印部分がそれぞれ INIR 命令を実行している箇所です。この 3 回の INIR 命令によってメモリ上の 0x0100 のアドレスに JP 0100H のコードが書き込まれます。カーソルで囲った部分で PIC が INIR 命令の代わりに JP 0100H 命令( 0xc3, 0x00, 0x01 )をデータバスに出力しています。
その直後の 0.84 us と時間表示されている部分がメモリの 0100H 上にある JP 0100H を始めて実行している部分で(Z80 は 12MHz 動作で JP は10クロック必要)、その後ジャンプ命令でループしています。
従って確認結果は「Z80 は INCR 命令を連続して実行中にフェッチコードが別の命令になった場合にはフェッチした命令を実行する」と言うことになります。
Z80PicCompact の boot 処理では、 INIR 命令を実行する前に B レジスタを設定していました( I/O アドレスは何でもいいので C レジスタは設定していません)。
しかし、今回の結果から B レジスタ自体の設定も不要であり、ロードするコードのバイト数も 256 バイト以上でも問題ないということが判りました。面白いですね。
[TOP] [ 前へ ] 連載記事一覧 [ 次へ ]
コメント 0