2013.1.8
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第287回]


●どうすればアドレスセットでの誤動作を回避することができるのでしょうか?

前回ロジアナ波形で実証しましたように、IMSAI8080のフロントパネル回路を踏襲したREAD(アドレスセット&リード)回路は、CPUがZ80系である場合にはZ80で拡張された命令が仇となって誤動作してしまうことがあります。
前回までのところではREAD回路についてのみ検証してきましたが、拡張命令のゆえに誤動作してしまうという点ではC3H(JP命令)の代わりに00H(NOP)を挿入するREAD NEXT回路でも全く同じです。

前回までの説明をもういちど以下に整理してみます。
CPUが命令コードを読み込むときは、そのマシンサイクルがOPコードフェッチであることを示す信号としてMREQ、RDとともにM1がアクティブになります。
IMSAI8080のフロントパネル回路を踏襲したE−80(仮称)ミニコンのREAD回路はそのM1の期間にデータバスに強制的にJP命令のOPコードC3Hを挿入することで、パネルスイッチで設定したアドレスにCPUを強制的にJPさせて、結果的にパネルスイッチで設定した値をアドレスLEDに表示させます。
それはCPUが8080であるときはそのまま正しく行われるのですが、CPUがZ80系の場合には、誤動作してしまう可能性があります。
Z80で拡張された命令の多くは2バイトのOPコードをもっており、M1(OPコードフェッチ)も2回連続して行われます。
たとえばIN A,(C)の命令コードED78はEDも78もともにOPコードです。
もしもCPUが第一のOPコードEDを読み込んだあと、次の第二のOPコード78を読もうとしているときに、データバスにC3Hを挿入した場合には、CPUはそれをJP命令としてではなく、EDC3という2バイトの拡張命令コードとして読み取ってしまいます。
EDC3という命令コードは存在しないため、E−80(仮称)ミニコンのCPU、Z8S180では未定義命令割込みが発生して0000Hに無条件ジャンプしてしまいます。
結果としてパネルスイッチの値はアドレスLEDに表示されないことになります。
この例の場合にはたまたまEDC3が未定義命令コードなので、そのような結果になりましたが、未定義命令コードにならない場合でも誤動作してしまうことには違いはありません。
たとえばCBC3としてCPUが読み取った場合、それはSET 0,Eとして実行されますからその場合でもJP命令は実行されず、やはりパネルスイッチの値はアドレスLEDには表示されません。
C3Hの代わりに00Hを挿入することで行われるREAD NEXT回路についても同じことが言えます。
たとえばED00は未定義命令コードなのでEDC3と同じことが起きますし、CB00はRLC Bとして実行され、READ NEXTで期待されるように次のアドレスがアドレスLEDに表示されることにはなりません。

このような誤動作は拡張命令の2番目のOPコードフェッチサイクルでWAITが検出され、そこでCPUが停止してしまった場合に発生します。
2番目のM1(OPコードフェッチサイクル)で停止してしまっても、そこでリセットすればCPUは必ずアドレス0000Hの命令を読むところで停止しますから(E−80(仮称)ミニコンのフロントパネル回路では、WAIT信号はリセットスイッチによっても解除されない仕組みになっています)、そのときCPUは最初のM1で停止していることになり、上で説明したような誤動作は発生しません。
ですから、パネルスイッチのREAD、READ NEXT等を操作するのに先立ってまずリセットスイッチを押すという手順を徹底すれば、この問題は解決します。
パネルスイッチの機能から考えると、STOP後にいきなりREAD NEXT、WRITE、WRITE NEXTの各操作をすることは通常は考えられません。
問題は新たなアドレスをパネルスイッチから設定するREADの操作にしぼられると思います。
パネルスイッチを操作するモード(パネルモード)では、多くの場合プログラムは0000Hから書き始めることになると思いますし、プログラムの実行を開始するときも0000Hからスタートすることになると思います。
アドレスを0000Hに設定する一番簡単な方法はリセットすることです。
ですから、0000H以外のアドレスを設定する場合でも、まず先にリセットしてから、パネルスイッチをそのアドレスに設定してREADスイッチを押す、という操作ルールにすることにはそれほど違和感はないかと思います。

ただ操作に慣れてきますと、なかなかそのようには素直に操作してくれなくなります。
ついショートカットをやるようになります。
ええ。
私自身が操作していて、そのように感じました。
まずSTOPして、それからパネルスイッチでアドレスを指定して、それからRESETして、それからREADを押して…。
と操作すべきところなのですが、つい、STOP→パネルスイッチセット→READというように操作してしまいます。
ここで間に入るRESETというのは結構邪魔っけな操作に思えます。
なんとかできないものか…。

●そこをなんとかしてしまうための回路です

前置きがめちゃめちゃ長くなってしまいました。
さて。
その、なんとかならないものか、ということなのですが。

STOPスイッチを押してWAIT信号がM1のタイミングでアクティブになるときに、それが拡張命令の2番目のM1であったときがそもそもの問題なのですから、なんとかして、拡張命令のときでも必ず1番目のM1でのみWAITがアクティブになるように考えることができれば問題は解決します。
実は後で調べてわかったことなのですが、Z8S180の場合には…。

うわあっ。
まさか…。
そんなことが…(しばし絶句)。
新年早々、またもやとんでもない思い違いをしておりました。
またやってしまいました…。
もう、病気とも言うべき見事な思い込みで…。

正月の休みの何日かをつぶして、せっせとこの説明のために撮りためた写真や回路図や、おお、それに、改造して追加してしまった回路なども、ぜーんぶ無駄作業じゃありませんかあ。

実はZ8S180にはそれを簡単にクリアできる機能が備わっています。
この問題をクリアしようと考え始めた段階で、そのことには気がついていました。
しかし、ああ、なんという痛恨のミス…!
どこをどう読み間違えたのか、その機能はE−80(仮称)ミニコンに採用したZ8S180(68pinPLCC)には無くて、80pinQFPのみの機能だと思い違いをしてしまいました。
当記事を書くためにさきほどZ8S180のUSER MANUALを調べていて、それが68pinPLCCにもちゃんとあることに気が付きました(とほほ、なんという…)。

私はてっきりZ8S180(68pinPLCC)にはそんな機能は無いものだと思い込んでしまったものですから、作る必要のない回路までわざわざ作ってしまって、おまけにご丁寧にも、その回路でも動作の様子をロジアナで観測したり、回路の写真を撮ったりしてしまいました。

あ。
しかし、まあ、考えてみれば、全くの無駄作業でもないかもしれません。
Z8S180では簡単な回路で済むことがわかりましたが、CPUがZ80の場合には、やはり私が考えたような回路が必要になります。
ひょっとすると、当記事を参考にして、どなたかがZ80を使ってIMSAI8080風フロントパネル回路の製作に挑戦されるかもしれません。
そのような場合には、今回の回路が参考になるかもしれません。

ということで。
Z8S180ではこんなことをする必要はありませんが、Z80ならばこういうことになりますよ、という回路をお見せすることにいたします。

これは[第285回]でお見せしましたSTOP回路部分の回路図です。


それを下図のように変更します。

Z8S180ではこんなことをする必要がないことがわかってしまいましたので、なんだか気が抜けてしまいました。
ですので簡単に説明をいたします。
回路図の上のほうのごちゃごちゃしたところで何をやっているのかといいますと、ここで拡張命令の第一バイトの検出をしているのです。
Z80で拡張された2バイト命令コードの最初の1バイトのコードはCB、DD、ED、FDのいずれかです。
そのコードを2進数で表現しますと
CB  11001011
DD  11011101
ED  11101101
FD  11111101
です。
D0〜D7の各ビットのうち、なるべく同じ組み合わせのところはまとめて1つの回路になるように考えて、上の4つのコードのときに74HC74のD入力がHになるようにしました。
なおたとえば4入力NANDゲートなどを使えばもう少し簡単な回路にすることができますが、近年製造中止になるICが増えてきています。
ですからなるべく基本的なゲートのみで組み合わせるように心がけています。
またそのほかのゲートについてもインバートしたりしてなかったりといろいろ使っていますが、これは1つのパッケージの中にある複数のゲートをできるだけ有効に使おうとした結果こうなっているだけで他意はありません。

中間に置いた74HC74の役目ですが、そのようにして検出した拡張命令の第一バイトか否かという情報を次の2番目のM1クロックのときまで保存するために使われています。
これは拡張命令ではない場合には全く余計なことをしていることになりますが、とにかくM1サイクルが来たときに、その1つ前のM1のときにどうだったか、がわかればよいわけですから、こういう回路になりました。
この回路によって、74HC73がSTOPスイッチからの入力信号をラッチするためのクロック信号は、1サイクル前のM1のときにデータバスの値がCB、DD、ED、FDだったときにはアクティブにはなりません。

こちらが上の回路を追加して、ロジアナで測定中の写真です。

左下のジャノ目基板が追加回路です。
右下に見えているのがカメレオンUSB+ロジアナです。

ジャノ目基板部分です。


このように追加した回路によって、STOP信号が拡張命令の2番目のM1サイクルのときに入力されても、WAITがアクティブにはされない様子をロジアナで観測して確認いたしました。
本日は時間がなくなってしまいましたので、ロジアナで記録した波形は次回にお見せすることにいたします。

ワンボードマイコンでCP/Mを![第287回]
2013.1.8upload

前へ
次へ
ホームページトップへ戻る