2022年8月11日木曜日

ZCCの注意点

YouTube に ZCCで "Hello, world" する動画を上げました。

"Hello, world" under CP/M-8000

 ZCCを使ってみて気づいた注意点を上げておきます。なにせK&R時代の古いCコンパイラなので、今の感覚でコードを書くと、思わぬところでエラーの嵐に遭遇します。

・=- に注意

 「x=-1」 は、「x = -1」ではなく「x -= 1」に解釈されます。コンパイル時にwarningがでますが、オブジェクトファイルが出力されリンクも正常にできるので注意が必要です。実行してみて意図した動作をしないことで気づきましたが、理由がわからずしばらく悩みました。 かなり古い(K&R以前?)の書き方のようです。

・関数のプロトタイプ宣言に引数の型を含めない & 戻り値がなくても int で宣言

 これもかなりハマりました。次のように宣言します。

         int foo(a, b);

         foo(a, b) int a, b;
         {
            /* 戻り値なしの処理 */
         }

・unsigned char が使えない?

 unsigned int は使えるのですが、unsigned char はサポートしていないようです。

・関数名、ラベル名、変数名は8文字まで 

 Cコンパイラは名前の前に "_" をつけるので、実質使えるのは7文字です。それ以上の文字は無視されるので、気を付けないと違う名前を付けたのに同じと判別されてしまいます。アセンブラとリンカが8文字までしかとらない仕様なので、これは仕方ありません。

・コンパイラの -D オプションが働かない

 これは、The Unofficial CP/M Web Siteに書かれていました。試したところ本当に働きません。ヘッダファイルに、#define で定義しておく必要があります。

・コンパイラのオプションがわからない

 ZCCのドキュメントが失われているようで、コンパイラーに指定できるオプションがわかりません。今のところわかっているのは、上の働かない-Dぐらいです。CP/M-68KのCコンパイラにはドキュメントが残っているようなので、参考になるかもしれません。

・改行コードと終端コードに注意

 改行コードがCR+LFで、テキストがEOFで終端されていないとエラーに悩まされます。これはZCCというよりCP/Mの仕様なのですが、意味のわからないエラーメッセージがでるので悩まされます。CP/M上でコードを編集する場合は大丈夫ですが、LinuxやWindows上で編集している場合に問題になります。改行コードは指定しておけば問題ないのですが、末尾にEOFをいれてくれるエディターはないようなので、意図的に入れる必要があります。VimだとCtrl+Zで入れられます。EOFのあとにテキストが入っていても無視されます。

癖がわかってくると、ZCCは結構使える気がします。アセンブリ言語で書くよりは格段に楽ですから、多少の制約は我慢できます。

2022年8月1日月曜日

CP/M-8000にFPUエミュレーションを追加

 CP/Mのライセンスに変化があったのと、夏休みに入って時間ができたこともあり、CP/M-8000に手を入れています。その一番目として、やり残していたFPUエミュレーションをCP/Mにリンクして使えるようにしました。

作業としては、fpe.o と fpedep.o をXOUTからCOFFに変換し、biostrap.sを書き換えるだけですんだので拍子抜けするほど簡単でした。fpe.oはZilogが出荷予定だった実数演算コプロセッサのZ8070をエミュレートするもので、Z8070の命令がくると例外処理で実数演算をソフトウェアで実行します。

これで、ZCC(ZilogのCコンパイラ)で、floatが扱えるようになりました。ためしに、レトロCPU界隈ではメジャーなマンデルブロ集合のASCIIARTをC言語に書き換えて実行してみました。コードは下のような感じです。


これをコンパイルして実行したのが下の結果です。

見慣れたアスキーアートが出ているので、問題なく動作しているようです。ただし実行時間は遅く、7分44秒とかなり期待はずれな結果です。結果はともかく、実数演算がC言語で使えるようになっただけで可能性は広がります。試せる人はかなり限られると思いますが、この成果はGitHubのリポジトリに反映しました。

今後は、開発環境を改善していく予定です。私にはCP/M標準のEDが全く馴染まないので、まずはエディタをどうにかしようと検討中です。