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


16ビットマイコンボードの製作

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
いつか使ってみるつもりで入手してそのまま置いてあった16ビットCPUのことを思い出しました。
AMD社のAM188です。
その名の通り、CPUコアは80188互換の16ビットCPUです。
そのAM188を使った16ビットマイコンボードの製作記事です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[第56回]



●AM188EMのCLOCK(6)

前回は[第53回]でテスト実行をしてオシロスコープで波形を観測した2本のプログラムのうち、下のリストのアドレス8018の06を01に書き換えたものをカメレオンロジアナで観測しました。
今回はもう1本のプログラム、8017をC3(RET)に書き換えたものをカメレオンロジアナで観測した記録をお見せします。

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  

前回は記録の先頭のところからお見せしましたが、今回は前回の記録と合わせるため、かなり進んだところからになります。
前回と同じ、アドレス8005から見ていただくことにします(5600nsのところです)。
前回も書きましたが画面では一部が隠れていますが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命令が実行されています。
6600nsあたりでPROBE08〜15(アドレスA0〜A7)に80が出力されていることで、それがわかります。


OUT命令の実行後、6800nsから8009、800A、800Bまで読み込まれています。
8009、800AはCALL T5USの第2、第3バイトです。
800BはCALL T5USのあとのDEC ALの第1バイトですから、ここで読んでも破棄されてしまいます。
無駄な「先読み」です。
そのあといきなり8017が読み込まれています。
8017はT5USサブルーチンの先頭バイトです。
まだCALL命令は実行されていませんが、これも「先読み」です。
なぜCALL命令がまだ実行されていないのがわかるかといいますと、まだCALL命令の次のアドレスがスタックにPUSHされていないからです。
7800nsのところでリターン後のアドレスがスタックにPUSHされています。
アドレスの下位8ビットしか見えませんが、先にFE、続いてFFになっています。
スタックへのPUSHが行なわれてからCALLが実行されます(厳密に言えばスタックへのPUSHもCALL命令の動作の一部なのですが)。


スタックPUSH後の8100ns近辺でアドレス下位18が出力されています。
MEMRDがアクティブではありませんから、メモリからの読み込みにはなりませんが、かといってMEMWRはありえません。
8017はRETです。
その次のアドレスを読み込むのは無駄な「先読み」です。
それにしてもMEMRDがアクティブではありません。
これは何でしょう。
先読みをしようとして途中で中止したのでしょうか?
そのあとスタックからリターン先アドレスがPOPされていますが、順序はPUSHのときと同じでF7FE、F7FFの順です。
続いて800B、800C、800Dが連続して読み込まれています。


続いて800E、800Fが連続して読み込まれています。
800FはCALL T5USの第1バイトです。
その後でOUT命令が実行されています。
10000nsあたりでPROBE08〜15(アドレスA0〜A7)に80が出力されていることで、それがわかります。
OUT命令の実行後、10200nsから8010、8011が読み込まれています。
8010、8011はCALL T5USの第2、第3バイトです。


続いて10600nsで8012が読み込まれています。
8012はCALL T5USのあとのINC ALの第1バイトです。
ここで読んでも破棄されてしまいますから無駄な「先読み」です。
そのあと8017が読み込まれています。
8017はT5USサブルーチンの先頭バイトです。
まだCALL命令は実行されていませんが、これも「先読み」です。
11200nsでリターン後のアドレスがスタックにPUSHされています。

そのあとなのですが、11500nsあたりでまた下位アドレスに18が出力されています。
さきほどと同じです。
タイミングとしてはここはサブルーチンコール後の最初の処理が実行されているところのはずです(スタックへのPUSHが行なわれた直後のタイミングです)。
ところがサブルーチンの先頭はにRET命令です。
うーん。
スタックにPUSHしてサブルーチンの先頭の命令を実行しようとしたら、それがRET命令で、何もしないですぐに戻れ、と命令されてしまったと。
CPUが混乱してちょっと迷ってしまうのでしょうか。
どうもサブルーチンの先頭がRETだと、こういう動作になるようです。


そのあとスタックからリターン先アドレスがPOPされています。
12200nsでメインプログラムに戻って8012が読み込まれています。
そのあと8013、8014、8015までが連続して読まれています。
8014、8015はJMP LOOPです。


次の13000nsで8016が読み込まれています。
これは無駄な「先読み」です。
JMP LOOPはマシン語コードでは3バイトになっていますが、8086アセンブラの都合でそうなっているだけで、本当は2バイト命令です(前回[第54回]参照)。
そのあと8004が読み込まれました。
この次の13600nsの8005の読み込みのところで、ロジアナの先頭の記録に一致します。
スタートが5600nsですから、ここまで一回のループが8000nsです。
[第53回]のオシロスコープでの観測結果(3.4μs+4.5μs)とほぼ一致しました。

前回と今回とで、2本のプログラムの動作をクロックパルスがわかる波形で見てきました。
どちらの波形も見たところ特にとりたてて異常なところは見られませんでした。
そういうことになりますと。
[第53回]で感じた疑問は解決できるのでしょうか?

前回のプログラムと今回のプログラムの違いは、前回はサブルーチンの中を1回だけ実行してRETしていますが、今回はサブルーチンの中を実行しないですぐにRETしている、というところだけです。
つまりサブルーチンの中の
MOV CL,01 (3clk)
DEC CL (3clk)
JNZ T5US2 (4clk)
の合計3+3+4=10クロック、0.5μs、これが2回なので計算上はちょうど1μsの差になるはずなのに、前回は10.6μsで今回は8μsですから、その差は2.6μsもあります。
この差はサブルーチンで生じているはずです。
サブルーチンは2回実行されていますから、1回あたりで考えると、計算上の差は0.5μsなのに実測での差は1.3μsです。
どこでこの差が出てきたのでしょうか?
やっぱりどこかに異常な動作が隠されているのでしょうか?

聡明なる読者の皆様はすでにおわかりのことと思います。
実は、その答えは前回に書いていたのでした(その時点では私はまだ本当に気が付いていたわけではなかったのですが)。

16ビットマイコンボードの製作[第56回]
2018.7.14upload

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