標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第51回]

●MVI M,I8の説明です

前回、前々回と2回、MVI命令のうち、レジスタにデータを書き込む、MVI r,I8について説明をしました。
MVI命令は、MVI r,I8と、データをメモリMに書き込むMVI M,I8の2種類あります。
命令コードはどちらも、 00ddd110 です。

命令コードのビット7とビット6が、ともに0で、さらにビット2〜ビット0が”110”にのとき、CPUはMVI命令であると認識します。
dddはデータを書き込むレジスタを指定する3ビットの値000〜111です。
ddd<>110のときはレジスタにデータを転送するMVI命令、MVI r,I8になります。
ddd=110のときはメモリMにデータを書き込むMVI命令、MVI M,I8になります。

MOV命令の回路は改良により、MOV r,r’とMOV r,MとMOV M,rと3つの回路に分かれていたのを、まとめて1つの回路にすることができました。
しかし残念ながら、MVI命令の回路は、MVI r,I8と、MVI M,I8の2つをまとめて1つにすることはできません。

MVI r,I8とMVI M,I8はターゲットがレジスタかメモリかという点では、MOV r,r’とMOV M,rとの相違と同じように思えますが、MVI r,I8とMVI M,I8はMOV命令よりも大きな相違点があるために、1つの回路にはできない、ということを[第49回]で書きました。
どこが違うのでしょうか。

●MVI M,I8はダイレクトに実行することができません

じつは、MOV M,rと違い、MVI M,I8はそのままダイレクトに実行することができないのです。
なぜ?

MOV M,rはレジスタのデータをメモリ(アドレスはHLレジスタで指定)に転送します。
それとはデータの向きは逆ですけれど、MVI r,I8もメモリ(アドレスはPCで指定)のデータをレジスタに転送します。
どちらも送り手のデータを内部データバスに出力するのと同時に、受け手がその内部データバスのデータを読み取ります。

一方、MVI M,I8はメモリ(アドレスはPCで指定)のデータを、メモリ(アドレスはHLレジスタで指定)に転送します。
どうやって?

メモリを指定するためには、そのアドレスを外部アドレスバスA0〜A15に出力する必要があります。そしてそのメモリアドレスからデータを読み出すためには、MEMRDをアクティブにしなければなりません。
一方、そのようにしてデータバスに出力されたデータを、同じメモリ(の違うアドレス)に書き込むには、やはりそのアドレスを外部アドレスバスA0〜A15に出力しなければなりませんし、今度はメモリにデータを書き込むのですから、MEMWRもアクティブにしなければなりません。

CPU内部にあるレジスタに対しては、送り手のレジスタと受け手のレジスタを同時に選択し、そしてregRDとregWRを同時にアクティブにすることができました。
しかしCPUの外部にあるメモリに対しては、同時に2通りのアドレスを指定することはできませんし、MEMRDとMEMWRを同時にアクティブにすることもできません。
CPUの外部に複数のメモリをつないだとしても、同じことです。

CPUの命令を使わないで、複数のメモリ間やメモリ、I/O装置間でダイレクトにデータを転送する、DMA(Direct Memory Acsess)という方法があります。
この方法は最新のペンティアムパソコンでも使われていますが、CPUを使わないで、DMAのための特殊なLSI(DMAC。DMAコントローラ)とそのための回路によってデータを転送しているので、CPUがメモリに対して同時にRead/Writeをすることができないという点では8080でもPentiumでも同じことです。

●MVI M,I8を実行させるためには、ワークレジスタが必要

あるメモリアドレスから別のメモリアドレスにデータを転送するには、送り手のメモリアドレスのデータを一度レジスタに書いておいて、それから受け手のメモリアドレスにそのレジスタのデータを転送する、という2段階の動作がどうしても必要になります。
しかし、そのためにA〜Lのレジスタを使うことはできません。
どのレジスタを使っても、そのレジスタの値がメモリのデータに書き換えられてしまうからです。

そこで、「つくるCPU」の回路には、そういう特別の目的のためのワークレジスタが用意されています。
WKHとWKLです。
このレジスタはCPUの命令(マシン語の命令)によってアクセスすることはできません。
CPUの外からは見えない、内緒のレジスタです。
多分8080でもZ80でも同じようなワークレジスタが存在している、と思います。

じつは、「つくるCPU」のワークレジスタ回路はすでに[第23回]●内緒のレジスタですで、ご紹介済みです。

CPUの命令ではアクセスできないとすると、内部回路はどうやって、このワークレジスタをアクセスするのでしょうか。
その秘密は、「レジスタ選択回路」([第27回])にあります。この回路もすでに何回か紹介しています。
レジスタ選択回路はその後MOV命令回路の改良によって、一部を変更しました。
改良後の「レジスタ選択回路」([第45回])です。
ワークレジスタについては改良前でも改良後でも変わりありませんから、どちらを参照していただいても構いません。

レジスタ選択回路を見ていただくと、今までレジスタを選択するのに使用していたs0〜s2、d0〜d2のほかに、s3、d3が使われていることがわかります。
s3、d3については、今までは「通常はHになります」とだけ説明してきました。
じつは、このd3、s3をLにすることで、ワークレジスタやその他の特殊なレジスタを選択することができるのです。
s0〜S3、d0〜d3によって選択されるレジスタの一覧については、[第27回]●s0〜s3、d0〜d3(レジスタアドレス)を参照してください。

レジスタの一覧表とレジスタ選択回路を見ることにより、ワークレジスタ(WKHレジスタ)が、s3〜s0またはd3〜d0が、”0110”のときに選択されることがわかります。

以上で、MVI M,I8の説明の前に必要な予備知識の説明が済みました。
そこで、いつものように、回路図とタイミングチャートを見ながら、説明をしていきます。

●MVI M,I8の回路図です



MVI r,I8の説明のところで、MVI r,I8の回路は、MVI M,I8の回路にほとんど含まれてしまいます、と書きました。
含まれないのは、どの部分かというと、T6のタイミングでMclrを出力しているゲートだけが、MVI r,I8にあって、MVI M,I8にはありません。
MVI M,I8のタイミングチャートで説明することにします。

●MVI M,I8のタイミングチャートです



MVI r,I8はT6にMclrがあって、そこで命令の実行が完了しましたが([第49回]MVI r,I8のタイミングチャート参照)、MVI M,I8では、MclrはT8になっています。
MVI M,I8命令では、まずT4、T5でPC(プログラムカウンタ)で示されるメモリのデータを一旦ワークレジスタ(WKH)に保存したうえで、次のT6、T7で、HLレジスタで示されるメモリアドレスに、WKHに一時的に保存したデータを書き込むという、2段階の動作をしています。

T4、T5の期間をMVI r,I8とMVI M,I8のタイミングチャートで比べてみると、MVI M,I8ではd0−d3が”0110”になっています。

ここのところはMOV r,I8では明示していません。d0−d2がdddになっています。
d3とs3は回路を組んで”0”を出力しない限り、通常は”1”になります。MOV r,I8では、d3もs3も出力していないので、”1”です。
d0−d2はOPコードのdddがそのまま出力されています。このdddとregWRでデータを書き込むレジスタを選択するためです。

MVI M,I8では、dddは”110”です。そしてMVI M,I8の回路図で見ると、中ほど右側で、M2の時に、d3にL(”0”)を出力しています。そのためMVI M,I8のタイミングチャートにある通り、d0−d3が”0110”になります。
d0−d3が”0110”のときにはWKHが選択されます(このことについては、今回の、前の方で説明しました)。
d0−d2は命令コードのdddをそのまま出力すればよいので、あとは、ただd3を”0”にする回路(NANDゲートを1つ)を用意するだけで、WKHを選択してデータを書き込むことができるのです。

なおこの段階では、まだs0−s3は使いませんが、次のタイミングでは必要になるので、T4〜T7の期間中、s0−s3も”0110”にしています。そのための回路はd3に”0”を出力しているゲートのすぐ上にあります。
s3の出力はインバータ1個で済んでいます。なぜd3の出力もそうしないのか、は次のタイミングの説明で明らかになります。

T6、T7のタイミングはかなり複雑になります。
PCselに代わってregRDがLになります。
regRDがLでs0−s3が”0110”なので、WKHが選択されて、そのデータが内部データバスに出力されます。
T6の期間はregWRもLになります。
d3はT4とT5の期間だけLにしていました。T6ではHになります。

ですから、タイミングチャートのようにd0−d3は”1110”になります。
regWRがLでd0−d3が”1110”の時は、HLselとMEMWRがアクティブになります(「レジスタ選択回路」([第45回])参照)。
そこで、WKHから出力されたデータがHLレジスタで選択されたメモリアドレスに書き込まれることになります。

d3をs3のようにインバータ1個で出力せずに、M2の期間だけ”0”にしたのは、同じd0−d2を利用して、d3の出力だけで、M2の期間はWKHにデータを書き込み、M3の期間はメモリにデータを書き込むという動作を簡単に実現するための工夫だったのです。

なおHLselの立下りに傾きがあるのは、ここだけが遅いという意味ではなくて、タイミングチャートの表現として、d0−d3、s0−s3の変化を示すのに勾配がついてしまうため、d0−d3の変化によってHLselが出力されることをはっきりと示そうとするとこうなってしまうからです。ただそれだけの理由ですから、この傾きにはそれ以上の意味はありません。
2008.8.29upload

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