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

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

[第301回]


●アドレスLEDの上位8ビットには何が?

前回の最後に書きました、プログラム実行中に消灯しているはずのアドレスLEDの上位8ビットが点灯してしまうという現象につきまして、その理由は、皆様お分かりになりましたでしょうか?
しかも、ただ無意味に点灯しているのではなくて、アドレス上位8ビットの設定スイッチ(PROGRAMMED INPUTと兼用)の状態と連動しているように見えます。

それを確認するために、プログラムを実行したままの状態で、PROGRAMMED INPUTスイッチを全部上側(11111111)にしてみました。
すると。


スイッチに連動してA11〜A8の赤LEDがぼんやりと点灯しました。
A15〜A12の青LEDは写真でははっきりとは見えませんが、やはり薄く光っています。
これは前回も書きましたように、赤LEDと青LEDの輝度の違い(赤のほうがはるかに明るい)によるもので、もしA15〜A8が全部赤LEDでしたら、全てが同じように光っているはずの状態です。

なぜこのようなことになるのでしょうか?
Z80に詳しい方ならば、あるいはご存知かと思います。

実は、犯人はZ80のIN命令とOUT命令だったのです。
その証拠をこれからご覧いただくことにいたします。

●STEP動作

E−80(仮称)ミニコンのフロントパネルにはSTEP動作の機能があります。
通常はCPUは供給されているクロックにしたがって目には見えない超高速で命令を実行します。
その実行速度はといいますと、CPUクロックが10MHzの場合に、1つの命令を0.4μsec〜2μsecほどで実行してしまいます。
まさに目にも留らぬ速さです。
したがってその動作を目で見て確認することはとてもできません。
ビット数が多いためオシロスコープでも確認は困難で、ロジアナでやっと確認ができるレベルです。

STEP機能はそのように普通は確認が困難なCPUの動作を1ステップ(マシンサイクル)ごとに停止させて、静止した状態で見ることが出来るという便利な機能です。
ちょうど連続して動いて見える動画のコマを1コマずつ再生して見るようなものです。

今回のように、ただ見ただけでは何がおきているのかわからないような時に、このSTEP動作は威力を発揮します。
ND80ZV(ND80Z3.5)にもステップ機能はありますが、それはソフトウェア的に見かけ上1命令ごとに動作しますから、今回のようにアドレスラインのハード的な確認のためには、残念ながら役には立ちません。
ND80ZV(ND80Z3.5)のステップ動作(TK−80も同じ)は、1命令ごとに進みますが、E−80(仮称)ミニコンのステップ動作(IMSAI8080も同じ)は、1マシンサイクルごとに進みます。

あ。
論より証拠、でありました。
それではSTEP動作の実際をご覧ください。

まず最初にRESET(CPU RESET)スイッチを押します。

アドレス表示LED(A15〜A0)は全部消灯して現在のアドレスが0000Hであることを示しています。
データバス表示LEDにはメモリの0000H番地の値(DBH)が表示されています。
DBHはIN命令の命令コードです。
左側の上から2段目にはCPUの状態を示すLEDが並んでいます(CPU STATUS)。
ちょっと見難いですが、左端(MEMRD)と右から2番目(M1)が点灯しています。
いまがOPコードフェッチサイクルであることを示しています。

次にSTEPを押しました。

アドレスが1つ進んでアドレスLEDの表示は0001Hになりました。
データバスLEDにはメモリの0001Hの値(FFH)が表示されています。
これだけを見るとREADやWRITEの操作結果と同じように思えます。
しかしよく見ますと大きな違いがあります。
左側のCPU STATUSの表示を見てください。
MEMRDだけが点灯しています。
READやWRITEの操作ではCPUをM1サイクルでのみ停止させますから、常にMEMRDとM1が点灯します。
そのことは前回の写真を見ていただくことで確認できます。
また常にM1サイクルで停止させることにつきましては[第285回]で書きました。
それに対してステップ動作は、本当にCPUを1ステップ(マシンサイクル)ごとに動作させます。
たとえばIN A,(FF)という命令(16進数コードDBFF)をCPUが実行する場合を考えますと
1)最初にまず命令コードDBHをメモリから読む
2)次に命令のオペランド部(FFH)をメモリから読む
3)アドレスFFHからデータを読み込んで、その値をAレジスタにセットする
の3ステップ(マシンサイクル)の動作になります。
上の写真はその2番目のステップですから、そこはもうM1(OPコードフェッチサイクル)ではなくて、メモリからデータを読むサイクルですから、M1が消灯してMEMRDだけが点灯するのです。

STEPを押しました。
注目していただきたいのはここです。

IN A,(FF)の3番目のステップ(マシンサイクル)です。
CPUはI/Oアドレスからデータを読み込むために、アドレスバス下位8ビットにFFHを出力します。
これはI/O READサイクルですから、IORDが点灯します(ちょっと文字が見難いですが、CPU STATUSの左から3番目の緑LEDです)。
実際にI/OアドレスのFFHからデータを読み込んでいることをはっきりさせるために、PROGRAMMED INPUTスイッチをそれまでの56H(01010110)から78H(01111000)にしました。
データバスLEDはそれに連動して瞬時に78Hが表示されました。

ところで、このときのアドレスバスの上位8ビットには何が表示されていますでしょうか?
56Hが表示されています。
これが犯人の正体です。

実はZ80のIN命令(コードDBH)とOUT命令(コードD3H)は、I/Oアドレスをアドレスバスの下位8ビットに出力すると同時に、その命令を実行する直前のAレジスタの値を上位8ビットに出力します(どうしてこんな余計なことをしてくれるのか、理由はよくわかりませんが、Z80はそのように設計されているようです。これは64180にも受け継がれていて、当然のことながらZ8S180でも同じ動作になります)。

上のタイミングでは、IN A,(FF)を実行する直前のAレジスタには、それ以前に実行されたIN命令で読み込んだ値(56H)が入っていたため、A15〜A8には、その56Hが出力されています。
ここでPROGRAMMED INPUTスイッチの値を78Hに変更したため、それは直ちにデータバスLEDの表示に反映されていますが、まだIN命令は完了していないため、Aレジスタの値は変化していません。
ですからA15〜A8の表示には、新しい入力スイッチの値ではなくて、それ以前の値が表示されています。

普通は確認することができない、こういう細かいCPUの動作まで把握することができる、というところがE−80(仮称)ミニコンの特記すべき優れた点であると思います。

STEPを押しました。

IN命令の実行が完了して、アドレスバスには次のアドレス0002Hが表示され、データバスにはメモリの0002H番地の値D3Hが出力されています。
ここは次の命令を読むタイミングなので、MREQとM1が点灯して、それがOPコードフェッチサイクルであることを示しています。

STEPを押しました。

アドレスが1つ進んでアドレスLEDの表示は0003Hになりました。
データバスLEDにはメモリの0003Hの値(FFH)が表示されています。
ここはOUT命令の第2バイトで、I/Oアドレスを読み込むサイクルなので、ただメモリからそのデータを読み込むという動作になります。
ですからM1は点かずにMEMRDだけが点灯しています。

STEPを押しました。
ここにも犯人がいました。

OUT (FF),Aの3番目のステップ(マシンサイクル)です。
CPUはAレジスタの値をI/Oアドレスに出力するために、アドレスバス下位8ビットにFFHを出力します。
これはI/O WRITEサイクルですから、IOWRが点灯します(ちょっと文字が見難いですが、CPU STATUSの右から3番目の緑LEDです)。
データバスにはAレジスタの値78Hが出力され、同時にそれはPROGRAMMED OUTPUTにも出力されています。

そしてこのときのアドレスバスの上位8ビットにもAレジスタの値78Hが表示されています。
このことについては、上のIN命令の実行のところで説明しました。
アドレスバスの上位8ビットA15〜A8には、さきほどのIN命令と今回のOUT命令の2回、Aレジスタの値が出力されます。
それがプログラムの実行中にアドレスLEDの上位バイトがPROGRAMMED INPUTスイッチに連動しているように見えた理由です。

理由はわかりましたから、ここでSTEP動作を止めてしまってもよいのですが、せっかくここまでお見せしたことですので、一巡するまで続けることにいたします。

STEPを押しました。

メモリアドレスが+1されて0004Hになりました。
プログラムの最後のJP命令の命令コード(C3H)を読み込むOPコードフェッチサイクルです。

STEPを押しました。

メモリアドレスが0005Hになりました。
JP命令の2番目のマシンサイクルです。
ジャンプ先アドレス値の下位8ビット(00H)を読み込みます。

STEPを押しました。

メモリアドレスが0006Hになりました。
JP命令の3番目のマシンサイクルです。
ジャンプ先アドレス値の上位8ビット(00H)を読み込みます。

STEPを押しました。

JP命令が完了して、アドレス0000Hにジャンプしました。
これでプログラムが一巡して、最初のステップに戻りました。
ここでSTEPを押せば、またこの説明の最初のところに戻って、STEP動作が続きます。

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

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