復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります!
[第53回]
●ファイル名が表示されないわけ
前回からの続きです。
COPYプログラムを作って実行してみたのですが、プログラムは正常に終了したはずなのに、DIRコマンドを実行してみると、COPY先のファイル名が表示されませんでした。
ZB3BASICに戻ってDMコマンドでRAMディスクのディレクトリエリアを表示させてみますと、COPYプログラムによって新しく作成されたtestdata.txtはちゃんと登録されています。
それなのに、どうしてDIRコマンドでは表示されないのでしょうか?
DMコマンドによって表示されたRAMディスクのディレクトリエリアのダンプリストを眺めていましたら、あることに気がつきました。
というところで、前回は終わりました。
おそらく。
前回をお読みになって、「そこじゃないのかなあ」、と思われた方も多いのでは、と思います。
下は前回お見せしたRAMディスクのディレクトリエリアのダンプリストです。
今回はその一部だけを、再掲いたします。
アドレス8940H〜895FHがTESTDATA.TXTのFCBです(水色で囲った部分)。
アドレス894CHの値がB8になっています。
そのほかのファイルの同じ位置を見ますと、全て00です。
COPY元のファイルFTEST4−1.TXTのFCBはアドレス88C0H〜88DFHです(緑色で囲った部分)が、その同じ位置(アドレス88CCH)はやはり00になっています。
FCBのこの位置は、[第51回]のCP/Mシステムエリアの説明では、「ディレクトリ拡張avに相当しているようです。
ディスクディレクトリのファイル毎のFCB(ファイルコントロールブロック)は、上のダンプリストにありますように、32バイトのサイズです。
その17バイト目からの16バイト(アローケーションエリア)に、そのファイルのデータが格納されているブロックbェ書き込まれます。
たとえばTESTDATA.TXTのデータ部はブロックbODおよびブロックbOEに置かれていることが、上のダンプリストからわかります。
この仮CP/MシステムのRAMディスクでは、1ブロック=4セクタです([第12回])。
ですからRAMディスクの先頭から4セクタ(1セクタは128バイト)ごとに区切って、そこにbO0、01、02…と番号をつけていったときの、bODとbOEに、TESTDATA.TXTのデータが書き込まれているということになります。
TESTDATA.TXTのサイズはFTEST4−1.TXTと同じですから707バイトです([第49回])。
1ブロック=4セクタ=128×4=512バイトですから、2ブロックに書き込まれます。
しかし、その計算でいくと、FCBのアローケーションエリアは16バイトですから、512×16=8192バイトを超えるファイルは扱えなくなってしまいます。
そこで、CP/Mシステムではそのような場合には、もう1つ同じファイル名のFCBを作成して、そのアローケーションエリアに続きのブロックb記入できるようにしてあります。
すると同じファイル名のFCBが複数存在することになりますから、それぞれを区別するために、今回注目しましたディレクトリ拡張bェ使われます。
ということになりますと。
このディレクトリ拡張cGリアは通常はおそらく00ということになりますでしょうし、もしそこが00以外であれば、同一ファイル名のセカンド以降のFCBであるということになりますから、DIRコマンドでは二重に表示されないようになっていると思われます。
おお。
どうやら、ここが00でないことが、DIRコマンドで表示されなかった原因のようです。
●表示されなかった原因を取り除きました
そこで、CMコマンドで894CHの値をB8から00に変更してみました。
>cm 894c 894C B8-00 894D 00- >jp d233 a>dir A: FILLE5 COM : FTEST1 COM : FTEST2 COM : DM COM A: TEST COM : FTEST4 COM : FTEST4-1 TXT : FTEST4-2 COM A: FTEST4-3 COM : COPY COM : TESTDATA TXT |
a>ftest4 testdata.txt ; BDOS TEST4 TYPE ;2012/2/28 ; ORG $8100 FCALL=$8005 FCB=$805C RECNO=$807C DMA=$8080 ; LD C,0F;open LD DE,FCB CALL FCALL INC A;if FFH? JP Z,ERR XOR A LD (RECNO),A ; LOOP1: LD C,14;read LD DE,FCB CALL FCALL OR A RET NZ;read end ; LD HL,DMA LOOP2:LD E,(HL) LD C,02 PUSH HL CALL FCALL POP HL INC L JP NZ,LOOP2 JP LOOP1 ; ERR:LD DE,ERRMSG LD C,09 CALL FCALL RET ERRMSG:"can'" "t op" "en" DB 0D DB 0A DB 24;$ ; a> |