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

●SHLD命令のクロック毎の動作の写真です

動作の確認をするために次のプログラムを実行させました。

0000 310008    LXI SP,0800
0003 217856    LXI H,5678
0006 223412    SHLD 1234
0009 210000    LXI H,0000
000C 2A3412    LHLD 1234

今回のテストではスタックポインタの設定は必要ありません。
しかしSHLD、LHLDでSP(スタックポインタ)を利用するため、その値が正しくWKレジスタに保存され、命令動作終了時にもとの値に戻ることをはっきり確認できるように、あらかじめSP(スタックポインタ)に適当な値(ここでは0800)を設定しておくことにしました。
同じ理由でHLレジスタにも適当な値(ここでは5678)を設定しておきます。
SHLDはメモリアドレス1234番地(および1235番地)に対して実行しますが、本当にメモリに値が書き込まれたかどうか確認したくなります。
そこでSHLDとペアになっている命令のLHLDを実行して、メモリからHLレジスタに値を読み出すことでSHLDとLHLDの両方の動作の結果の確認をすることにしました。
SHLDのあとにLXI H,0000があります。
LHLD命令の前にHLレジスタの値をクリアしておくことで、メモリからHLレジスタにデータが読み込まれる様子がより分かり易くなります。

メモリアドレス”0006”のSHLD命令のT4から、クロック毎の動作を見ていくことにします。

SHLD命令のT4の写真です。


うっかりしていて、SP(スタックポインタ)のLEDにフラットケーブルがかかってしまって、一部がかくれてしまいました。
でも、なんとか見えると思います。

OPコードレジスタには”22”(SHLD命令のOPコード)がラッチされています。
PC(プログラムカウンタ)は”0007”になっていますが、PCADoutが消灯していて、PC(プログラムカウンタ)の値は、外部アドレスバスA15−A0には出力されていません。

regRDとregWRが共に点灯しています。
regRDが点灯していて、s3−s0が”0101”なのでデータの送り手としてSPLレジスタ(スタックポインタの下位8ビット)が選択されます。
SPLrdが点灯していて、SPLレジスタの値、”00”が内部データバスinnerBUSに出力されています。
regWRが点灯していて、d3−d0が”0111”なのでデータの受け手としてWKLレジスタが選択されます。
WKLregWRが点灯していて、WKLレジスタに内部データバスの値”00”が読み込まれています。

s3−s0、d3−d0とレジスタの関係については、「レジスタコード表」([第27回])を参照してください。

T5の写真です。


regWR、WKLregWRが消灯し、WKLレジスタに、内部データバスの値”00”がラッチされました。

T6の写真です。


regRDとregWRが共に点灯しています。
regRDが点灯していて、s3−s0が”0100”なのでデータの送り手としてSPHレジスタ(スタックポインタの上位8ビット)が選択されます。
SPHrdが点灯していて、SPHレジスタの値、”08”が内部データバスinnerBUSに出力されています。
regWRが点灯していて、d3−d0が”0110”なのでデータの受け手としてWKHレジスタが選択されます。
WKHregWRが点灯していて、WKHレジスタに内部データバスの値”08”が読み込まれています。

T7の写真です。


regWR、WKHregWRが消灯しました。
WKHレジスタに”08”がラッチされました。
これでWKレジスタにSP(スタックポインタ)の値”0800”が保存されました。

T8の写真です。


PCADoutがアクティブになって、PC(プログラムカウンタ)の値”0007”が外部アドレスバスA15−A0に出力されています。
MEMRDが点灯し、メモリアドレス”0007”の値”34”が外部データバスD7−D0に出力されています。
内部データバスinnerBUSも”34”になっています。

regWRが点灯していて、d3−d0が”0101”なのでデータの受け手としてSPLレジスタが選択されます。
SPLwrが点灯していて、SPLレジスタに内部データバスの値”34”が読み込まれています。

T9の写真です。


regWR、SPLwrが消灯しました。
SPLレジスタに”34”がラッチされました。

PCclkが点灯しました。
PCclkが点灯→消灯のタイミングでPC(プログラムカウンタ)が+1されます。

T10の写真です。


PCclkが消灯し、PC(プログラムカウンタ)の値が+1されて”0008”になりました。
PCの値が外部アドレスバスA15−A0に出力されています。
MEMRDが点灯し、メモリアドレス”0008”の値”12”が外部データバスD7−D0に出力されています。
内部データバスinnerBUSも”12”になっています。

regWRが点灯していて、d3−d0が”0100”なのでデータの受け手としてSPHレジスタが選択されます。
SPHwrが点灯していて、SPHレジスタに内部データバスの値”12”が読み込まれています。

T11の写真です。


regWR、SPHwrが消灯しました。
SPHレジスタに”12”がラッチされました。
SHLD命令で指定したメモリアドレスの”1234”がSP(スタックポインタ)に書き込まれました。

T12の写真です。


SPselがアクティブになって、SPの値が外部アドレスバスA15−A0に出力されています。
regRDが点灯し、s3−s0は”1101”なので、データの送り元としてLレジスタが選択されています。
LregRDが点灯していて、Lレジスタの値、”78”が内部データバスinnerBUSに出力されています。

外部データバスD7−D0も”78”になっていて、MEMWRがアクティブになっています。
メモリアドレス”1234”に”78”が書き込まれていることを示しています。

T13の写真です。


MEMWRが消灯しました。
SPclkが点灯しました。
SPd/uは点灯していますから、SPclkが消灯するタイミングでSP(スタックポインタ)は+1されます。

T14の写真です。


SPclkが消灯し、SPの値が+1されて”1235”になりました。
SPの値が外部アドレスバスA15−A0に出力されています。

regRDが点灯していて、s3−s0が”1100”なのでデータの送り手としてHレジスタが選択されます。
HregRDが点灯していて、Hレジスタの値、”56”が内部データバスinnerBUSに出力されています。
外部データバスD7−D0も”56”になっていて、MEMWRがアクティブになっています。
メモリアドレス”1235”に”56”が書き込まれていることを示しています。

T15の写真です。


MEMWRが消灯しました。
メモリアドレスの1234と1235に、HLの値”5678”が書き込まれました。

T16の写真です。


今まではクロックタイミングを示すLEDはQa〜Qd(A〜D)の4ビット分だったのでT0〜T15(0000〜1111)しか表示できませんでした。
T16は2進数では”10000”で5ビット必要ですが最上位の1ビットを示すLEDが無いため、T16とT0の区別がつきませんでした。

ということで、Qe(E)を表示するLEDを追加しました。
これでT16以上も表示できるようになりました。

T16からはCPU内部での処理です。
WKレジスタに保存しておいた、SP(スタックポインタ)の値をもとに戻します。
T4〜T7の処理の逆を行います。

regRDとregWRが共に点灯しています。
regRDが点灯していて、s3−s0が”0111”なのでデータの送り手としてWKLレジスタが選択されます。
WKLregRDが点灯していて、WKLレジスタの値、”00”が内部データバスinnerBUSに出力されています。
regWRが点灯していて、d3−d0が”0101”なのでデータの受け手としてSPLレジスタ(スタックポインタの下位8ビット)が選択されます。
SPLwrが点灯していて、SPLレジスタに内部データバスの値”00”が読み込まれています。

s3−s0、d3−d0とレジスタの関係については、「レジスタコード表」([第27回])を参照してください

T17の写真です。


regWR、SPLwrが消灯し、SPLレジスタに、内部データバスの値”00”がラッチされました。

T18の写真です。


regRDとregWRが共に点灯しています。
regRDが点灯していて、s3−s0が”0110”なのでデータの送り手としてWKHレジスタが選択されます。
WKHregRDが点灯していて、WKHレジスタの値、”08”が内部データバスinnerBUSに出力されています。
regWRが点灯していて、d3−d0が”0100”なのでデータの受け手としてSPHレジスタ(スタックポインタの上位8ビット)が選択されます。
SPHwrが点灯していて、SPHレジスタに内部データバスの値”08”が読み込まれています。

T19の写真です。


regWR、SPHwrが消灯しました。
SPHレジスタに”08”がラッチされました。
これでSP(スタックポインタ)に、もとの値”0800”が戻されました。

T20(次の命令のT0)の写真です。


これはまた、ひどいピンボケになってしまいました。
なんなのでしょうか。フォーカスがしっかり合ってくれないときがあるようです。
T20は一瞬で終了し、次の命令のT0になります。

●LHLD命令のクロック毎の写真です

SHLD命令によってメモリアドレス”1234”と”1235”に、HLレジスタの値”5678”が書き込まれました(はずです)。
今度はLHLD命令によって、それを確認してみます。

LHLD命令とSHLD命令はT12〜T15が違っているだけで、その他の期間の動作は全く同じです。
ですから、LHLDについてはT12〜T15だけを見てみることにします。

LHLDのT12の写真です。


SPselがアクティブになって、SPの値が外部アドレスバスA15−A0に出力されています。
MEMRDが点灯していて、メモリアドレス”1234”の値”78”が外部データバスD7−D0に出力されています。
SHLD命令で書き込んだ通りの値です。
内部データバスinnerBUSも外部データバスと同じ値になっています。

regWRが点灯し、d3−d0は”1101”なので、データの受け手としてLレジスタが選択されています。
LregWRが点灯していて、内部データバスinnerBUSの値、”78”がLレジスタに書き込まれています。

T13の写真です。


LregWRが消灯しました。
SPclkが点灯しました。
SPd/uは点灯していますから、SPclkが消灯するタイミングでSP(スタックポインタ)は+1されます。

T14の写真です。


SPclkが消灯し、SPの値が+1されて”1235”になりました。
SPの値が外部アドレスバスA15−A0に出力されています。

MEMRDが点灯していて、メモリアドレス”1235”の値”56”が外部データバスD7−D0に出力されています。
SHLD命令で書き込んだ通りの値です。
内部データバスinnerBUSも外部データバスと同じ値になっています。

regWRが点灯し、d3−d0は”1100”なので、データの受け手としてHレジスタが選択されています。
HregWRが点灯していて、内部データバスinnerBUSの値、”56”がHレジスタに書き込まれています。

T15の写真です。


HregWRが消灯しました。

SHLD命令でメモリに書き込んだ値”5678”がそのままメモリから読み出されて、元通りにHLレジスタに正しく書き込まれました。
このあとのT16〜T20はSHLD命令と全く同じなので(回路も同じ部分が実行される)、省略します。
2008.11.1upload

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