[プチ連載です]
Legacy8080用オプションボードの製作
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
葛Z術少年出版様からLegacy8080用のオプションボード製作の依頼を受けました。
そのボードには電流制限素子(ポリスイッチ)をつけることになりました。
そこで…。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第22回]
●OUT命令、IN関数のテスト
当連載は前回で終了したつもりだったのですが…。
葛Z術少年出版の吉崎様からPPI接続基板の参考資料として、ZB3BASICのOUT命令とIN関数の実行時間のデータが欲しいのですが、というメールをいただきました。
それで簡単なテストをして、写真に撮ってメール添付でお送りするつもりだったのですが、こうして連載記事として書いてきたことでもありますので、参考までに連載をちょっと延長して皆様にも見ていただくことにいたしました。
Legacy8080のPPI接続コネクタにPPI接続基板を接続してテストプログラムを実行している写真です。
PPI接続基板の出力端子にオシロスコープを接続して出力波形を観測中です。
下はテストプログラムです。
10 'out test1 20 OUT $E3,$80 30 OUT $E0,0 40 OUT $E0,1 50 GOTO 30 |
もうこれ以上は簡単にできないというくらい簡単なプログラムです。
20行でPPI(82C55)のポートを出力に設定しています。
30行でAポートから00000000を出力します。
40行で00000001を出力します。
50行のGOTO文で30行に戻ります。
このプログラムを実行するとAポートのビット0からHLパルスが出力されます。
出力波形の写真です。
Hが0.3ms、Lは0.2msです。
このことからOUT命令の実行時間は1回あたり約0.2msで、GOTO文は0.1msであることがわかります。
ところで、上の実行時間は実はOUT命令やGOTO文のほかにも実行するときにかかってしまう時間が含まれています。
これはBASICインタプリタの宿命のようなもので、たとえばBASICインタプリタの場合、その1行を実行するたびに毎回解読するための作業が加わります。
ZB3BASICはOUT文やGOTO文などの命令文は”OUT”、”GOTO”という文字列を中間コードに置き換えていますから、文字列そのものを解読するための時間はかかりませんが、それ以外にもいろいろかかっている時間があります。
そこのところは工夫によって多少は実行時間を短くすることは可能です。
参考までに以下にその例を示します。
上のプログラムを少し変形して下のプログラムにしました。
10 'out test2 20 OUT $E3,$80 30 A%=0,B%=1,C%=$E0 40 OUT C%,A% 50 OUT C%,B% 60 GOTO 40 |
同じじゃないか、というよりもむしろこちらのプログラムのほうが面倒なことをやっているようにも思えます。
もとのプログラムはI/Oアドレスの$E0や出力する値の0、1をOUT文に直接書いていますが、変更したプログラムではそれらの値を一旦変数に入れたうえでOUT文ではその変数を使っています。
このプログラムを実行すると、その結果はどうなるでしょうか?
下が実行結果です。
さきほどの結果と比べてみてください。
ほんの少しですが速くなっているのがわかると思います。
さきほどの結果では1回のHLの出力は合計0.52msほどかかっています。
それが今回は0.44msほどに短縮されました。
これには理由があります。
ZB3BASICインタプリタはもとのプログラムの定数値はASCII文字そのままか、または定数値としての中間コードに置き換えて保存します。
それは計算可能な「生の」数値ではなくて何らかの加工が必要な値のため、実行時にはそれを解読して計算可能な値に翻訳しなければならないので、そこで毎回時間がかかってしまいます。
一方今回のプログラムの場合にはその翻訳作業は変数に代入するところで済んでしまいます。
変数に入れられた数値はそのまま計算可能な数値なので、今回のように変数を用いて記述したほうがわずかですが実行時間を短縮することができます。
参考までに最初のプログラムがメモリの中でどのような形で保存されているかを見ていただきましょう。
>dm 8000,804f 8000 CD 51 4A D1 C9 CD 53 40-C9 CD 36 6D CD 53 40 CD ヘQJムノヘS@ノヘ6mヘS@ヘ 8010 0A 00 0B A2 6F 75 74 20-74 65 73 74 31 0D 0E 14 ...「out test1... 8020 00 09 90 24 45 33 2C 24-38 30 0D 0C 1E 00 09 90 ...$E3,$80...... 8030 24 45 30 2C FA 00 00 0D-0C 28 00 09 90 24 45 30 $E0,.....(...$E0 8040 2C FA 01 00 0D 0C 32 00-04 80 1E 00 0D 07 3C 00 ,.....2.......<. |
右側のASCIIダンプでわかるように16進定数は$E3、$E0のようにASCIIコードのままです。
この部分は実行時に毎回、文字コード→数値への変換が必要なため時間がかかります。
0、1という数値はアドレス8034〜8036のFA0000、8041〜8043のFA0100のように頭に整数であることを示すFAをつけたあと16進数そのままで格納されています。
この部分はこのままでもわりと速く実行されます。
下は2番目のプログラムのダンプリストです。
>dm 8000,808f 8000 CD 51 4A D1 C9 CD 53 40-C9 CD 36 6D CD 53 40 CD ヘQJムノヘS@ノヘ6mヘS@ヘ 8010 40 F4 41 25 00 54 00 77-1E 00 02 00 42 F4 42 25 @.A%.T.w....B.B% 8020 00 54 00 77 1E 00 02 00-44 F4 43 25 00 54 00 77 .T.w....D.C%.T.w 8030 1E 00 02 00 0A 00 0B A2-6F 75 74 20 74 65 73 74 .......「out test 8040 32 0D 0E 14 00 09 90 24-45 33 2C 24 38 30 0D 0C 2......$E3,$80.. 8050 1E 00 18 F2 0C 00 9A FA-00 00 2C F2 18 00 9A FA ..........,..... 8060 01 00 2C F2 24 00 9A 24-45 30 0D 1B 28 00 09 90 ..,.$..$E0..(... 8070 F2 24 00 2C F2 0C 00 0D-0C 32 00 09 90 F2 24 00 .$.,.....2....$. 8080 2C F2 18 00 0D 0C 3C 00-04 80 28 00 0D 07 8A 00 ,.....<...(..... >dm f440,f44f F440 00 00 01 00 E0 00 76 21-F7 F1 CD 60 72 21 D0 F0 ......v!..ヘ`r!ミ. |
30行は8050〜806Bです。
先頭に行番号30の16進数001Eがあります。
A%=0は8052〜8059です。
18はLET文の中間コードです。
F2 0C 00は整数型変数を示すコードF2に、その変数の情報がある相対位置000Cをつけたものです。
実はその情報位置は8010〜801Bで、8010、8011はその変数のメモリ上のアドレスF440を示しています。
F440は整数変数A%のアドレスで8012〜には変数名が書かれています。
A%です。
その後ろの8018、19にはA%を定義している行30の16進数001Eが置かれています。
30行の解読に戻ります。
8056の9Aは=の中間コードです。
その後ろのFA 00 00は整数定数を示すFAに続けてその値の0000を記述したものです。
40行のOUT文は、806C〜8078にあります。
先頭に行番号40の16進数0028があります。
90はOUT命令の中間コードです。
その次に続くF2 24 00、F2 0C 00は上で説明した変数の種類とその情報の位置を示す値です。
ちょっと見ていただきましたようにBASICプログラムの実体は結構複雑な構造をしているため、マシン語プログラムよりもうんと実行時間がかかってしまうのです。
このプログラムを実行すると変数アドレスF440、41(A%)、F442、43(B%)、F444、45(C%)にそれぞれ0000、0001、00E0が入ります。
上のダンプリスト(F440〜F44F)はその様子を示しています。
説明の途中ですが、時間がなくなってしまいました。
続きは次回にいたします。
Legacy8080用オプションボードの製作[第22回]
2016.8.20upload
前へ
次へ
ホームページトップへ戻る