ワンボードマイコンをつくろう!(パソコンの原点はここから始まった)
TK80ソフトコンパチブル!8080、Z80マシン語からBASICまでこれ1台でこなせます
当記事は2009年11月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.6.30
前へ
次へ
目次へ戻る
ホームページトップへ戻る
☆ND80ZVでBASICを。
とんでもない機能追加を思いついてしまいました。
ND80ZVでBASICを実行できるようにしようというのです。
それも浮動小数点演算ができて、三角関数や対数計算までできる本物のBASICです!

[第55回]

●今度は/SAVEコマンドがハングアップです

前回は時間が無くなってしまいましたので、そのことについて書くことができなかったのですが、今度はテストプログラムを保存しておこうと思いましたら、/SAVEコマンドでハングアップしてしまいました。
前回の最後のところでお見せしましたログファイルがそれです。

>run
a%=123       b%=456       c%=579
0            1            2            3            4            5
6            7            8            9            10           abc=123.5
0            0
1            1
2            1.41421
3            1.73205
4            2
5            2.23607
6            2.44949
7            2.64575
8            2.82843
9            3
10           3.16228

>/save bstest.txt

ndremote.exeを終了しました
logfile closed at Wed Jun 23 09:07:16 2010

前回の終わりのところで、今回は実数型のFOR NEXTと実数型演算の仕組みについて説明する予定です、と書きました。
でも、ログファイルやら画面のコピーを整理してみましたら、それよりも前にこちらについて説明しないと手順が合わないことがわかりましたので、急遽、予定変更です。
あしからずご了承願います。

ということで、前回お見せしましたログファイルの最後のところなのですが、
/save bstest.txt
の後、無応答になってしまいました。

今回のZ80BASICシステムは、川崎製鉄のZ80互換CPU、KL5C8012を使ったZBKシリーズ用のZBK開発セットのためのシステムがもとになっています。
ZBK開発セットのシステムでは、DOS/Vパソコンとターゲットボードとは、今回と同じようにUSBで接続していますが、通信の仕組みは全く異なります。
もとはFTDI社のFT245を使った仮想的なRS232C通信で行っています。
そこのところを今回はPIC18F14K50を使ったHID送受信に全て変更しなければなりません。

ZBK開発セットのシステムプログラム(=今回のZ80BASICシステムプログラム)にはいろいろなコマンド機能が含まれていますが、その多くが、ホストであるDOS/V側のC++プログラムとPIC18F14K50を間にはさんで、Z80CPUとの間で、頻繁にコマンドやデータの送受信を繰り返します。
特にSAVEコマンドは大量のデータストリームを扱いますから、途中でこけてしまわないようにしっかりと交通整理をしなければなりません。

なかなかに大変なのです。
ログファイルの日付を見ていただければわかりますが、ここのところ何日もかけて長々と書いておりますことは、もう10日ほども前の、1日間の出来事なのです。
この日はまあなんと長い一日だったことでしょう。
朝早くからテストプログラムがハングアップしてしまう原因を追求するためにあれこれデバッグを繰り返してきましたら、それがまだ解決できていませんのに、今度は/SAVEコマンドでもハングアップです。

上で引用しましたログファイルのCLOSEタイムを見ますと、6月23日09:07になっています。
ちなみにこの日、最初にOPENされた(記録開始された)ログファイルは、[第49回]でお見せしています。
そこのところも引用いたしますと、

logfile nd80zlog\06230602.txt open

ND80ZVに接続しました
send[read+]
0001 0000 - zzentry
1000 00C3 - send goto zentry

6月23日06:02に、デバッグ作業を開始いたしました。
前回の終わりのところではまだ09:07ですから、まだ長い1日が始まったばかりなのです。

ここでFOR NEXT文の追求は一旦棚上げにいたしまして、/SAVEがハングアップしてしまう原因を解明することにいたしました。
追求すること数時間で、なんとかクリアすることができました。
C++のプログラムがかなり複雑に入り組んでいて、コマンドを送ってから、データストリームを受け取るまでの流れがうまく通っていなかったのが原因でした。

同じUSB通信ではありますけれど、仮想的な232C通信とHID通信とでは、基本的に異なっているところがあって、そこを合わせるためには、やはりかなりプログラムに手を入れる必要があります。

さて/SAVEコマンドですが、このコマンドはBASICのプログラムをテキストイメージでファイルにSAVEするものです。
ファイルにSAVEされるテキストイメージは、画面にLISTコマンドで表示されるものと全く同じです。
ということで、実は/saveコマンドは、ターゲットに対してLISTコマンドを送出しておいて、ターゲットから送られてくる表示データをそのままテキストイメージでSAVEする、という仕組みになっています。

そのデバッグの過程で、今回のそもそものきっかけとなりました、テストプログラムの表示が全く行われないでハングアップしてしまうということの原因にも通じているリスト表示の問題点を取り除くことに成功する、という有難い副産物を得ることができました。
そのリスト表示の問題点につきましては、[第52回]で少しふれています。
プログラムリストが受信バッファに全部たまってから、まとめて表示されているように見える、のがちょいとおかしい、と思ったのです。
なにしろHIDは1msecごとにわずか64バイトしか送れないのですから、受信バッファのデータはすぐさま表示されてしまい、したがって受信バッファはいつもすぐに空になってしまう、はずだからです。

/SAVEコマンドを手直しして、ハンクアップしないでうまくSAVEできるようになったあたりのログファイルを見ますと、そのlistコマンドによる表示の異常さが際立っています。

logfile nd80zlog\06231501.txt open

ND80ZVに接続しました
[00],inbfend=1
send[read+]
[14]
[04][00][01][00][00][00],inbfend=6
0001 0000 - /[WR+]
[15]
[04][00][02][00][08][00],inbfend=6
0002 0008 - zzentry
[01]
[00],inbfend=1
[00]
[00],inbfend=1
[00]
[00],inbfend=1
[00]
[00],inbfend=1
[12]
[04][10][00][00][C3][00],inbfend=6
1000 00C3 - [10]
send goto zentry
[3E][01],inbfend=2
>help
[48][45][4C][50][0D][0A]
[54][45][58][54][20][38][30][30][34][2D][38][31][32][37][0D][0A][CD][DD][BD][B3][20][44][46][45][46][2D][44][46][46][46][0D][0A][3E][01],inbfend=34
TEXT 8004-8127
ヘンスウ DFEF-DFFF
>list
[4C][49][53][54][0D][0A]
[20][20][20][20][31][30][20][41][25][3D][31][32][33][0D][0A][20][20][20][20][31][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][32][30][20][42][25][3D][34][35][36][0D][0A][20][20][20][20][33][30][20][43][25][3D][41][25][2B][42][25][0D][0A][20],inbfend=62
[20][20][20][34][30][20][50][52][49][4E][54][20][22][61][25][3D][22][3B][41][25][2C][22][62][25][3D][22][3B][42][25][2C][22][63][25][3D][22][3B][43][25][0D][0A][20][20][20][20][34][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][35][30][20][46],inbfend=124
[4F][52][20][41][25][3D][30][20][54][4F][20][31][30][0D][0A][20][20][20][20][36][30][20][50][52][49][4E][54][20][41][25][2C][0D][0A][20][20][20][20][37][30][20][4E][45][58][54][20][41][25][0D][0A][20][20][20][20][37][31][20][41][42][43][3D],inbfend=184
[31][32][33][2E][35][0D][0A][20][20][20][20][37][32][20][50][52][49][4E][54][20][22][61][62][63][3D][22][3B][41][42][43][0D][0A][20][20][20][20][37][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][38][30][20][46][4F][52][20][41][25][3D][30][20],inbfend=246
[54][4F][20][31][30][0D][0A][20][20][20][20][38][35][20][50][52][49][4E][54][20][41][25][2C][0D][0A][20][20][20][20][39][30][20][50][52][49][4E][54][20][53][51][52][28][41][25][29][0D][0A][20][20][20][31][30][30][20][4E][45][58][54][20][41][25][0D],inbfend=308
[0A][3E][01],inbfend=311
    10 A%=123
    15 'STOP
    20 B%=456
    30 C%=A%+B%
    40 PRINT "a%=";A%,"b%=";B%,"c%=";C%
    45 'STOP
    50 FOR A%=0 TO 10
    60 PRINT A%,
    70 NEXT A%
    71 ABC=123.5
    72 PRINT "abc=";ABC
    75 'STOP
    80 FOR A%=0 TO 10
    85 PRINT A%,
    90 PRINT SQR(A%)
   100 NEXT A%
>/save zbtest.txt
savefile ZBTEST.TXT open
[4C][49][53][54][0D][0A]
[20][20][20][20][31][30][20][41][25][3D][31][32][33][0D][0A][20][20][20],inbfend=18
    10 A%=123
   [20][31][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][32][30][20][42][25][3D][34][35][36][0D][0A][20][20][20][20][33][30][20][43][25][3D][41][25][2B][42][25][0D][0A][20][20][20][20][34][30][20][50][52][49][4E][54][20][22][61][25][3D][22][3B],inbfend=62
 15 'STOP
    20 B%=456
    30 C%=A%+B%
    40 PRINT "a%=";[41][25][2C][22][62][25][3D][22][3B][42][25][2C][22][63][25][3D][22][3B][43][25][0D][0A][20][20][20][20][34][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][35][30][20][46][4F][52][20][41][25][3D][30][20][54][4F][20][31][30][0D][0A][20][20][20],inbfend=62
A%,"b%=";B%,"c%=";C%
    45 'STOP
    50 FOR A%=0 TO 10
   [20][36][30][20][50][52][49][4E][54][20][41][25][2C][0D][0A][20][20][20][20][37][30][20][4E][45][58][54][20][41][25][0D][0A][20][20][20][20][37][31][20][41][42][43][3D][31][32][33][2E][35][0D][0A][20][20][20][20][37][32][20][50][52][49][4E][54][20],inbfend=62
 60 PRINT A%,
    70 NEXT A%
    71 ABC=123.5
    72 PRINT [22][61][62][63][3D][22][3B][41][42][43][0D][0A][20][20][20][20][37][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][38][30][20][46][4F][52][20][41][25][3D][30][20][54][4F][20][31][30][0D][0A][20][20][20][20][38][35][20][50][52][49][4E][54][20],inbfend=62
"abc=";ABC
    75 'STOP
    80 FOR A%=0 TO 10
    85 PRINT [41][25][2C][0D][0A][20][20][20][20][39][30][20][50][52][49][4E][54][20][53][51][52][28][41][25][29][0D][0A][20][20][20][31][30][30][20][4E][45][58][54][20][41][25][0D][0A][3E][01],inbfend=45
A%,
    90 PRINT SQR(A%)
   100 NEXT A%
>/exit

ndremote.exeを終了しました
logfile closed at Wed Jun 23 15:01:57 2010

全く同じプログラムリストなのですが、上のlistコマンドによる表示は、データを全部受信し終わってからまとめて表示されています。
これに対して下の/saveコマンドによるプログラムリストの表示は1回のHID受信(62バイト)ごとに行われています。
ここで、後者のinbfendの値が64バイトではなくて62バイトなのは、HID受信のための制御データとして2バイトを使っているからです。

C++プログラムで、/saveコマンドによるリストの表示は、listコマンドによるリストの表示とは別のところに書かれています。
たまたまその部分の表示の仕方に相違があることがわかりました。
/saveの方は単純で、受信バッファからデータを読んでくる都度、画面に表示するとともに、ファイルにSAVEします。
すると上のログのような結果になりますが、これはごくノーマルな表示のされ方です。

一方listコマンドの方は少し複雑で、listコマンドのみに限定したデータ表示ルーチンではなくて、「その他大勢」の処理と同じ表示ルーチンになっていました。
そこでは「いつ終わるかわからないが、少量のデータ」の表示、を扱うことがメインになっていて、その表示データに続いて送られてくるはずのプロンプトマーク>(コード3E)とデータ入力要求コード(01)が来たときにまとめて表示する、という仕組みになっていたのです。

そのために、listコマンドでの表示は、最後の[3E][01]が送られてきたときにまとめて行われていたのです。

理由がわかりましたので、そこのところをちょいと手直しいたしました。
下はそのように手直ししたあとのlist出力の画面です。



ああ。listコマンドの部分がスクロールしてしまって見えませんですね。
では、ログファイルで確認していただくことにいたしましょう。

logfile nd80zlog\06231527.txt open

ND80ZVに接続しました
[00],inbfend=1
send[read+]
[14]
[04][00][01][00][00][00],inbfend=6
0001 0000 - zzentry
[01]
[00],inbfend=1
[00]
[00],inbfend=1
[00]
[00],inbfend=1
[00]
[00],inbfend=1
[12]
[04][10][00][00][C3][00],inbfend=6
1000 00C3 - [10]
send goto zentry
[3E][01],inbfend=2
>help
[48][45][4C][50][0D][0A]
[54][45][58][54][20][38][30][30][34][2D][38][31][32][37][0D][0A],inbfend=16
TEXT 8004-8127
[CD][DD][BD][B3][20][44][46][45][46][2D][44][46][46][46][0D][0A][3E][01],inbfend=18
ヘンスウ DFEF-DFFF
>list
[4C][49][53][54][0D][0A]
[20][20][20][20][31][30][20][41][25][3D][31][32][33][0D][0A][20][20][20][20][31][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][32][30][20][42][25][3D][34][35][36][0D][0A][20][20][20][20][33][30][20][43][25][3D][41][25][2B],inbfend=57
    10 A%=123
    15 'STOP
    20 B%=456
    30 C%=A%+[42][25][0D][0A][20][20][20][20][34][30][20][50][52][49][4E][54][20][22][61][25][3D][22][3B][41][25][2C][22][62][25][3D][22][3B][42][25][2C][22][63][25][3D][22][3B][43][25][0D][0A][20][20][20][20][34][35][20][27][53][54][4F][50][0D][0A][20][20][20],inbfend=62
B%
    40 PRINT "a%=";A%,"b%=";B%,"c%=";C%
    45 'STOP
   [20][35][30][20][46][4F][52][20][41][25][3D][30][20][54][4F][20][31][30][0D][0A][20][20][20][20][36][30][20][50][52][49][4E][54][20][41][25][2C][0D][0A][20][20][20][20][37][30][20][4E][45][58][54][20][41][25][0D][0A][20][20][20][20][37][31][20][41],inbfend=62
 50 FOR A%=0 TO 10
    60 PRINT A%,
    70 NEXT A%
    71 A[42][43][3D][31][32][33][2E][35][0D][0A][20][20][20][20][37][32][20][50][52][49][4E][54][20][22][61][62][63][3D][22][3B][41][42][43][0D][0A][20][20][20][20][37][35][20][27][53][54][4F][50][0D][0A][20][20][20][20][38][30][20][46][4F][52][20][41][25],inbfend=62
BC=123.5
    72 PRINT "abc=";ABC
    75 'STOP
    80 FOR A%[3D][30][20][54][4F][20][31][30][0D][0A][20][20][20][20][38][35][20][50][52][49][4E][54][20][41][25][2C][0D][0A][20][20][20][20][39][30][20][50][52][49][4E][54][20][53][51][52][28][41][25][29][0D][0A][20][20][20][31][30][30][20][4E][45][58][54][20],inbfend=62
=0 TO 10
    85 PRINT A%,
    90 PRINT SQR(A%)
   100 NEXT [41][25][0D][0A][3E][01],inbfend=6
A%
>/exit

ndremote.exeを終了しました
logfile closed at Wed Jun 23 15:27:00 2010

このときの時刻は15:27です。
大分時間も過ぎましたけれど、夏至の一日はまだまだ続きます。

あ。でも本日は時間切れになってしまいました。
この続きはまた次回にいたします。
CPUをつくろう!第540回(2010.7.2upload)を再編集


ワンボードマイコンをつくろう![第55回]
2011.6.30upload

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