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

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

[第105回]


●大きなランダムファイルの作られ方について(2)

前回は、ランダムファイルの作られ方をさらに詳しく調べてみました。
1つのセクタに1件のレコードを格納するとした場合に、シーケンシャルファイルではディスク容量を越えるレコードを記録することはできません。
もしもファイルの先頭のレコードから順に番号をつけていったとしますと、シーケンシャルファイルでは、最後のレコード番号はそのファイルの使用セクタ数に一致します。

ところがランダムファイルではそうは言いきれないということがわかりました。
ディスク容量を越えてレコードを記録することができない、ということについてはランダムファイルでも全く同じなのですが、レコード番号に注目してみると、ランダムファイルの特徴があきらかになってきます。

たとえばランダムファイルで、作成したレコードの最大のレコード番号が99だったとしますと、そのランダムファイルのサイズはシーケンシャルファイルの場合と同じで最大のレコード番号+1がそのファイルを構成するセクタ数になりますから、128×100=12800バイトになります(レコード番号は0からスタートします)。
しかしランダムファイルでは、そのファイルサイズは実際の使用済みセクタ数を意味するとは限りません。
1レコード番号は1セクタと1対1で対応していますが、実際にそのデータを書き込むために使用されるセクタはレコード番号の大きさには関係無く、つねにディスクの空きエリアの先頭のセクタになります。
前回はそのことを確認するために、レコードbディスクの空いている先頭のセクタから順にあてはめていったとすれば、ディスクの容量を越えてしまい範囲外のセクタに割り当てられることになるレコード番号を指定してテストをしてみました。
その結果は、レコード番号の大きさには関係無く、そのレコードは空いている最初のセクタに書き込まれることが確認できました。

それならば、前回まででお見せしてきましたレコード番号テーブル(キー配列表)の値0〜63よりも大きな値を指定することも可能ではないか、という考えに行きつきます。
しかし、そうするとその場合のレコード番号テーブル(キー配列表)は、どこに作られるのでしょうか。
これも試してみればわかるはずです(そのはずだったのですが…)。

前回と全く同じようにして、そのことを試してみることにしました。
前回までのレコード番号テーブル(キー配列表)の値よりも大きな値として、64(40H)を、レコード番号表データの最後に追加しました。

>dm 8300,830f
8300  26 0F 22 27 29 0E 11 12-16 03 0D 3F FF D2 CA FF  &."')......?.メハ.
>cm 830c
830C FF-40
830D D2-ff
830E CA-

>dm 8300,830f
8300 26 0F 22 27 29 0E 11 12-16 03 0D 3F 40 FF CA FF  S..')......?.メハ.
>

再テストをするため、もう一度FILLE5.BINを実行してRAMディスクをクリアしました。
そのあと、FTST20.BINをロードしてCP/Mを起動し、AドライブにFTST20.COMをセーブしました。

>/ld fille5.bin,8100
loading FILLE5.BIN ...0010(16)bytes loaded,from 8100 to 810F
>jp 8100
>/ld ftst20.bin,8100
loading FTST20.BIN ...00a5(165)bytes loaded,from 8100 to 81A4
>jp d233

a>dir
No file
a>save 1 ftst20.com

そして、FTST20.COMを実行しました。
そのあと、結果を確認するために、CP/Mを終了してZB3BASICに戻り、
DM 8800,887F[Enter]
を実行して、ディレクトリエリアのメモリダンプを行ないました。

>jp d233

a>dir
A: FTST20   COM
a>ftst20 test.raf
done

a>dir
A: FTST20   COM : TEST     RAF
a>^D
end of CP/M
>dm 8800,887f
8800  00 46 54 53 54 32 30 20-20 43 4F 4D 00 00 00 02  .FTST20  COM....
8810  01 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
8820  00 54 45 53 54 20 20 20-20 52 41 46 00 00 00 40  .TEST    RAF...@
8830  08 00 00 03 06 07 00 00-04 02 05 00 00 00 00 09  ................
8840  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
8850  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
8860  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................
8870  E5 E5 E5 E5 E5 E5 E5 E5-E5 E5 E5 E5 E5 E5 E5 E5  ................

ところが期待に反して、その結果は前回と全く変わりませんでした。
なぜかレコード番号64のレコードは作成されませんでした。

本当ならば、このときTEST.RAFのFCBエリアがもうひとつディレクトリに作成されて、そこにレコードbU3を超える番号のレコードを記録するブロックbェ置かれるはずでした。
実はCP/Mのランダムファイルでは、そういうルールになっていることはわかっていました。
ですから、そうなるはず、と予測していたのですが…。
何かよくないことがおきてしまったようです。

そこで、一体何が起きているのだろう、ということを追求して、それを解決するために、時間を費やして、あれこれ試してみたのでしたが、その過程をまた説明するということになりますと、またまたいっぱい書かなければなりません。
ですから、試行錯誤の過程は省略しまして、その結果明らかになったことだけを書くことにいたします。

下はCPM22Lのアセンブルリストのファンクションコール22Hのエントリ部分です。
そこにはレコードbェ格納されたFCBエリアの値とエクステント(拡張用FCBのナンバー)との関係を説明するコメントが書かれています。



レコードbヘFCBの最後の2バイトで指定されます([第102回]参照)。
上のリストのコメントではfcb+33(r−0)とfcb+34(r−1)です。
ここをよく見ますと、下位8ビット(r−0)のビット7が上位8ビット(r−1)と組み合わされて、それがextent numberになることがわかります。
そのファイルを構成するブロック数が1つのFCBではおさまらない数になったとき(16個を超えたとき)、同じファイル名のFCBがディレクトリ内に新たに作られます。
しかしそのままではディレクトリ内に同じファイル名のFCBが複数存在することになって不都合ですから、同名のFCBが作成されるたびに複製であることを示すためのカウントナンバーをFCBの特定エリアに書き込むことで、それが最初のFCBなのか2つ目以降のFCBなのかがわかる仕組みになっています。
そのカウント値がextent numberです。
そしてそのナンバーはFCBのエクステンション(拡張子)エリアの次のアドレスに置かれます。
ということで、レコードbフ第7ビットよりも上の数値がエクステントを示していることがわかりました。

むむむ。
そういう仕組みになっていたとは。
それじゃあ、ブロック当り4セクタという、現在の仮RAMシステムじゃだめ、ということではありませんか。

こういうことです。
下は何回も登場していますレコード番号テーブルです。

 0
 1
 2
 3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

この次の第2番目のテーブルは下のようなテーブルになる(同じファイル名の第2のFCBが作られてそこに置かれる)、というように思っていたのですが…。

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

そのようにはならないらしいことがわかりました。
第2のテーブルになるはず、と考えて上に示したテーブルの最初の番号は64です。
64は16進数の40Hですが、それをビットで表現すると、下のように表されます。

01000000

最上位の第7ビットは0です。
つまりこの番号はそれよりも若い番号(0〜63)と同じ、最初のエクステントに属する、と判断されてしまうようです。
それじゃあ第7ビットが1になるようなレコード番号、たとえば
10000101 85H(133)
を指定すればうまくいくのではないか、とも考えて試してみたのですが、うまくはいきませんでした。
やっぱり1ブロックが4セクタというのは「想定外」のようです。

少なくともランダムファイルについて考える限りは、1ブロックは8セクタでなければならないようです。
もしくは1ブロック16セクタという場合もある、とも考えられますが、それについてはここでは考えないことにします。

さて、そういうことだとわかった上で、それでは最初のエクステントにはおさまらないような大きなレコード番号を指定したときに、同じファイル名のFCBが作成されて、そこにブロックbェ書き込まれる、ということを、現在の仮RAMディスクシステムで確かめることはできるでしょうか?
そのためには1ブロックを8セクタにしなければなりません。

それはちょっと無理ではないか…。
と思ったのですが。
いや、ひょっとすると、なんとかなるかもしれない、と思い直して、とにかく試してみることにいたしました。

本日もちょっと時間がありません。
この続きは次回にすることにいたします。

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

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