Z180 MPU

このZ180 MPUは、日立がオリジナルを開発して、Zilog社はセカンドソースです。日立がHD64180でZ80 CPU上位互換プロセッサの分野に進出しましたが、最初のHD64180はZ80ファミリの周辺LSIを利用するのに問題がありました。その問題点を解決したのがHD64180Z系列のマイクロプロセッサで、さらにそのセカンドソースにZilog社が名乗りをあげてZilog式のシリーズ名称にしたのがZ180 MPUです。型番としてはZ80180となります。ですから、本来は日立のところに掲載すべきですが、手持ちがZilog製品なので、こちらに置いておこうかなと。
HD64180にZ80ファミリの周辺LSIを利用しにくい原因は、クロック高速化の際に外部回路を設計しやすくするために改良されたはずのバスタイミングにありました。Z80ファミリの周辺LSIは割り込み処理のために自分がアクセスされていないときでもバスの状態を監視し、プロセッサが読み込む命令列を解読しています。ごく単純なものとはいえ命令解釈機構が組み込まれているわけです。ですから、命令をプロセッサが読み込むタイミングが異なってしまうと、バスを覗き見してプロセッサが読む命令列を取り込むことができなくなります。というわけで、周辺LSI組み込みの割り込み処理機構を利用できなくなってしまいます。また、一部の周辺LSIについてはI/Oバスサイクルも互換性がない場合があります。
Z180 MPUは、これらの問題点を解決したプロセッサではありますが、巷でよく語られるように、Z80 CPU互換のバスサイクルタイミングに変更したプロセッサではありません。実はかなり変わった方法で解決しています。まず、リセット直後はZ180 MPUといえど、HD64180と同じバスタイミングで動作します。内部の制御レジスタを設定して初めて、Z80ファミリのLSIを使えるタイミングに変更されます。しかしこのモードでも命令フェッチサイクルは実はHD64180と同じもので、RETI命令の実行サイクルにZ80ファミリのLSIを動かすための特別なサイクルが追加されるという形になっています。というわけで、そのタイミングも完全互換でないため、Z80 CPUで動作しているデバイスドライバをそのまま利用できない場合すらあります。

Z180 MPU
最大クロック周波数10 MHzのZ180。

もう少し詳しくZ80 CPU, HD64180, Z180 MPUの違いを見ていきます。
Z80 CPUでは命令フェッチサイクルが4クロックで構成され、おおまかにいえば前半2クロックで実際の命令フェッチを、後半2クロックでメモリのリフレッシュサイクルを実行します。RDストローブ信号は約1.5クロック幅です。命令フェッチ直後はプロセッサ内部で命令解読を行ってから命令ごとに異なる実行サイクルに入る必要があるため、命令解読時間の間は外部バスが空きます。その間にダイナミックメモリのリフレッシュを行うのは、合理的な考え方でした。しかし4クロックのM1サイクルに命令フェッチとリフレッシュサイクルを押し込めていますから、3クロックの一般のメモリリードサイクルのRDストローブ信号が約2クロック幅なのに対し、M1サイクルは約1.5クロック幅と狭くなり、メモリ回路のタイミング設計が厳しくなります。リフレッシュされるメモリ側から考えると、M1サイクルにつき1回だけリフレッシュが行われますから、実行時間の長い命令を連続して実行した場合にリフレッシュ不足にならないか検討が必要ですが、2.5 MHzクロックで動作するZ80 CPUなら充分な余裕があります。
このように初期のZ80 CPUならタイミング的に厳しいところがあってもクロック周波数が低くてメモリ回路設計に余裕がありましたが、だんだんにZ80 CPUが4 MHz, 6 MHz, 8 MHzクロックと高速化されてくるとそんな余裕がなくなってきます。さらに、リフレッシュし過ぎという欠点が目立ちはじめます。2.5 MHzクロックでも一般的なプログラムにおける命令実行過程では多めのリフレッシュサイクルが実行されていたのに、8 MHzクロックともなると必要量より1桁多いリフレッシュサイクルが実行されてしまいます。それ自体はメモリの機能において直接の悪影響はありませんが、よけいなリフレッシュサイクルの分だけ消費電力が増大して発熱も増えます。
HD64180では、これらのM1サイクルに伴う問題を解決するため、M1サイクルからリフレッシュ機能を取り除きました。リフレッシュ機能はプログラム可能なタイマによって一定周期ごとに起動される、独立したバスサイクルに変更されました。命令解読も高速化されているため、M1サイクルも一般のリードサイクルも同等の3クロックサイクルとなり、RDストローブ信号も約2クロック幅と広がり、外部回路も設計しやすくなります(データを内部にラッチするタイミングが一般のリードサイクルよりM1サイクルの方が0.5クロック早いが)。1クロック分、命令実行時間も得をして、処理性能の高速化にも役立ちます。ついでにI/Oリードライトサイクルも改良され、IORQストローブ信号やRDストローブ信号が0.5クロックだけ早くアサートされて、アクセスタイミング余裕も増えました。その結果、8 MHzクロックや10 MHzクロックでも、外部のメモリやI/Oポートのタイミングに余裕ができ、設計しやすくなりました。
と、ここまでは良いことばかりですが、残念ながら意外なところで問題が生じます。Z80ファミリの周辺LSIがうまく動かないという問題です。HD64180はZ80 CPU上位互換のプロセッサですから、Z80 CPUの置き換えに利用したいと誰でも考えます。ところがZ80 PIOやZ80 SIOを接続しても、割り込み処理を中心に正常に動作しないという現象が生じます。これは、M1サイクルが変更されたため、2 Byte命令であるRETI命令をプロセッサが読み込む際に1 Byte目と2 Byte目を読み込む間の時間間隔が短くなり、周辺LSIがRETI命令を読み込んで割り込み禁止状態から割り込みを受け付けられる状態に遷移することがうまくできなくなるのが原因です。周辺LSIは割り込み要求をプロセッサに伝える際、それ以降の割り込み要求受付を禁止します。プロセッサがRETI命令で割り込みハンドラを終了するとき、そのRETI命令のフェッチを周辺LSIも監視していて、周辺LSI側の割り込み要求受付禁止状態を解除して、次の割り込みに備えます。このようにして、異常に割り込みのネストが深くならないように調整して、多重割り込みを処理するのがZ80ファミリの割り込みの特徴です。Z80ファミリの周辺LSIではRETI命令検出以外に割り込み調停機構にに割り込みハンドラ終了を伝える手段のない方が普通です。というわけで、周辺LSIが想定しているM1サイクルと異なるタイミングで命令フェッチを行うと、周辺LSIの割り込み調停機構が正常に動作しなくなり、その結果、割り込みを利用できなくなります。わざわざZ80ファミリの周辺LSIを採用するのは、その高性能の割り込みを利用するのが動機であることも多いですから、これでは困ります。また、周辺LSIの中にはプロセッサとのデータの授受にIORQストローブ信号やRDストローブ信号だけでなくプロセッサのクロック信号も併用するものもあり、ストローブ信号とクロック信号のタイミング関係が異なってしまうHD64180ではアクセス自体が正常に行えないものもあります。
これらの問題点を解決すれば、HD64180でZ80ファミリの周辺LSIを利用できるようになります。しかし単純にZ80 CPUと同じタイミングに戻したのでは、もともとのZ80 CPUのタイミング関係の欠点が目立つようになります。そこで日立は改良版のHD64180Zにおいて、別の方式での解決方法を採用しました。
HD64180ZではZ80周辺LSIとの互換をとるとめに内蔵I/Oレジスタのオフセット3EHにOperation Mode Control Register (OMCR)が新設されました。このOMCRのビット割り当ては次のようになっています。

bit
名称
意味
7
M1E
M1 Enable
6
M1TE*
M1 Temporary Enable
5
IOC*
I/Oタイミング調整
4
---
予約
3
---
予約
2
---
予約
1
---
予約
0
---
予約

上位3 bitだけに役割があり、下位5 bitは予約ビットとなっています。これらのビットのリセット後の初期値はすべて1で、このとき、HD64180と完全互換の動作を行います。リセット直後はHD64180とまったく同じ動作をしますので、そのままHD64180に差し換えることも可能です。
M1Eビットを0にすると、HD64180Zは唯一の例外を除いてM1信号をアサートしなくなります。すなわち、外部回路からはインストラクションフェッチサイクルを区別することができず、通常のメモリリードサイクルしか行っていないものと扱われます。で、その唯一の例外ですが、RETI命令の命令実行サイクルなのです。RETI命令のインストラクションフェッチは通常のリードサイクルと同様、M1信号はアサートされません。しかし、命令実行サイクルにおいて、ダミーのRETI命令コードの再読み込みを行います。この再読み込みはZ80 CPUと同一の信号タイミングで、M1信号もアサートされるのです。Z80ファミリの周辺LSIの側では、このダミーの再読み込みがRETI命令のフェッチであるかのように認識することとなり、LSIに内蔵された割り込み調停機構が正しく動作するというわけです。
こんな方式ですべて丸くおさまるか、気になります。RETI命令の実行サイクル以外にM1信号がアサートされないわけですから、他の動作でM1信号を利用している周辺LSIがあれば、そちらに悪影響が出るはずです。実際、問題が生じます。Z80ファミリの周辺LSIでは、コントロールワードに割り込み許可を書き込んでも、すぐには割り込みが有効にはなりません。そのあとのM1信号のアサートを確認してから本当の割り込み許可が実行されます。すると、M1Eを0にしたHD64180ZではRETI命令を実行するまでは割り込みが生じないことになります。割り込み発生源がZ80周辺LSIだけだと、RETI命令が実行されるのは割り込みハンドラ内だけですので、割り込みが発生するまでは割り込みが許可されないということになり、永遠に割り込みが無効のままです。いや、仮に割り込み発生源が別に存在したとしても、次にRETI命令が実行されるまでに周辺LSIの中の割り込み要求源が複数回割り込み要求を出してしまえば、最後の1回を除いて割り込みの取りこぼしが生じます。いずれにせよ、プログラマの意図したタイミングで割り込みが許可されないわけで、これは重大な問題です。
それを解決するためにあるのがM1TE*ビットです。このビットに0を書き込むと、その直後の1回のM1サイクルだけM1信号がアサートされます。M1TE*ビットは自動的に1に戻り、この効果は1回限りで消えます。ですから、周辺LSIのコントロールワードに割り込み許可の意味を持つデータを書き込んだあとに、M1TEビットをリセットする命令列を実行させればよいわけです。M1TEビットを操作する必要のある条件ではM1Eビットも後述のIOC*ビットも0になっているはずですから、OMCRに0を書き込むだけで目的を達成できます。
IOC*ビットを0にすると、I/OバスサイクルのIORQ, RD*信号が常にZ80 CPUと同一のクロックタイミングで変化するようになります。
結局、HD64180ZでZ80ファミリの周辺LSIを利用する場合、次の手順を取ることになります。まず、リセット直後のプロセッサ内蔵レジスタ類の初期設定時に、OMCRレジスタに40Hを設定します。この初期化は外部のZ80ファミリの周辺LSIの初期設定に先立って行わなくてはなりません。さらに、周辺LSIの割り込みを許可する際には忘れずにM1TE*ビットを制御してM1信号をアサートさせます。前者は、いずれにせよHD64180系列のプロセッサを利用するときにはリフレッシュ挿入タイミングや自動ウェイト挿入の設定のためにプロセッサ内蔵レジスタを初期設定する必要がありますから、そのついでに行えば問題ありません。しかし後者の操作に関しては、Z80 CPUを採用したシステムで動作していたデバイスドライバをそのまま利用するわけにはいかず、ソースコードへの追加なりパッチなりでコードの変更が必要になります。アルゴリズム的な変更ではなく、1箇所につき2命令の追加ですからたいした手間ではありませんが、変更箇所が複数あってそのうちのひとつの修正を忘れたりすると、不可解な症状で悩むかもしれません。

まぁ、長々と書いてしまいましたが、Z80ファミリの周辺LSIを利用できるようにした上で、HD64180とも完全な互換性を持つプロセッサが、HD64180Z、Zilog社の名称ではZ180 MPUというわけです。

Return to IC Collection