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

標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
やっと(!)MYCPU80の改良型基板製作に着手しました!!





[第851回]


●SHLD、LHLD、XTHL命令のテスト

SHLD、LHLD、XTHL命令のテストです。
SHLDはメモリアドレスを指定してそのアドレスとその次のアドレスにHLの値をSTOREする命令です。
LHLDはその逆の命令で、メモリの値をHLにLOADします。
XTHLはスタックトップにある2バイトのデータとHLレジスタの値を交換する命令です。
下のリストはSHLD、LHLD、XTHL命令のテストプログラムです。

0000 310000   LXI SP,0000
0003 010000   LXI B,0000
0006 110000   LXI D,0000
0009 3E00     MVI A,00
000B C5       PUSH B   (8)
000C E3       XTHL      (16)
000D 23       INX H     (8)or(12)
000E 225000   SHLD 0050 (20)
0011 210000   LXI H,0000 (8)
0014 2A5000   LHLD 0050 (20)
0017 E3       XTHL      (16)
0018 C1       POP B     (8)
0019 1C       INR E      (8)
001A C20B00   JNZ 000B  (12)or(8)
001D 14       INR D      (8)
001E C20B00   JNZ 000B  (12)or(8)
0021 3C       INR A      (8)
0022 C30B00   JMP 000B  (12)

BCレジスタとDEレジスタには初期値0000を入れます。
Aレジスタにも00を入れます。

PUSH B、POP Bは、XTHLの動作を確認するために使っています。
PUSH B命令の実行によって、スタックのトップにはBCレジスタの値が置かれます。
XTHLを実行すると、そのときにスタックトップにある2バイトのデータと、HLレジスタの値とが交換されます。
XTHL命令によって、スタックトップのデータ(実はBCレジスタの値と同じ)がHLレジスタに入り、代わりにHLレジスタの値がスタックに置かれます。
BCレジスタは変化しませんが、動作としては、BCとHLの値を交換したに近い動作になります。
ですから、HLの値は、実はBCの値と同じになっています。

そのHLの値を次のINX Hで+1します。
そしてSHLDとLHLDのテストのために、まずSHLD命令で、メモリの0050にHLの値をSTOREします。
その後に、LHLD命令で、メモリの0050から、ふただび値をHLレジスタに読み込みます。
そしてもう一度、XTHLを実行して、スタックトップのデータ(保存してあった、もともとのHLのデータ)と、現在のHLレジスタの値とを交換します。

ここまでの動作で、スタックトップの値(実はBCレジスタの値)が+1されたことになります。
そして最後に、POP Bで、スタックトップの値をBCレジスタに戻します。
結局、HLレジスタの値は変わることなく、BCレジスタの値だけが+1されたことになります。

実行時間を時計で計って、計算結果と比較できるように、以上の動作を1回実行するごとに、Eレジスタを+1します。
Eレジスタを+1した結果が00でなければ、000Bに戻って繰り返します。
結果が00のときは、Dレジスタを+1します。
Dレジスタを+1した結果が00でなければ000Bに戻って繰り返します。
Dレジスタを+1した結果が00のときは、Aレジスタを+1してから、000Bに戻って繰り返します。
上のリストの各命令の後ろの()内の数はその命令の実行クロック数です。
実行時間の計算については省略しますが(MYCPU80操作説明書では詳細な計算の説明をしています)、Aレジスタは約4秒ごとに+1されていきます。
下はプログラムを実行中の写真です。


●SPHL、PCHL命令のテスト

SPHL、PCHL命令のテストです。
SPHLはHLレジスタの値をSP(スタックポインタ)に転送する命令です。
PCHLはPC(プログラムカウンタ)にHLの値を転送します。PC(プログラムカウンタ)がHLの値になりますから、HLの値で示すアドレスにジャンプするという動作になります。
下のリストはSPHL、PCHL命令のテストプログラムです。

0000 3E00     MVI A,00
0002 47       MOV B,A
0003 4F       MOV C,A
0004 57       MOV D,A
0005 5F       MOV E,A
0006 210001   LXI H,$0100
0009 F9       SPHL      (8)
000A E9       PCHL      (8)

00FE 00       DB 00
00FF 00       DB 00
0100 3B       DCX SP    (8)or(12)
0101 3B       DCX SP    (8)or(12)
0102 F1       POP PSW   (8)
0103 3C       INR A      (8)
0104 F5       PUSH PSW  (8)
0105 C20901   JNZ $0109   (12)or(8)
0108 03       INX B      (8)or(12)
0109 24       INR H      (8)
010A E5       PUSH H    (8)
010B 210900   LXI H,$0009 (8)
010E E3       XTHL       (16)
010F C9       RET        (8)

01FE 00       DB 00
01FF 00       DB 00
0200 3B       DCX SP    (8)or(12)
0201 3B       DCX SP    (8)or(12)
0202 F1       POP PSW   (8)
0203 3C       INR A      (8)
0204 F5       PUSH PSW  (8)
0205 C20902   JNZ $0209   (12)or(8)
0208 13       INX D      (8)or(12)
0209 25       DCR H      (8)
020A C30A01   JMP $010A   (12)

上のプログラムは2つの24ビットカウンタB、C、AとD、E、Aを交互にカウントアップさせる動作をします。
Aレジスタが共用されているため、スタックに値を退避します。
SPHLとPCHLを使って2組のプログラムと2組のスタックを使い分けています。

HLレジスタには初期値として0100を入れています。
この0100は「BCA」カウンタルーチンのエントリアドレスであるとともに、スタックポインタのアドレスでもあります。

次の命令、SPHLで、SP(スタックポインタ)に、この0100がセットされます。
そして、さらにその次の、PCHL命令によって、PC(プログラムカウンタ)にも同じ0100がセットされます。
PCの値が0100になりますから、つまり、これはJMP 0100が実行されるのと同じことです。
したがって、処理の流れは、0100に移ります。

0100と0101にはDCX SP命令があります。
DCX SPを2回実行しますから、SPの値は0100−2で00FEになります。
次にPOP PSWを実行します。
SP(スタックポインタ)に00FEをセットしておいて、POP PSWを実行することで、00FE〜00FFのメモリ内容がAレジスタとフラグレジスタに入れられます。
POP PSWのあと、INR Aを実行して、Aレジスタを+1(インクリメント)します。
そして、PUSH PSW命令で、+1したあとのAレジスタの値をまたスタックに保存します。

Aレジスタが256カウントされて、00になるたびに、その上位カウンタのBCレジスタを+1します。
次にINR Hを実行します。Hレジスタが+1されます。
HLレジスタには「BCA」カウンタルーチンを実行するために、そのエントリアドレスの0100が入っていました。
そのHレジスタが+1されるとHLレジスタの値は、0200になります。

0200はもうひとつのカウンタ「DEA」をインクリメントするためのルーチンのエントリアドレスです。
0200〜のメモリアドレスには、0100〜と同じ動作をするプログラム(対象になるレジスタだけが異なっている)が書かれています。

0100〜のプログラムを実行したあとで、次に実行するプログラムのエントリアドレスである0200をHLレジスタに入れた後、PUSH Hを実行し、最後にRETを実行します。
こうすることで、0200にジャンプしてもうひとつのカウンタルーチンが実行されることになります。

このようにして、0100〜のプログラムと0200〜のプログラムが交互に実行され、B、C、AレジスタとD、E、Aカウンタが交互にインクリメントされることを繰り返します。
上のリストの各命令の後ろの()内の数はその命令の実行クロック数です。
実行時間の計算については省略しますが(MYCPU80操作説明書では詳細な計算の説明をしています)、BおよびDレジスタは約8秒ごとに+1されていきます。
下はプログラムを実行中の写真です。



TTLでCPUをつくろう![第851回]

2018.2.25upload

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