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

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

[第135回]


●ファンクションコール10H(ファイルクローズ)、13H(ファイル削除)、15H(シーケンシャルライト)、16H(新規ファイル作成)

今回は表記のファンクションコールを一度にテストします。
テストプログラムFTST5CPYは[第51回]で作成しました。
ファイルコピープログラムです。

FTST5CPYは[第52回]で実行しましたが、そこでバグがみつかったため、[第54回]で修正をしました。
そのあと再度実行をしています。

ファイルクローズ〜新規ファイル作成までの機能は、CCP(Console Command Processor)のERAコマンドやSAVEコマンドとしてすでに検証済みなので、今回のテストは楽勝ものだったはずなのですが。
またまた見事にこけてしまいました(なかなかにつらいものです)。

下はテスト中の画面です。



ファンクションコール13H(ファイル削除)の機能を試すために、COPY後のファイル名を登録済みにしておく作業を先に行なっています。
REN LFTEST.CPP TESTDAT2.TXT
です。
どうでもいいファイルをそのように名前変更しました。

[第52回]でしたのと同じように、FTST5COPY.BINをロードしてから互換DOSを起動して、COPY.COMというファイル名で仮RAMディスクにセーブしました。

セーブする前にRENを実行していますが、誤操作を避けるためには、セーブコマンドを実行後にすべきところです。
慣れてきますとこういうイレギュラーな操作を平気でするようになりますが、よくないことです。

そのあと
COPY FTEST4−1.TXT TESTDAT2.TXT
を実行して、エラーも出ずに無事終了しました。

めでたし、めでたし、でありました。
念の為に、軽い気持ちで、ディレクトリの中味も見ておきますかねぇ、ということで、一旦CP/M互換DOSを終了してZB3BASICに戻ってDMコマンドでディレクトリエリアを表示させてみました。

そうしましたら!



えっ?
まさかのハプニングです。
画面なかほど、TESTDAT2.TXTのブロックアローケーションエリア(ファイル名の次の行)が、空っぽ???
COPY元のFTEST4−1.TXTのそこには、ちゃんと08、09の2ブロックが登録されておりますのに、COPY先のTESTDAT2.TXTは00のみで何も登録されていません。

うわあ、えりゃあこっちゃあ。
どこかにとんでもないバグがあるう…。
かくして、ため息をつきながら、デバッグ作業を開始したのでありました。

ブレークポイントを設定してデバッグを開始したときの様子です。



しばらく地道にデバッグを続けておりました。
デバッグというのは本当に骨の折れるしんどい作業です。



うむむ。
おかしいなあ。
どこも、悪くないなあ。

あっ…。
なんだ、これは?

やっと気が付きました。
なんとディスクが満杯だったのでした。

もう何回も説明をしております通り、本来はWindowsパソコンのハードディスク上に設けるつもりのRAMディスクなのですが、今のところテストに都合がよいように、ND80ZVのRAMに小さな仮のRAMディスクを設けて、そこでテストを続けております。
わずか32KBしかないRAMに、CP/M互換DOSをインストールして、さらにトランジェントエリアも設けた上で、余ったところをRAMディスクとして利用するわけですから、ムリムリの状態です。
アドレス8800H〜B7FFHの12KBをさらに2分割して、Aドライブ6KB、Bドライブ6KBとして使っています。
ディスク容量がたったそれだけしかありませんから、すぐにディスクが一杯になってしまいます。
でも、テストを行なうにはこれが一番都合がよいので、このようにして使っているのです。

さて。
その構成での1ブロックは4セクタ0.5KBです。
Aドライブは6KBなので、6/0.5=12ブロックしか使うことができません。
ブロックナンバーで言いますと、0〜Bまでで12ブロックです。
さきほどのディレクトリエリアのダンプをよく見てみますと。



最後にセーブしたCOPY.COMがブロックBを使ってしまっています。
もっともCOPY.COMの実行時に作成されるコピー先ファイルのTESTDAT2.TXTはすでにセーブ済みのファイルで、それを削除してからそのエリアを再利用しますから、もしもコピー元のファイルサイズが1ブロックだけだったとすれば、かろうじてディスク容量ぎりぎりで済んだはずなのでありますが。
上の画像にありますように、コピー元のFTEST4−1.TXTは08、09の2ブロックを使っています。
当然コピー先のTESTDAT2.TXTも2ブロックになりますから、そうするとディスク容量が足りません。

しかし。
それならエラーになったはず。
何のエラーも表示されなかったということは、それはそれで問題です。
そこで今度は、なぜディスクフルのエラーが表示されなかったのか?
ということを追求いたしました。
だんだん焦点が定まってきて、ついに解決に至ります。

ディスクフルエラーは、COPYプログラム(FTST5CPY)の中でチェックしていたはずでした。
最終的なFTST5CPYのプログラムリストは[第54回]にあります。
そこでは何箇所かでディスクフルをチェックしています。
その中で、今回のトラブルの原因は、ファンクションコール15H(シーケンシャルライト)のエラーチェックにあることがわかりました。
ソースプログラムのその部分です。

;
LOOP2:  LD C,14;read
        LD DE,FCB
        CALL FCALL
        OR A
        JP NZ,CLOSE;read end
        LD C,15;write
        LD DE,FCBWK
        CALL FCALL
        INC A;if FFH?
        JP Z,DFULERR
        JP LOOP2
;

ファンクションコール15Hを実行したあと、INC Aを実行することで、A=FFHをチェックしています。
実はここが間違っていたのです。

それまでにテストをしたいくつかのファンクションコールでは、エラーの場合にはA=FFHが入りましたからここでもそのように書いたのですが、その後に、シーケンシャルライトでは、正常終了時はA=00、異常終了時にはAには00以外の値(エラーコード。FFHとは限らない)が入ることがわかりました。
そこでその後に作成を開始したCP/M互換DOSでは、そのようにプログラムを書きましたから、ディスクフルエラーではFFHを出力しません(エラーコード02を出力します)。

テストプログラムFTST5CPYはそのことに気が付く以前に作成したため、本当はファンクションコール15Hでディスクフルエラーになっていたのに、それがエラーとして認識できなかったのでした。

やっとそういうことがわかりましたので、FTST5CPYのその部分を下のように修正してから、再テストを行ないました。

        LD C,15;write
        LD DE,FCBWK
        CALL FCALL
        OR A
        JP NZ,DFULERR
        JP LOOP2
;

厳密にはA≠00はディスクフルだけとは限りませんが、テストプログラムですから、ここはこういうことでよろしいでしょう。

再テストを行ないましたら、disk full!のメッセージが表示されました。


そこでいくつかのファイルをERAコマンドで削除してから、もう一度実行しましたら、今度はcopy doneと表示されました。

念の為にCP/M互換DOSを終了して、ZB3BASICに戻って、DMコマンドでディレクトリエリアを表示させました。



今度は正しくセーブできました。
上から2番目にTESTDAT2.TXTがあります。
そのブロックアローケーションエリアを見ますと、ブロックbO2と06が書き込まれています。
一番下にコピー元のファイルFTEST4−1.TXTがありますが、そのブロックアローケーションエリアには08と09が書き込まれていて、データとして08、09の2ブロックが使われていることを示しています。
TESTDAT2.TXTも2ブロックを使ったことになっていますから、とりあえずは正しくコピーが行なわれたとみてよいでしょう(でもあとでさらに確認のためのテストはするつもりですが)。

なお上の画面をよくみると、下から3番目にもTESTDAT2.TXTがあります。
これは以前のテストで作成されたファイルですが、16進ダンプの先頭データを見ますと、そこはE5になっています。
ファイル名エリアの先頭にE5があると、そのファイルは消去されたものとして扱われますから、同名のファイルであっても問題はありません。

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

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