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

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第16回]

●EOFコードの確認は?

前回、テキストファイルを表示させるプログラムを作って試したところ、表示されたリストの後にゴミが表示されてしまいました。
CP/MではプログラムやデータをディスクにSAVEするときに、ページ(256バイト)単位で保存を行ないます。
データの最後の部分が256バイトに満たないときは、その後の関係のない部分も含めて256バイト分が保存されてしまいます。
そのようにしてディスクに保存されたファイルを、読み出すときも同じように、データの最後の部分は、その後の関係のない部分も含めて読み出してしまいます。
ですからもしデータの終わりを示すマーク(EOF)が無いと、前回お見せしたようなゴミが表示されてしまうことになります。

そういうことがわかりましたから、データの最後の部分にEOFコード(1A)を追加してから、もう一度そのファイルを読み込んで表示させてみました。
EOFコードを追加する前は、TYPEコマンドでもゴミが表示されたのですが、EOFコードを追加したところ、TYPEコマンドではゴミは表示されなくなりました。
ところが「応用CP/M」に載っているサンプルプログラムを実行したところ、EOFコードを追加しても、やっぱり追加する前と同じように、ゴミまで表示されてしまいました。

というところまでが、前回でした。
そこで、あらためてプログラムを調べてみましたら、なんとEOFコードをチェックしているところが全く無いことがわかりました。
これではEOFコードを追加してみても、何の変化も無かったのも当たり前です。

下はそのプログラムの、バッファに読み込んだファイルの内容を1バイトずつ表示する部分です。
Cレジスタ=02のファンクションコールは、Eレジスタの値をASCIIコードとみなして、その文字をコンソールに表示します。

811C 218080   	LD HL,DMABF
811F 0E02     SCROUT:LD C,02
8121 5E       	LD E,(HL)
8122 E5       	PUSH HL
8123 CD09C4   	CALL BDOS

この部分を下のように変更しました。

811C 218080   	LD HL,DMABF
811F 0E02     SCROUT:LD C,02
8121 7E       	LD A,(HL)
8122 FE1A     	CP 1A;EOF
8124 C8       	RET Z
8125 5F       	LD E,A
8126 E5       	PUSH HL
8127 CD09C4   	CALL BDOS

このように変更してから、もう一度テキストファイルを表示してみたところ、今度はゴミは表示されませんでした。

こういうこともあるのですねえ。
これが印刷されたプログラムリストなどですと、活字の誤植ということもあるのですけれど、この「応用CP/M」の場合には、プリンタに出力したプログラムリストをそのまま写真製版したもののようですから、誤植ではありません。

こういうところが、プログラムの難しいところです。
プログラムをたくさん書いていると、なかには作者も気が付かないような、こういうバグがひそんでいることもあるのです。
これは推測なのですが、おそらく作者がこのプログラムを作成したときは、たまたまメモリがクリアされているところに、ソースプログラムを書いていった、というようなことだったのではないでしょうか。

そうだったと仮定して、その状況を再現して確かめてみることにします。
あらかじめ8100H〜83FFHの範囲のRAMをクリアして(全てに00を書き込んで)、そこにT1520.TXTをロードしてから、それをファイルとしてSAVEしました。
SAVEされたデータの最後のところは、下のようになっています。
前回ゴミデータだったところはすべて00になっています。

>D.,8300,833F
8300  0D 0A 09 44 42 20 30 41-0D 0A 09 22 24 22 0D 0A  ...DB 0A..."$"..
8310  3B 45 4E 44 0D 0A 0D 0A-00 00 00 00 00 00 00 00  ;END............
8320  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
8330  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
このようにしてSAVEしたT1510.TXTを、プログラムを修正する前の、T1510.COMで実行して、その内容を表示させてみたところ、下のようになりました(表示された最後のあたりの部分のみ示します)。

        RET
MSGERR:DB 0D
        DB 0A
        DB 0A
        "FILE"
        " GA "
        "NAI"
        DB 0D
        DB 0A
        "$"
;END


a>DIR


プログラムにEOFをチェックする部分がなくても、ゴミは表示されなくなりました。

しかしこれはたまたまゴミデータの部分がすべて00だったため、見かけ上は正しく表示されているように見えるだけで、もしもそこにそれ以外のコードが書かれていたら(そういうことのほうが圧倒的に多いはずです)、前回のようにゴミが表示されてしまうことになります。

プログラムのバグのために、システムがダウンしたとかという話はよく耳にしますが、実際にテストをして確認していても、このように状況によってはテストをすり抜けてしまうバグは意外に多いのです。

ワンボードマイコンでCP/Mを![第16回]
2012.1.26upload

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