πの1000桁でハマる
CP/Mエミュレータで、手持ちの書籍「入門CP/M」に沿ってトレーニングを進めた。この書籍の最終章は、「12章 高級言語を使ってCP/Mを理解する」。MBASICとBASICコンパイラを使って、πの1000桁を計算するのが課題だ。プログラムのソースは本に書いてある。こんな時は、将棋の棋譜をそのままトレースするのと同様、ソースをそのまま入力してトレーニングするのが宜しい。エディタでソースを入力して、カット&ペーストでMBASICに流し込むことにした。まず、エディタでソースを作り込むのにハマった。きちんと動いてくれないのだ。もちろん原因は入力ミス。後々のため、どんなミスが有ったかを書き留めておくべ。・「,」を隣りの「.」に、「:」を隣りの「;」に、「;」を隣りの「:」と入力してしまうミス・「)」を「]」に打ち間違ってしまうミス・「O」を「0」に、「1」を「I」に見間違えたことによる入力ミス本とエディタを何度も照らし合せて修正&RUNを繰り返した。1回RUNさせると10分以上帰ってこない(多分ループが余計に回っているのだと思う)ので、1回の修正&RUNに時間が掛かってたまらん。きちんとπの1000桁を動かすようにするのに1日半掛かってしまった。(苦笑)そのソースがこれ。 ↓πの1000桁の実行時間は、6分20秒だった。本には、同じプログラムの実行時間が、PC-8001のMBASICで5時間以上、if800のCP/Mで4時間と書いてあった。それがポンコツPCのCP/Mエミュレータ上のMBASICで6分20秒!この本が出版された1982年当時と比較して、機器の性能向上に驚かされた。次に、πの1000桁プログラムをコンパイルするのだけれど、ここでもメチャクチャハマった。本には、コンパイルするのに、BASCOM.COM BASLIB.REL L80.COM が必要とあるが、BASCOM.COMが無い!これは”BASCOM.COM CP/M”のキーワードで検索して、発見。ダウンロード&展開で解決した。BASCOM.COMをエミュレータ上に取込む方法が分からない。これは、エミュレータに入っている R.COM を使うみたいだ。r {ターゲットファイル} で取込めるみたいだけれど、これもハマった。R.COM を使う上で {ターゲットファイル} 名は大文字かつ CPMエミュレータと同じディレクトリにある必要があるみたいだ。BASCOM.COMをCP/Mエミュレータのあるディレクトリに持ってきて、r BASCOM.COM で取込んで解決。本に書いてあるコマンド BASCOM P1000,P1000=P1000と打込んでコンパイル開始した。すると、BCLOADが無い、BRUN.COMが無いとのエラーメッセージが出て止まった。共に BASCOM.COM を展開した中に有ったので、これを R.COM で取込んで解決。もう1度 BASCOM P1000,P1000=P1000と打込んでコンパイル開始。今度はコンパイラは動いたが、フェイタルエラーが1行目で出ている。1行目はコメント文じゃんか、何で???コンパイラが出力した PI1000.PRN をタイプして、本の PI1000.PRN と見比べて気がついた。コンパイラがソースファイル全体を1行目と認識しているみたいだ。ということは、行末コードに秘密があるのかな。ソースファイルをダンプしてみて気がついた。行末が "0A" すなわちLFで終わっていた。もしかして "0F 0A" CR LF が必要? 調べてみたらLinuxの行末コードはLF、CP/Mの行末コードはCR LFだった。原因はこれに違いない。問題は、行末コードを変換する方法だ。これも調べてみて、いくつかの方法があるのが分かった。今回使ったのは sed を利用する方法。次のように打込んで行末コードをLFからCRLFに変換する。 sed -i ‘s/$/\r/g’ {元ファイル} > {変換ファイル}変換したソースファイルをダンプコマンドで確認。確かに行末がCRLFに変換されていた。変換したソースファイルで BASCOM P1000,P1000=P1000と打込んでコンパイル成功。出来上がったオブジェクトファイルを実行したら1分20秒で πの1000桁を出力した。大文字と小文字の使い分け、sedコマンドの使い方など、理解が不十分だけれど、とりあえず、ここでπの1000桁は区切りを付けた。残りは次の段階に進めながら、並行して理解を深めていこう。最後に、以前C言語に移植した ASCIIART をMBASICとBASCOMで描画してみた。実行時間は、MBASIC(インタープリタ)が14.79秒、BASCOM(コンパイラ)が5.40秒だった。MBASIC(インタープリタ)によるASCIIARTBASCOM(コンパイラ)によるASCIIART結果は同じ、当然だけど。ASCIIARTのソースファイル