16ビットマイコンボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第55回]
●AM188EMのCLOCK(5)
前回はカメレオンロジアナを使ってAM188が命令を実行するときにかかるクロック数について解析しました。
簡単なプログラムを書いて実行し、それをカメレオンロジアナで観測することで、命令のクロック数から求めた計算上の実行クロック数と実際にかかるクロック数が異なるということが確かめられました。
それで疑問は解決したのですけれど。
せっかくカメレオンロジアナをセットしたことでもありますし、この機会に[第53回]でテスト実行をしてオシロスコープで波形を観測した2本のプログラムをカメレオンロジアナでも観測してみました。
オシロスコープと違ってクロック単位での詳細な記録が得られましたが、それだけに画像の枚数も多いので、今回と次回と2回に分けて整理することにしました。
[第53回]でテスト実行をしたプログラムは、下のリストのアドレス8018の06を01に書き換えたものと、8017をC3(RET)に書き換えた2本のプログラムです。
2018/7/1 7:226 86cktst.LST [00001] ;;; clock test for am188 [00002] ; [00003] ORG=8000 [00004] ; [00005] 8000 B080 MOV AL,80 [00006] 8002 E683 OUT 83,AL [00007] 8004 32C0 LOOP:XOR AL,AL;3 [00008] 8006 E680 OUT 80,AL;9 +1.5us [00009] 8008 E80C00 CALL T5US;7us <8017> [00010] 800B FEC8 DEC AL;3 [00011] 800D E680 OUT 80,AL;9 +0.6us [00012] 800F E80500 CALL T5US;7us <8017> [00013] 8012 FEC0 INC AL;3 [00014] 8014 EBEE90 JMP LOOP;14 <8004> [00015] ; [00016] ;5us timer clock 20MHz [00017] 8017 B106 T5US:MOV CL,06 [00018] 8019 FEC9 T5US2:DEC CL;3 [00019] 801B 75FC JNZ T5US2;13,,,16*6=96 0.05*100=5us <8019> [00020] 801D C3 RET;20 CALL=19,,,0.05+140=7us [00021] ; [00022] ;END LOOP =8004 T5US =8017 T5US2 =8019 |
今回はそのうちアドレス8018の06を01に変更したプログラムを実行して、それをカメレオンロジアナで観測した記録について見ていただきます。
この記録を見ていただくことで、前回説明しましたAM188(8086と同じ)ではメモリからの読み込み動作と内部で命令を解読し実行する動作が独立して並行して行なわれるということがおわかりいただけるかと思います。
途中(アドレス8005)から記録が始まっていますがどこから始まってもプログラムが一巡すれば同じことなので、このまま見ていただくことにします。
前回も書きましたが画面では一部が隠れていますがPROBE00〜07がデータバスD0〜D7、PROBE08〜15がアドレスバスA0〜A7です。
PROBE16がCLKOUTA(10MHzクロック)、PROBE17はRAMRDです。
8005は8004 XOR AL,ALの第2バイトです。
そのあと8006、8007のOUT 80,ALのあと8008まで読み込まれています。
8008はCALL T5USの第1バイトです。
その後でOUT命令が実行されています。
1100nsあたりでPROBE08〜15(アドレスA0〜A7)に80が出力されていることで、それがわかります。
OUT命令の実行後、1400nsから8009、800A、800Bまで読み込まれています。
8009、800AはCALL T5USの第2、第3バイトです。
800BはCALL T5USのあとのDEC ALの第1バイトですから、ここで読んでも破棄されてしまうことになりますが、これが前回説明した「先読み」です。
そのあといきなり8017が読み込まれています。
8017はT5USサブルーチンの先頭バイトです。
まだCALL命令は実行されていませんが、これも「先読み」です。
2400nsのところでおそらくリターン後のアドレスがスタックにPUSHされていると思われますが、ここも8ビットCPUでの常識とは異なる動きになっています。
アドレスの下位8ビットしか見えませんが、先にFE、続いてFFになっています。
データバス部分(PROBE05〜07)を見ると、上位3ビットしか見えませんが、先にビット7=0、後でビット7=1のデータがPUSHされていますから、ここはF7FEに0B、F7FFに80がPUSHされていると考えられます。
値としては8ビットCPUの場合と同じですが、8ビットならばPUSHする順序は先にF7FF、次にF7FEになるはずです。
8086の場合には16ビット(2バイト)を同時に読み書きしますが、その場合には偶数アドレス、奇数アドレスの並び順でアクセスされます。
AM188はデータバス幅が8ビットですから2回に分けて読み書きしますが、その場合も16ビットの場合の読み書き順に従いますから、先に偶数アドレス(F7FE)にアクセスしていると考えられます。
スタックPUSH後の2700ns近辺からはT5USサブルーチンの続きが読み込まれています。
8018、8019、801A、801B、801Cです。
801B、801CはJNZ T5US2ですが、今回のプログラムはCLに01を入れていますから、DEC CLでZフラグが立つため、このJNZ命令はスルーされることになります。
801DがRETですが「先読み」によって、次の801Eが無駄に読み込まれています。
そのあとスタックからリターン先アドレスがPOPされていますが、順序はPUSHのときと同じでF7FE、F7FFの順です。
そのあと800Bが読み込まれています。
続いて800C、800D、800E、800Fが連続して読み込まれています。
800FはCALL T5USの第1バイトです。
その後でOUT命令が実行されています。
5900nsあたりでPROBE08〜15(アドレスA0〜A7)に80が出力されていることで、それがわかります。
OUT命令の実行後、6100nsあたりから8010、8011、8012までが連続して読み込まれています。
8010、8011はCALL T5USの第2、第3バイトです。
8012はCALL T5USのあとのINC ALの第1バイトです。
ここで読んでも破棄されてしまいますから無駄な「先読み」です。
そのあと8017が読み込まれています。
8017はT5USサブルーチンの先頭バイトです。
まだCALL命令は実行されていませんが、これも「先読み」です。
7100nsあたりのところでリターン後のアドレスがスタックにPUSHされています。
スタックPUSH後の7500ns近辺からはT5USサブルーチンの続きが読み込まれています。
8018、8019、801A、801B、801Cです。
801B、801CはJNZ T5US2ですがDEC CLでZフラグが立つため、このJNZ命令はスルーされます。
801DがRETですが「先読み」によって、次の801Eも無駄に読み込まれています。
そのあとスタックからリターン先アドレスがPOPされています。
そこでメインプログラムに戻って8012が読み込まれています。
8013、8014、8015、8016までが連続して読まれています。
8014、8015がJMP LOOPですが、次の8016が「先読み」されています。
JMP LOOPはマシン語コードでは3バイトになっていますが、8086アセンブラの都合でそうなっているだけで、本当は2バイト命令です(前回[第54回]参照)。
そのあと8004が読み込まれました。
この次の10800nsの8005の読み込みのところで、ロジアナの先頭の記録に一致します。
スタートが200nsですから、ここまで一回のループが10600nsです。
[第53回]のオシロスコープでの観測結果(4.8μs+5.8μs)とぴったり一致しました。
今回のロジアナでの記録を読むことで、以下のことが明らかになったと思います。
途中何回かの「先読み」ロスが発生していることで、計算上のクロック数よりも実際の実行クロック数のほうが多くなるということと、基本的にメモリからの読み込み時間(1回4クロック)がネックになっていて、内部でのトータルの実行クロック数が計算上はいくら短くても、必要なメモリからの総読み込みクロック数を下回ることはできないということです。
16ビットマイコンボードの製作[第55回]
2018.7.13upload
前へ
次へ
ホームページトップへ戻る