2019年10月5日土曜日

CP/M-8000は移植できるのか リンカ 3

とりあえずCP/M-8000のリンカ ld8kは、Linux上に移植し動作するようになりました。
だれの役にも立たないでしょうが、移植のコツみたいなものを書き出しておきます。

もともとのC言語のソースコードはスタイルが古典すぎて、そのままではGCCでコンパイルできないので、まず今風に書き換える必要があります。
使われているコードのスタイルは次のようになっています。
func(a, b) int a;
{
    return(a + b);
}
  • 引数の型宣言は、関数の後ろ
  • 引数の型宣言は省略できる。型は int になる
  • 戻り値の宣言は省略できる。型は int になる
  • int のサイズは16bit
  結構ルーズな書き方も許されていて面食らうこともあります。
 
標準ライブラリも今時の標準と違うので、前後のコードと予想した動作から別のものに書き換える必要があります。
  • opena() --- テキストモードでファイルをオープン
  • openb() --- バイナリモードでファイルをオープン
  • seek() ------ ファイルシーク  
このあたりは、fopen(), fseek() で置き換えました。
 ファイルをオープンするモードや、シークポジションの基点などは、コードから推測して指定します。

Z8000がビッグエンディアンなので、スモールエンディアンと相互に変換するようコードに書き換えていく必要があります。これは、オブジェクトファイルから読みだす時と書き出す時に必要になります。
例えば、
unsigned int a;
read(infile, &a, 2);
上のような、ファイルから16bit値を変数 a にロードするコードは、下のように書き直します。
unsigned int a;
unsigned char buf[2];

fread(buf, 2, 1, infile);
a = buf[0] * 256 + buf[1];

CP/M-8000のCコンパイラは、関数名や変数名に8文字までしか使えないようで、命名が短縮され過ぎています。当時、短い名前は当たり前だったのでしょうが、名前から役割を推測しづらく、読み解くのは結構きついです。

なんやかんやでリンカは移植できたのですが、もとのCP/Mのライセンスの扱いがよくわからないので、コードは公開できないでしょう。 コードも分かりづらいし公開できるよう、できれば完全に書き直したいのですが、とりあえず先に進みます。

次の段階は、BIOSを書くことです。参考になるOlivetti M20用のBIOSのソースコードがあるのですが、アセンブリ言語とC言語で書かれており、CP/M-8000が動く環境がないとリビルドできません。なので、クロス開発することになるのですが、残念ながら XOUT フォーマットを吐いてくれる開発ツールは存在しないようです。GNU Binutils のクロスアセンブラは COFF を吐いてくれるので、これを XOUT に変換してリンクすることにします。

ということで、次はオブジェクトファイルの変換ツールを作ることが目標になります。

先ながいなぁ…

0 件のコメント:

コメントを投稿