6800用のコンパイラを探して – Fuzix/CC6303(ベーシックマスター開発 その22)

BASICMASTER, 昔のパソコン

GAMEコンパイラの書き直しのために、参考になる6800で動くコンパイラがないかと探していたら、EtchedPixels氏(aka Alan Cox氏)によるFuzix OS内にCコンパイラがあった。

6502用のCコンパイラであるCC65を68系用にに書き直したもので、6803/6303では充分に動作するらしい。残念ながら6800では、サポートルーチンが欠落していて簡単には動きそうもない。


インストールメモ

まだ全然動かないのだけど、試行錯誤の結果をメモしておきます。下記の作業でコンパイラ単体が動くところまでは実行できます。サポートルーチン・ライブラリが無いので何もできません。

  • MacOSだとarが非互換なのでインストールに失敗する。Homebrewからbinutilsを入れて、そちらを使う。
  • https://github.com/EtchedPixels/Fuzix-Bintools を先に入れる必要がある。
  • /opt/fcc/lib/cppは homebrewのcppを使うように変更する。


コンパイラ出力を見てみた

longを使わなければ、もしかしたら実用になるかもしれない。longはサポートルーチンを大量に作らないといけない。long関係は出力コードも怪しい気がする。

  • intは2byte,longは4byteのよくある処理系。
  • charは1byteで扱う(引数としてpushするときも1byte)
  • 関数のcleanup(スタック戻し)は呼ばれた側で行う。スタックを戻すバイト数Nの __cleanupN を呼ぶ
  • (__cleanupNは戻りアドレスをどっかに保存して、SPにN+2を加えて、戻りアドレスに飛ぶ)
  • 戻すバイト数が大きすぎる時は、__cleanupを呼ぶ。戻す数はjmp命令の次にあるが、これだとダメだと思う…
  • 戻り値: char/int/pointer は AccABで返す。long以上はStackで返すっぽい


エミュレーターは使えそう

テスト用にemu6800というエミュレーターが含まれている。バイナリイメージを0番地から読んで、コード先頭から実行するという豪快な仕様になっている。

run-test6800.shを作って、下記のように修正すると、サポートルーチンを全く呼ばないプログラムは動く。どうも動的リンクが未サポートっぽい。
(emu6800.cはemu6809.cに合わせて、0xFExx へのメモリ書き込みをhookするように修正が必要。testcrt0_6800.sも6809版を参考にでっちあげる)

GAME68で$2000からのバイナリを作って、emu6800も$2000から読むようにすれば、それなりに動きそうである。
(文字入出力を入れないとテストは難しそうではあるが)

[code lang="shell"]
ld6800 -b -Z0 -C256 -B512 -m tests/$b.map -o tests/$b testcrt0_6800.o tests/$b.o /opt/fcc/lib/6800/lib6800.a /opt/fcc/lib/6800/libc.a
./emu6800 -d 6800 tests/$b tests/$b.map
[/code]