復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります!
[第433回]
●PL/IのLINKでエラー(2)
前回からの続きです。
COBOLに引き続いてPL/IでもファイルOPENでこけてしまいました。
互換性を実現するというのはなかなかに難しいものです。
ZB3DOS(CP/M互換DOS)はCP/Mについて書かれた参考書などをもとにしましてプログラムを書いたものなのですが、説明書などには書かれていないような細かいところまではわからないので、こういうことがでてきてしまいます。
なんだ。
オリジナルのCP/Mを解析したんじゃないのか。
と疑問に思われるかもしれません。
ええ。
オリジナルのCP/Mのソースリストは[第17回]に書きましたように、ダウンロードさせていただいております。
ですけれど、どうしても不明なところはちょいと参考にはさせていただきましたけれど、ほとんど解析などはしておりません。
互換プログラムなどを書こうとする場合には、オリジナルのプログラムを逆アセンブルなどして解析するのが常道ではないかと思われるかもしれませんが、それは労多くして功少ない方法だと思います。
一体何がしんどいと言いましても他人が書いたプログラムを解読するということくらいしんどいものはありませぬ。
もうほとんど拷問ですな。
ですので、やりたくはありませんです。
入力がこうで、出力がこう、というように、インプットとアウトプットが決まっていて、その間のプロセスを記述するのがプログラムでありますから、それができなきゃあプログラマとはいえませんでしょう。
他人の書いたプログラムを解析するより、はなから自前でプログラムを書いたほうがなんぼ楽かわかりません。
そのかわり、約束事として表に出てきていないような微妙な仕様が使われるところでは、とたんにこけてしまうことになります。
ま、しかし。
そうやってこけたところをひとつひとつつぶしていくことによって、少しずつ完全な互換に近づいていくことになります。
このところのH様、N様のご協力によりまして、かなりオリジナルに近い互換性が実現できたと思っております。
これひとえに両氏のご協力のたまものと、心より感謝いたしております。
今後とも引き続きご協力のほどをお願い申し上げます。
さて、それで。
前回の続きなのですが。
H様のデバッグによりまして、PLILIB.IRLをファイルOPENしようとしたところでこけていることがわかりました。
ファイルOPENのファンクションコール(ファンクション0F)は、FCB(ここではアドレス005CH〜)にファイル名を書いてコールするのですが、そのFCBではエクステント(拡張aBFCBの先頭から13バイト目)に01が書かれているのです。
ここは本来は00でなければならないはずなので、それでZB3DOSではエラーにしてしまったのです。
CP/Mのディレクトリについておさらいです。
ディスクにファイルをセーブするときには、まずディレクトリにそのファイル名を登録します。
ディレクトリは目次のようなもので32バイトずつに区切られています。
メモリ内に置かれるFCBとレイアウトはよく似ていますが、異なっているところもあります。
先頭の1バイトはメモリ内に置かれるFCBではドライブb示しますがディレクトリではファイルの存在を示す場所として使われ、そこには00が書かれます。
未使用であったり、消去された場合には先頭の1バイトは非00(E5)になります。
次の8バイトがファイル名で、次に3バイトの拡張子が続きます。
その次の1バイトがエクステント(拡張ajです。
それではそのエクステントとはなんだ?
ということについて説明をしなければなりません。
32バイトの後半16バイトはブロックアローケーションエリアです。
CP/Mではセクタをまとめたものとしてブロックという概念を使います。
ハードに依存しない論理的なものですが、ハードと一致すればトラックと考えてもいいと思います。
ZB3DOSのシステムでは、1セクタが128バイトで1トラック=1ブロックは16セクタ(2048バイト)です。
ZB3DOSの仮想FDDは先頭からbOブロック、bPブロック、…と順にブロックbつけて、そのブロックbイとに管理を
しています。
ファイルのデータはセクタに書き込まれますが、そのときには1ブロックが丸ごと空いているブロックをみつけて、そこの16個のセクタに順にデータを書き込んでいきます。
たとえ1セクタしか使わなくて書き込みを完了した場合でもそのブロックは使用済みになります。
ファイルを保存する場合には、ディスクのデータ領域の先頭から空いているブロック(2048バイト)をさがしながらセクタ単位でデータがディスクに記録されていき、同時にディレクトリ内のFCBの後半16バイトのブロックアローケーションエリアに、データを書き込んだブロックの位置を示す2バイトのブロックbェ記入されます。
16バイトですから、8個のブロックb記入すると、枠がいっぱいになってしまいます。
ということは、そのルールでディスクに書き込めるデータは最大で2048×8=16KBです。
それでは16KBを越えるファイルを作成するにはどうしたらよいでしょうか?
そこで登場するのがエクステントです。
データを16KB書き込んで、枠がいっぱいになってしまうと、同じファイル名の32バイトのエリアがディレクトリ内にもうひとつ作成されます。
これでもう16KB分のデータ保存が可能になります。
ただそれだけでは、ディレクトリ内に同じファイル名のFCBが2つ存在することになりますから、あとから作成したFCBのエクステントは01にして、最初のFCBとは区別します。
このように、ディレクトリに最初に作られるFCBのエクステントは00で、次に作られる同じファイル名のFCBのエクステントは01、その次には02…というように、エクステントb順につけることで、大きな容量のファイルでも、その記録した順序の通りにデータを読み出すことができます。
実はH様がデバッグのために表示させたメモリダンプでそのことを確認することができます。
下は前回お見せしたログファイルの一部です。
>DM@0050,00FF 0050 0C A8 AE EA 08 E8 77 75-02 85 AA 2A 00 50 4C 49 .ィョ...wu..ェ*.PLI 0060 4C 49 42 20 20 49 52 4C-01 00 00 80 3E 00 3F 00 LIB IRL....>.?. 0070 40 00 41 00 42 00 43 00-44 00 45 00 18 35 F7 00 @.A.B.C.D.E..5.. 0080 00 50 4C 49 4C 49 42 20-20 49 52 4C 00 00 00 80 .PLILIB IRL.... 0090 3E 00 3F 00 40 00 41 00-42 00 43 00 44 00 45 00 >.?.@.A.B.C.D.E. 00A0 00 50 4C 49 4C 49 42 20-20 49 52 4C 01 00 00 80 .PLILIB IRL.... 00B0 46 00 47 00 48 00 49 00-4A 00 4B 00 4C 00 4D 00 F.G.H.I.J.K.L.M. 00C0 00 50 4C 49 4C 49 42 20-20 49 52 4C 02 00 00 5C .PLILIB IRL...\ 00D0 4E 00 4F 00 50 00 51 00-52 00 53 00 00 00 00 00 N.O.P.Q.R.S..... 00E0 00 52 4D 41 43 20 20 20-20 43 4F 4D 00 00 00 6B .RMAC COM...k 00F0 54 00 55 00 56 00 57 00-58 00 59 00 5A 00 00 00 T.U.V.W.X.Y.Z... |
D>dir dfact.* D: DFACT PLI D>pli dfact PL/I-80 V1.0, COMPILATION OF: DFACT NO ERROR(S) IN PASS 1 NO ERROR(S) IN PASS 2 CODE SIZE = 00A5 DATA AREA = 0028 END COMPILATION D>dir dfact.* D: DFACT PLI : DFACT REL D>link dfact LINK 1.0 F 0100 /SYSIN/ 1BAD /SYSPRI/ 1BD2 ABSOLUTE 0000 CODE SIZE 1A54 (0100-1B53) DATA SIZE 01E5 (1C28-1E0C) COMMON SIZE 00D4 (1B54-1C27) USE FACTOR 5E D>dir dfact.* D: DFACT PLI : DFACT REL : DFACT COM : DFACT SYM D>dfact Factorial( 0 )= 1 Factorial( 1 )= 1 Factorial( 2 )= 2 Factorial( 3 )= 6 Factorial( 4 )= 24 Factorial( 5 )= 120 Factorial( 6 )= 720 Factorial( 7 )= 5040 Factorial( 8 )= 40320 Factorial( 9 )= 362880 Factorial( 10 )= 3628800 Factorial( 11 )= 39916800 Factorial( 12 )= 479001600 Factorial( 13 )= 6227020800 Factorial( 14 )= 87178291200 Factorial( 15 )= 1307674368000 Factorial( 16 )= 20922789888000 Factorial( 17 )= 355687428096000 Factorial( 18 )= FIXED OVERFLOW (1) Traceback: 0007 019F 0018 0000 # 2809 6874 0355 0141 End of Execution D> |