LSI-C86 講座

setup

  • (LSI path)/bin に path を通す
  • (LSI path)/bin/kmmake があるが使う利点がないはずなので普通の make を使う

lcc86

コマンドラインオプション

  • -O は -O (最適化有効) か -O0 (最適化無効) の2つだけ
  • -B をつけると // がコメントになる (B 言語の B?)
  • あとは gcc と大体同じ

lcc86 はプリプロセッサ(cpp)、コンパイラ(cf, cg86)、アセンブラ(r86)の各コマンド群を呼び出すフロントエンド的な役割があるようだ。 lcc86 が呼ぶ cpp は (LSI path)/bin/cpp を期待しているものの、 path の都合で /mingw/bin/cpp が呼び出されてしまう。プリプロセッサの出力内容は全く知らないのだが、どうやら問題ないらしい。

(LSI path)/bin/cpp を呼び出したい場合は lcc86.exe をバイナリファイルで開いて cpp の文字列を無理矢理変えるなどすれば、かなり無茶だが直せる。

r86

コマンドラインオプションは出力ファイルを指定するぐらい。

命令は r86 専用名称になっている場合があり、 8086 の opcode が通らないことがあるのでマニュアルを参照すべし。

C 関数名/変数名はソースで定義した名前の末尾に _ が付加される。C から呼ぶ場合は _ はいらないが、アセンブラからは _ がいるので注意(はまった)。

C の関数の引数の与え方は、かなり複雑なのでまじに使うならマニュアル参照。面倒なので引数、型共に void の C の関数に jmp する命令だけにした。割り込み対応も最低限だけアセンブラで書くようにする。

lld

コマンドラインオプション

  • -M -g あたりを出しておくとリンク情報が出る
  • -Tsegment address とすると segment のアドレスを指定できる。
  • -Fh で ihex, -Fe で exe など出力フォーマットの設定が出来る。

segment は gcc でいう section のこと。標準状態で text, data, bss がある。 text は CSEG (code segment), data と bss は DSEG (data segement) となりどうも CPU のセグメントレジスタと関連しているようだ。ここらへんは動かして様子を見たい。

data, bss に関しては const は使えるものの, rodata がないので ROM に配置すべきデータも data となってしまう。グローバル変数は初期化せずに bss に飛ばして RAM に張るので、 data は実質的に const があってもなくてもかわらないことに...
現時点で data と bss のアドレスをかなり離したのだが stack overflow! とエラーが出てる。そもそも stack は別の segment だよな? よくわからん。

-F オプションでは exe を出してしまって先頭についてるヘッダの 0x200 byte を削り落とせば純粋な ROM 向けバイナリになるようだ。未使用データは 0x00 で埋まっているので実 ROM に焼く場合は 0xff にしたほうが好ましい。*1 今回は FPGA 内蔵 RAM に埋めるので問題ないはず。

*1:うちの安物ライターは 0xff でも書き込みシーケンスをやってるおばかさん。