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

●[8]LXI、PUSH、POP、CALL、Cx、RET、Rx命令回路の動作テストの続きです(操作説明書から)

●15.CALL、RET命令のテスト

MYCPU80組立説明書 V組立 [8]LXI、PUSH、POP、CALL、RET命令回路 の組立作業後に行う動作テストの説明です。

●15−1. CALL、RET命令のテストプログラムをメモリに書く

メモリに次のプログラムを書きます(1. メモリにデータを書き込む の説明を参考にして操作してください)。

0000 310000   LXI SP,$0000
0003 3E00     MVI A,00
0005 210000   LXI H,$0000
0008 110000   LXI D,$0000
000B 3C       INR A    (8)
000C CC2000   CZ $0020  (8 or 18)
000F C30B00   JMP $000B (12)

0020 2C       INR L   (8)
0021 C0       RNZ    (4 or 8)
0022 24       INR H   (8)
0023 C0       RNZ    (4 or 8)
0024 1C       INR E   (8)
0025 C0       RNZ    (4 or 8)
0026 14       INR D   (8)
0027 C9       RET    (8)
(リスト11) CALL、RET テストプログラム

このプログラムはCALL命令とRET命令をテストするものです。
CALL命令は別のアドレスにあるサブルーチンをCALLして実行する命令です。
指定するアドレスに移ってそのアドレスから命令を実行する、という動作はJMP命令と同じですが、JMP命令は「行きっぱなし」であるのに対し、CALL命令はRET命令によって、もとのプログラムに戻ってくることができます(JMP命令はRET命令によっても、もとに戻ってくることはできません)。

[注意]CALL命令、RET命令を使うプログラムは、SP(スタックポインタ)の設定が必要です。
このテストプログラムのようにSP=0000に設定した場合、スタックはそれ(0000)から−1したFFFFから使われていきます。

[注意]サブルーチンプログラムはメモリアドレス0020から書き込みます(ディップスイッチDS2の設定を変えることを忘れないようにしてください)。
サブルーチンをメインプログラムに続けて書いても構わないのですが、マシン語のプログラムの場合には、一度書いてしまうと、後から途中に命令を追加することができません。
途中で命令コードを追加するときは、そこから後ろを全部書き直さなければなりません。
サブルーチンを少し後ろから書くようにすると、プログラム変更の場合の負担が少なくなります。またサブルーチンを「きり」のいいアドレスから始めることで、プログラムが後から見やすいものになります。
なお、このような配慮はマシン語プログラムについてのもので、アセンブラを使ってプログラムを作成する場合にはそれほど意識する必要はありません。

●15−2. テストプログラムを実行する

プログラムの実行の仕方については 4. テストプログラムを実行する を参照してください。
RESETSWを押しながら、ディップスイッチDS3−4をOFFにします。その後RESETSWを離すとプログラムが実行されます。

プログラムが実行されると、Aレジスタが00〜FFまでインクリメント(+1)されます。結果が00でないときは、CZ命令は実行されませんから、次のJMP命令によって、また000Bに戻ってINR Aが実行され、それを繰り返します。
結果が00のときは、0020のサブルーチンがCALLされます。
CZはZフラグがONのときにサブルーチンをCALLする命令です。

0020のサブルーチンではINR Lによって、Lレジスタが00〜FFまでインクリメント(+1)されます。結果が00でないときは、RNZが実行され、そのままメインルーチンに戻ります。
RNZはZフラグがOFFのときにメインプログラムにリターンする命令です。
結果が00のときは、次のINR Hが実行され、Hレジスタがインクリメント(+1)されます。その結果が00でないときは、そこでRNZが実行され、メインルーチンに戻ります。
結果が00のときは、さらにその次のINR Eが実行されます。

そのようにして、順次、A、L、H、E、Dレジスタがインクリメントされていきます。
Aが最下位8ビットでDが最上位8ビットになるように、8ビツトのバイナリカウンタを5個、直列につないだのと同じ動作となります。

テストプログラム(リスト11)の命令の後ろに( )で示した数字は、その命令の実行クロックです。
INR A、CZ、JMPのループの実行クロック数は、INR Aの結果が00ではないとき(つまり結果が01〜FFになる255回は)8+8+12=28クロックで、結果が00になるときだけ、8+18+12=38クロックになります。
このことからAレジスタが00から始まって次の00まで256回インクリメントされるときのクロック数は
28×255+38=7178クロックになります。
また256回のうち1回だけは10クロック多くかかる、と考えて
28×256+10=7178クロックという計算をすることもできます。

MYCPU80のCPUクロックは2MHzですから、1マシンクロックは0.5μSです。
7178クロックを時間に直すと、7178×0.5=3589μSになります。
Aレジスタが00から次の00までカウントアップされるのに3.6mSしかかかりませんからLEDは全点灯しているようにしか見えません。

その上のレジスタについても計算してみましょう。
Aレジスタが00になるときにCALLされるアドレス0020のサブルーチンでは、Lレジスタがインクリメントされます。
この部分の実行クロック数の計算もAレジスタのときと同じように考えますが、Lレジスタが+1されるときは、Aレジスタが00〜00まで一巡したときであることも計算に含める必要があります。
この計算は256回に1回RNZが実行されないときだけ4クロック少ない、と考えると簡単になります。
 (7178+8+8)×256−4=1841660クロックになります。
実行時間は1841660×0.5=920830μSです。
Lレジスタが00から次の00までカウントアップされるのにかかる時間は920.8mSですから、上位の2〜3ビットが点滅していることが確認できるだけです。

上の計算によって、Hレジスタは0.9秒ごとにカウントアップしますから、十分目視することができます。
D、E、Hレジスタの表示結果をもとに計算して、ストップウォッチで計測した結果と比較することもできます。
たとえばD=01、E=23、H=45のときの、スタートしてからの経過時間は次の計算で求められます。

012345は十進数に直すと、74565ですから、
74565×0.92083≒68661.7(秒)になります。
19時間04分21秒です。
ちょっと19時間の観測はきついですから、Dレジスタは00で、EレジスタとHレジスタがカウントアップするのを計測するのがよいでしょう。

[注記]上記の計算の詳細については、当社ホームページの
「つくるCPU[第154回]」(http://www.alles.or.jp~thisida/mycpu154.html)
を参照してください。

☆☆☆操作説明書からのコピーはここまでです。
操作説明書には図はありますが画像(基板の写真)はありません。でもせっかくのホームページですから、写真もUPいたします。☆☆☆

●テストプログラムを実行中の写真です


Dレジスタが00、Eレジスタが0D、HレジスタがC0を表示しています。
DC0は十進数では3520です。
Hレジスタが+1されるのに0.92083秒かかりますから、スタートしてからこの写真のときまでの経過時間は以下の計算で求まります。
3520×0.92083≒3241.3(秒)
54分01秒3です。ストップウォッチとぴったり一致しました。

●過去記事へのリンク

08/10/16 [第97回]●CALL命令●CALL命令のタイミングチャートです●CALL命令の回路図です●条件CALL命令
08/10/17 [第98回]●RET命令●RET命令のタイミングチャートです●RET命令の回路図です●条件RET命令
08/10/19 [第99回]●CALL命令のクロック毎の動作の写真です●MOV B,A命令のクロック毎の写真です●RET命令のクロック毎の動作の写真です
09/2/5   [第154回]●CALL、RETを使ったテストプログラムです●CZ命令の実行時間●RZ命令、RET命令の実行時間●テストプログラムの実行時間
09/6/30  [第264回]●JMP、CALL、RET、PCHLのテストプログラムです

2009.9.13upload

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