Cコンパイラ開発顛末記 小窓次郎

はじめに
C3POとは、6809用に開発されたMicroCをベースにして日立のHD6301/6303にカスタマイズとチューニングを行った組み込み目的のCコンパイラです。現在DOSで動作するバイナリ-とソースコードとマニュアルなどがあります。開発の機会を与えてくださった、前職場の上司ならびに、快く端末開発の過程で付き合ってくれた仲間達、また没頭を許してくれた細君に感謝いたします。このコンパイラは、現在の状況で使う価値があるかといえば・・・?ということだと思います。まあ、まだチップとして630Xシリーズがあればフリーのコンパイラとしての価値があるのかもしれません。注意を加えるならば、このコンパイラはアセンブラソースコードを吐くタイプのコンパイラであってクロスアセンブラが必要になります。当時のクロスアセンブラの文法には準じたコードが出ますし、またその部分もコードが独立していますのでカスタマイズは可能です。ソースコードですのでご参照いただければ明白です。

開発されたのは、1984年12月が最初の版のリリースでした。1988年頃までは実務と趣味でメンテナンスをしてきたと思います。

アーカイブ(LZH形式です)

目的と開発の背景
このコンパイラの開発目的は次のようなものでした

  • 組み込み開発で適用可能なコンパイラが欲しかった
  • C言語を勉強する必要があった
  • アセンブラでのプログラミングノウハウをコンパイラにカプセル化したかった

今ならば、GCCも有りますし、昨今の溢れかえったFlashサイズなどからこだわりはなくなってしまったようですが、開発当時(1984)の組み込み開発事情を考えていただければまともに使えるコンパイラとは当時の8080用に開発されたLSI-Cだったかと思います。無論6809用であればMicroCはエレガントなコードを生成してくれました。コンピュータとしてのアーキテクチャが綺麗だったこともあります。しかし、私の暮らしていた組み込みの世界では、アーキテクチャよりも消費電力や多機能が搭載されていたマイクロコントローラという概念でかのモトローラと特許係争にまで陥ったほどのベストセラーになった日立の8ビットコントローラが厳然としたデファクトとしてありました。このCPUで16kBを越す大規模なソフトウェア開発の効率を上げたいというのが当時の背景でありました。

アセンブラベースで8kBぐらいの容量でメモリーダイヤル搭載の自動車電話を開発していた時代なのです。当時のアセンブラベースでICEと睨めっこしつつの開発というのは、現在のCベースで10MBを越すアプリケーション開発をしている状況から考えると稚拙に思われるかもしれません。せいぜい開発人数も3人で半年位かけて開発しているわけで8KBのコードですとアセンブラソースコードで9000行クラスでしょう。そうなると開発規模は、一人あたりの生産性は300ライン/月くらいだといわれていた時代でもあります。いまは、ベースとなるソースコードがCになって同様の数字なのでしょうか。アセンブラで記述するということによる問題点は相当の熟練を要するというのが背景にあります。スタック操作を誤れば簡単に暴走できますし、そうしたことからリアルタイムトレースといったツールや方法の必要論がまかり通っていました。

熱き青春の日々
そんな当時に米国でUNIXが登場して、時代はC言語だと言われて開発方法の転換ということが、現在のJavaなどと同様なレベルで言われていました。但し、C言語コンパイラの効率は低く、アセンブラベースでのコードに比べて三倍程度のコードサイズならびにそれに伴う速度低下が指摘されていました。マイコンの進化やコンパイラの進歩により改善されると言われるものの実際に使いたいCPUのコンパイラは開発ツールベンダーが提供するもの、あるいはチップメーカーが開発提供するものという流れでどれも満足いくコード効率や性能が出せるものではありませんでした。開発環境は、当然時代の渦中であるVAXとBSD-UNIX4.1/4.2です。決して、VMSではありません。開発環境としてのUNIXの作法を学びつつ、大文字のアセンブラの世界から小文字のCの世界への橋渡しというのも仕事でした。

トップダウンで始まったUNIXならびにスーパーミニコンの導入は笛吹けど踊らずというのは、ソフトウェア開発を生業にされている方々での共通した性質なのかも知れません。まずは、様子見なのです。判らないものに対して遠巻きにするのも、好奇心で追いかけるのもいずれもソフト屋の特性の表れではあるのでしょう。そんななかで進んで新しい環境を珍しがって飛び込んでいくのは生来のお馬鹿な気質なのでしょう。私に限らずそうした人材も少数派として存在していることを期待はしています。当時のVAX-UNIXという環境はBSDベースでの開発プラットホームとして多くの道具が提供されはじめた時代でもありました。いまやメンターに組み込まれてしまったMicrotecなどもそうしたクロスツールを提供しはじめた草分けでしょう。

当時の私は、8ビットマイコンを駆使してアセンブラベースの開発を手掛けていました。高圧縮型のインタプリタシステムを駆使した自動車電話やパーソナル無線の開発を通じてアプリケーション実装と性能実現のバランスについてはかなり苦労してある領域に到達していました。機器メーカーの技術者として、ハードウェア設計者ほどソフトウェア設計者の技術や仕事内容が理解されていない時代でもありました。いつまでもはんだ付けをしているというような印象のあるコーディング作業に従事するわけにも行かず、メンバーを増やしつつの開発を手掛けるようになり自分達の到達したノウハウの共有なども含めて現実の難しさに直面していました。HP(現アジレント)の開発マシンを揃えて、一通り軌道に乗り始めた開発スタイルで、マルチボードのZ80ベースのシステム開発などを通じて中型コンピュータからリプレースする商談を開発実現したりと、詐欺のようなある意味とんでもない開発を実施実現してきました、こうしたことから、ある意味でアセンブラベースでの開発限界に到達したという感触もありました。

そんなシステム開発経験の後に、業務用無線機の第二世代機の開発を命じられた時に、当時の開発志向として「ソフト開発はC言語で」という新たな流れに乗らなくてはというトップダウン指示に、うまうまと乗ってしまったのです。既に開発を終えたアセンブラベースの第一世代からの移植とはいえ、コストダウンもテーマとして挙げられていて、8ビットマイコン+EPROM 8kBというシステム構成からデュアル4ビットマイコン(4KB)というシステム構成に向けて開発を行うことになりました。この社内で開発された4ビットマイコン用の簡易C言語を適用しようというのが取り組みでした。ドライバー・プロトコルマイコンとUIマイコンの二つなのですが、ドライバー側マイコンの開発を実際に一人で担当して開発環境の構築から始まって初めてのUNIX環境でのC言語体験というハードルをこなして開発を終えました。性能も満足いくものでした。しかし、複雑なUI機能を実現する上で当時のアドレッシングに制限のある4ビットマイコンのROM容量は不十分で、詰めようにも処理単位は256バイトに収めなければならず、全体でも4KBというサイズでは入らないことが最終的に明白になり開発は失敗に終わりました。開発で培ったUIマイコンの液晶表示機能やサウンド機能のみを使った表示系サブシステムに使った8ビットマイコンシステムのグレードアップという形で不本意な開発となりました。C言語が合わないというよりもシステム設計の目算が不十分だったというのが反省でした。アドレスに制限のない8ビットマイコンなら適用は十分に可能というのが私の得た経験でした。

開発失敗で、次の開発プロジェクトでリベンジのチャンスが来ました。開発完了した例の無線機に搭載する無線データ伝送ユニットの開発というテーマです。8ビットマイコンで16KBという大容量のシステムが当時の8KB程度だった無線システムからの移行ということも含めて開発検討をしつつ適用の方策を模索しました。HPの開発環境で既に提供されはじめていたクロスコンパイラはモトローラの6800に対応したものでしたが、リエントラントな構造を実現していく上で不十分なものでした。インデックスレジスタをスタックに退避する命令が無いことからサブルーチンでプッシュポップをするサブルーチンがバインドされてしまい、この処理時間が当時の割込み処理周期である0.8msを越える時間を必要としていたのです。しかし実際に適用するマイコンは6800の上位互換性を有する日立の6301でインデックスやビット操作など制御用に必要な機能が強化されCMOSベースで低消費電力も達成する優れものでした。HPの開発環境ではツール開発もままならずUnixベースへの移行などをベースに考え直すことにしました。

6809用に数年前にソース公開されていたMicroCの記事を思い出しました。FLEXベースのOSで動作するコンパイラでしたが何しろCソースが公開されていたのでUNIXベースに移植して6301用に必要な最低限の改造を試みることにしました。よく出来たソースコードでしたので、コンパイラの仕組みから学ぶことも含めてよい勉強になりました。一週間ほどでとりあえず6301用の命令のみに対応することが達成できました。満足いくコード効率ではありませんでしたが、今後の改良でなんとか成るだろうという安直な考えで利用することにしました。課題としては次のものがありました。6301では条件分岐命令が8ビットオフセットの範囲でしか飛べないので分岐条件を逆にして届くようなロングの分岐命令を展開する必要がある。命令の効率はいまいちである。6809の命令を6301用に変換したためともいえるが最適化という観点からは未着手なものである。開発ツールとして利用してきたHPのクロスツールを当面は利用するのですが、開発マシンをVAXへの端末としてログインすることでコンパイルされたソースコードをHPの開発マシン側で利用してまずは開発に利用が可能となりました。

VAXとHP開発マシンの二つが必要になるという条件でどれほど当時利用価値があったのかどうかは判りませんが、まずは開発環境としてリリースすることが出来ました。知己であるペンギンソフトの筒井君がインタフェース誌にコマーシャルを打ちましたが案の定、この件について問い合わせしてきたユーザーは、HPと日立のみでした。会社のアドバンテージとしての開発ツールですから売れる必要性はありません。むしろ会社独自のツールとしての性能向上を図ることで会社での製品性能全体が向上するというのが私の考えでもありました。こうした意見は、開発マシンからの移行をUNIXに進めていこうとする会社側の思惑とは乖離していたかも知れません。生意気だと思われていたのかもしれません。コンパイルされたソースコードに自分自身で文句をつけつつ最適化の長い道のりに自分の空いている時間を費やす趣味のコンパイラ開発改善の日々が始まりました。開発されたコンパイラを利用していくためにはRTOSの壁がありました。Cコンパイラはその性格上、スタック領域を多用します。通常のRTOSを適用すると、各タスク単位で所要のスタック領域を確保する必要がありました。こうなるとCを利用するとRAMサイズが大きくなるという話になってしまいます。

この矛盾を解決したのは、当時利用していたオリジナルのシングルスタックOSでした。このOSでは、プリエンプティブではなく、タスクは同時には一つしか動作しません。タスクへの実行制御要求は、優先順位でキューイングされるために、各タスクの所要時間(およそ数00us)でタスクは終了する設計になっていたのて最優先のタスクが実行されることになります。不用意にタスク遷移を行うよりも効率もよく、当時のシステム設計には十分でした。このOSを改造してシングルスタックでWAITが掛けられるような工夫を施しました。WAITしているコンテキストおよびスタックをQUEに退避するような機能を追加したのです。制限はありましたが使いにくさは大分改善されました。使い勝手の観点から、UNIX系のみでで開発ツールを揃える上で必要になったのはクロスアセンブラです。当時の私は、コンパイラへの興味はありましたがアセンブラは既に標準的なものとして対応できるはずだという思いから市販のツールを捜しました。

UNIXベースでのツールといえば、当時のWhiteSmithはある意味で純正あるいは正統派の流れとして評価されていたように思います。このツール群にはXA8というアセンブラ群もありました。この汎用のクロスアセンブラを用いることにしました。このツールでは条件分岐を自動判断する機能が搭載されていてコンパイラで最適化を考える必要はなくなりました。唯一の問題点は、6800系統で必要になるアドレス最大値に配置する割込みベクトルのリンクです。割込みベクトルはFFF8からFFFFまでにRESET,IRQ,SWI,NMIなどの最低四つのベクトルが6800系統では必要になります。8080系統では0番地から配置すればよいのでこの辺りの作業が手作業になるのが課題でした。まあ不便なのでリンクを二回に分けて行う事にして、割込みベクトルを最後のモジュールとしてリンクして必要なオフセットを全体にかけて再度リンクを行う事でベクトルの位置が適切な位置に配置されるようなリンカーのドライバーを開発して解決をみたわけです。手作業なしでツールによるmakeベースで構築できたVAX版のツールの開発完了でした。

実際の開発ツールとして
さて、開発ツールメーカーではありませんので実際の開発に使ってなんぼのもんです。ツールの完成度の評価も実際の製品開発を通じてチューニング出来るのも逆に強みなのかもしれません。通常の言語ツールメーカーのサイクルとはある意味で比較にならないサイクルなのかも知れません。実のところは知る由も有りませんでしたが・・・。元々の開発目的であるROM容量16KB+RAM容量2KBほどの無線端末通信制御ソフトはアセンブラベースでの開発で進められていました。市場に投入した二つの無線端末の開発では、新任の女性技術者が設計した初めてのC言語ベースの端末が回収することもなく順調にサービスインしたのです。これは当時は画期的なことでした。システム件名で開発しているアセンブラベースの端末では数回に渡る現地でのROM交換など当たり前の世界だったのです。バグフリーで開発しうる要素が少なくともC言語で達成できたのです。当初は製品の機能確認レベルに必要な性能でしたが製品としての機能が満載になるにつれて複雑化してきたソフトウェアソースから生成されるアセンブラコードの内容も満足の行かないものが出てきました。何故こんな効率の悪いコードが出来てしまうのだろうか。しかし、リアルタイム処理のデバッグと違ってコンパイラの開発は実に簡単です。バグが必ず再現するからです。

Parserが食べて作成したtokenのリストの解釈を出来るだけ長く先読みをしながら生成するのが良いコードを出す秘訣でした。生成したコードが保有しているであろうレジスタやフラグの状況を管理する機能も追加しました。アセンブラベースの技術屋なら当たり前のことですがコンパイラは局面毎の譜面のみをベースにコードを作成しますので難しいことなのもかも知れませんが納得のいくコードを出すためには必要な技術と判断して追究しました。開発マシンを使って実際の開発と、開発ツールの開発が並行で行われているのは大変なことなのもかも知れませんでした。生成したコードに問題があると聞くと直さずにはいられないし、使っている方は安定したリリースを求めます。そうした葛藤が続く中で利用していたプロジェクトチームにある事件が起きました。

いつもの様にソフトウェアの開発を進めていた女子社員が開発したソフトをコンパイルして出来上がったアセンブラソースコードを用いてデバッグを進めていたところ、いくつかの確認をする意味でパッチを入れて動かそうとしたら動かないのです。このことを開発を進めていたリーダーに報告してソースコードを見てもらいました。よおく見ると今までと随分違う命令が出来ていて入れたパッチが合いません。まるでコードの前後関係を読んでいるような変なコードです。「またあ、裏で小窓さんがログインしてソース書き換えられたみたいだな、こう直せば通るかな」と指導をもらいましたが中々修正した結果もうまく動きません。「コンパイラのバグレポートを書いておいてね。どこから小窓さんは仕事しているんだろうね。」そんな事態を知らない私は年休を取っていました。

翌日出社すると、ニコニコしながらバグレポートを突きつける新人女子後輩社員がいます。「昨日は変なコードが生成されていて大変でした。これです、みてくださいな。」と渡されたコードリストを見せられて「で、どこがおかしいんだい・・・これかな・・・ここかな。でも正しいよ。」と話すと何だか大変な様子です。「え・え・・・でもパッチを入れたところでおかしくなるんですよ。」と怪訝そうな顔で促すと「ああパッチしたのか、へへパッチしちゃいけないんですよね。命令とレジスタ状態はコンパイラが管理しているからね・・・。」と話すと反応が無いのは、目を回している様子の周囲であった。確かに、コンパクトな命令が生成されているのだが、「パッチよりも修正してコンパイルだね。」という流れが最近の悪しきソフト開発の芽を育んでしまったのかも知れない。実際パッチできないほどの最適化レベルを実現しているのだった。不要な命令を出さないコード展開は、アセンブラ技術者が書いたコードよりも小さくなるほどだった。小さくなる理由は、変数使い方などの理由なのだがスタック割付によるRAMの圧縮なども効果を出していた。適用した68系マイコンはインデックスアクセスするとコードサイズが減るのでした。

潮風の果て
開発したコンパイラーを利用して、本来の無線装置開発に適用していった。無線装置としてそれまで開発してきた物を流用してある大きなシステム開発を受注したものに対応することになった。無線データ伝送システムとして初めてのデータの放送である。一対一での通信であれば相互に確認しあうことで信頼度を高めていくというのが伝送の基本である。一方通行で多数に報知していくという放送という仕組みを必要とするのには訳があった。成田に続く国際空港の建設が関西に海上空港として進められているのは聞いていたのだが、この建設工事に無線のデータ放送が必要なのだった。業務用無線の特殊性というか一般的な使い方としてグループ相手の通信という物がある。これにデータを適用するというのが、ことの発端でもあり、受注の理由でもあった。海上の幅広い海域をサポートする為には専用の中継局の設置から搭載する電話装置とならんでデータ伝送先というものとしての某かの端末あるいはパソコンなどが必要になっていた。

このシステム受託が決まるまでの製品ラインとしては、小規模ユーザーに向けたパソコンなどのBASICで記述できるような簡易手順を実装した物と、大規模ユーザーに向けた専用プリンターなどの端末との専用手順を実装した物とがあったのだが今回のシステム開発にはその二種類に対応していく必要があった。接続するデータ源は、気象庁の保有している潮位情報をもつテレメータシステムであり、これが保有している通信手順に合わせなければならない。データ配信先は漁船に積まれたパソコンであり潮位情報を受け取りプリンターに印字するので、これはパソコン側で処理をすれば良かった。データ配信では、応答を返すことも出来ないので一方的に送られてくるパケットデータを連送していくことで誤り訂正(FEC)と誤り検出(ECC)によりパケットを再生してリンクリストを再構成して外部に送出するというのが仕様である。連送して放送される内容とは潮位データなのだが、埋め立てをしている船にとって潮位の絶対情報が放送されることで超音波測定で得られる海底までの相対距離から当日の埋め立てした絶対成果とを算出するのに必需なのである。無論業務用無線機なので音声通信が個別あるいはグループで通信できるのは有用な機能であった。ちなみに電話には繋がらないが・・。

O電気で開発されたテレメータは既に以前から稼働しているものでありその機器との通信は伝送制御仕様書に基づいて開発するものの実際は現地でのなき合わせを必要とした。テレメータ装置は二つあり、一つは空港建設予定海域の海上にある潮位センサーである。海底から立ち上がっている人工鉄塔の上部のみが海上に突出していてそこにセンサーが収容されている観測所がついていた。岸和田沖にあたる、そこに行くのには作業用として借り出されている漁船に乗っていくしかなかった。もう一つの接続先は和歌山に程近い樽井という駅の側にあった気象協会の施設におかれていた。そこには中継装置自体も設置されていた。両方のテレメータ装置は同じ仕様で出来ていた為に海上局との相手はある意味で陸上局の装置とのなき合わせで解決できる筈だった。活躍するのは、シリアル接続をモニターするプロトコルアナライザーである。潮位テレメータ局に何度かROM交換に行ったのだが、揺れる船から飛び移ったりするのはスリルがあった。バッテリー動作する機材しか持ち込めないのではあるが貴重なバッテリー動作のテクトロニクスのオシロを抱えていくのはびくびくものである。使う船によっては軸方向には揺れず左右にしか揺れない船もありそうした場合には舳先までの中心線を進む限りは楽だった。舳先が上下するような船と波の状況の時には気合を入れて飛び移るだけである。

空港建設で沸き返る現地には、工事に出入りする業者などに向けて新興のビジネスホテルを準備していた。現地で鳴き合わせのテストをしていきながら見つかったバグを直すのにはコンパイルをする必要がある。しかし自分で開発したクロスコンパイラを使う為には、電話で事業部の開発マシンを呼び出す必要があった。早速持ってきたエプソンの1200bpsのモデムをホテルの電話に接続してUNIXマシンにログインする。持っていったPC98LTで端末ソフトを立ち上げてATDxxxとダイヤルするのである。「ピーギャーギャー」という音がベッドの上に広がる。音が止まりキーインするとログインのプロンプトが出てくる名前とパスワードを入力して横浜のマシン環境が繋がる。開発環境に移動してviでソースを開く1200bpsでは画面が全部は出てこないので時々ctrl-Lを叩いて画面をリフレッシュする必要がある。修正をして、makeを叩いて電話をきる。電話代が掛かるので、コンパイル完了を見計らって電話を掛けなおす。完成したhexファイルを端末ソフトのログ機能を活かしておいてからcatコマンドで画面に出すことで受信に替える。時々モデムがノイズで化けると二回受信して対応個所を訂正する。一晩で電話代が15000円を越えてしまったが持ち合わせが無く振り込み先などの対応を聞こうとすると慣れないホテルマンは「見なかったことにします」といってくれた。これでは仕事に支障が出るので知り合いがいる研修所に押しかけて電話線を奪取して利用したりとかしたのだが、最終的には気象協会の電話を借り受けてあとから請求してもらうことにした。この時の滞在で解決したのだが電話代の請求額は100万円を越えていた。この時の請求額は現地の営業所でも処理できる額ではなくて事業部にまで回ってきた。決裁を申請して処理をした。DOSで動作できる環境にする必要を強く感じた。

開発環境という製品
C言語開発環境としての完成度が高まってくると、本格的に逆手に取った製品が企画された。ソフトウェア開発環境も合わせて提供してユーザーにソフトウェアを開発してもらうという製品である。いわゆるクリーンコンピュータ的な考え方を持つシステム商品である。いまでこそSDKは当たり前の世界だが、当時何をしたらよいのか右も左もわからないままであった。無線機やその応用システムを開発している事業部ではあったが、そうした端末機器の開発という範囲であると事業範囲を逸脱してしまう畏れもあった。企画された商品は、流通業界向けのデータ端末でありペン型バーコードリーダのケーブルレス版である。いわゆるインテリジェント型の商品でデータを格納する機能をもつ強烈な個性の商品である。こうした個性のある商品であればデータ端末事業を進めている他の事業部との関係も崩さないですむ。事業部制をとっていた会社としては、市場競合する商品が生まれることもあったのだが隣接する事業部同士でもありトップ同士で話を通して開発は進められていった。

まずは、試作品の開発であるが、マスクROMにBIOSとプログラムローダを搭載して周辺装置もあわせて開発することになる。周辺装置はまずは代用品でBASICパソコンでちょちょっと書き上げてプログラムローダを開発した。無論ダウンロードするデータである端末側のソフトウェアをINTEL-HEXの形式からBASICの構文であるDATA文への変換ツールなどもでっち上げでUNIX上に作成する。バーコードソフトハウスとの共同開発でBIOS側の仕様化以降はICEベースで開発を進めてきた試作品が出来上がってきた。ICEとの組み合わせでダウンロードの確認を終えた。COB(チップオンボンディング)と呼ばれる工法で開発された超小型の端末は、ICのシリコンが直接基板に実装されて金線でボンディングされて樹脂で封止されて出来ている。FLASHの無い時代には、ソフトウェアの完成度は高めておく必要があった。間違えば捨てざるをえないのである。

マスクROMの訂正ということには以前取組んだことがあった。当時はEPROMなどが無い時代でもありMASKROM自体がLSIの扱いであった。いくつかの対策をソフトウェア的に織り込むことを実装した。ダウンロードが出来れば、BIOSをRAMで動作させることが出来るようにしたのである。そんな対応策を考えつつ、モックアップが出来上がり、ブレッドボードでの動作試験などが進み、実際のMASKデータが発注されてシリコンチップが入荷してきた。このチップは早速、超小型実装には定評のある長野の協力会社に発送され、そこで組み立てられた試作品が事業部に到着してダウンロードを試みた。しかし動かない。ダウンロードさえ出来ればBIOSのバグは回避できるのだが・・・。ソースコードをひっくり返してみると・・・・。

高密度実装が求めたもの
動かない試作品を前にして、ソフトウェアの確認と現象の再現確認とをあわせて進めると、基板にリセットを掛けるとうまく動作するタイミングもあることが判った。ソフトウェアのソースを確認していくと、とんでもないことが判明した。スタックポインターの設定を忘れていたのだ。ICEで確認をしていたために、ICEのファームがバックグラウンドで設定してしまっていたこうした事態を確認できないでいたのだ。リセットされた段階でスタックポインタは不定なのであった。たまたま、この値がSRAMの範囲に合致した場合には動作が開始されるのである。64KBの空間にしめる40KBのSRAM空間の確率は5割を超えていたために何度かリセットをすると動作することになった。動作した場合には液晶表示が初期化されるので判別もついた。なんと最初からBIOSのバグ回避を行うコードをダウンロードする事態になってしまった。その上、ダウンロードに成功するのは何度かに一度である。ダウンロードできればソフトウェアは訂正される。訂正されたBIOSがSRAMにあれば、訂正されたダウンローダが動作する。割込みベクトルの訂正処理などを回避したコードを納入されていたソースコードに加えてアプリケーションプログラムと結合してロードデータを作成した。アプリケーションはC言語での書いたために簡単に開発が出来て、それまでのICEベースでの開発環境から考えると見違えるほど効率的にデモソフトが完成できた。ブザーでメロディを鳴らしたり、ランプを点滅制御したり液晶に結果を表示したりといっぱしの端末として通用するものが、こんな簡単に開発できるのかと組み込みばかり進めてきた自分にとっては驚きの日々でもあった。

試作品にようやく訂正されたデータがローディングされた後は、充電さえ欠かさなければデモが続けられる状態となった。しかし問題は試作機を米国の展示会に持ち込みデモをする必要があり、持ち込む環境のパソコンは通常使っていたEPSONのHC20ではなく、NECのPC8201であった。マイクロソフトのBASICとはいえ当時のパソコンは数々の方言がありとくに周辺機器やシリアルなどのアクセス方法には大きな違いがあった。借り受けたNECのパソコンとそのマニュアルとを首っ引きにして自宅で訂正したソフトを仕上げた。無事、試作機とパソコンは海を越えてデビューを果たした。試作機で問題が明らかになったBIOSの改版は直ちに行われて製品版のマスクROMには訂正が加えられた。開発環境としてのC言語の優位性が、周囲からも理解が集まり開発環境自体を製品に加えて提供していくというまるでパソコンメーカーのような事業が始まることになった。コンパイラーをDOSで動作させなければならなかった。DOS版のクロスアセンブラーやダウンロードツールの開発、マニュアルやSEの育成といった段階を考えると、実感が湧かないのは致し方なかった。そうした開発を始めつつ、周辺機器開発にも着手してホストコンピュータとの伝送と充電を制御するアダプターも端末同様に同じマイコンにUARTを追加搭載してプロトコルの変換を行った。端末との間の特殊手順とホストのための通信手順の変換を行ったりするのが目的である。こうした端末の導入に当たっては、既存端末とのリプレースメントが前提となるのでホストの接続手順は踏襲することが必要で、実装面で必要な訂正があればなにかアダプターを介して解決するのが一般的だった。

プロトコルを整理して、一気にコードを書き上げてコンパイルしてアセンブルしてROMライターにダウンロードしてROMを書き込み、実装して確認する・・・。というのが開発サイクルである。こうして、その日のうちにソフトは動作した。端末を多量に導入するお客様にとってはシングル用のアダプターも複数台に対応するアダプターも必要だった。複数の端末が充電スタンドの如きスタイルであたかも輪投げの的のようなものだったが、連結されて利用される様は圧巻だった。業務の終了した端末は伝送スタンドに挿入されて状態ランプが点灯あるいは点滅して、状態(伝送待ち、伝送完了、異常)を知らせていた。開発に必要なライブラリも自作しつつ整備していった。関数の仕様書は、UNIXを見れば内容は明らかだしよいサンプルが沢山あった。あとは自分のコンパイラでコンパイルするだけの話である。連結された端末ならびにアダプターは、1台のホストコンピュータに順序制御されて次々と伝送を行っていった。運用にあわせてシングルモデルのアダプターはプリンターへの印字制御で帳票を発行する際にも利用されていた。色々な機能を持っていたアダプターであったが、いずれの開発も数日のうちに終わり、日常の開発の効率化は十分に達成していて、かつてアセンブラベースで開発して苦労していたICEや開発環境の悲惨さについては個人的には忘れ始めていた。

UNIXからDOSへ
開発環境としてDOSへの移行は電話代の一件もあり、また端末開発ツールとして提供する話も持ち上がってきた為に悩ませてくれた。UNIXで開発されたコンパイラの移植の壁になったのは当時のLatticeやMSCの完成度ならびに言語仕様がIntelの制限として示されたからでもあった。ポインターとintのサイズの相違とコードサイズが64kbを越えるモデルがまともにコンパイル出来ないからでもあった。コンパクトモデルからラージモデルへの移行と共に内部のコードをDOSとUNIXとで共有できるように変換するというのが求められている実態でもあった。コンパイラとして必要なのはリスト構造のハンドリングとトークンである文字列データの取り扱いだった。コンパイラ的に考えると、ポインターを直接扱うことに問題があるのでポインターの配列を定義しておき関数の引数で扱うのを、その配列の要素に置き換えることでUNIX的にもDOS的にも同じ関数引数サイズになるようにした。どちらも必要なデータは16ビットのintで足りるのである。

このクロスを買ってくれていた知人の筒井氏が、彼が開発していた南極ペンギンコンパイラを提供してくれた。生憎とまずは個人ベースで始めた移植作業であったが、まともなコンパイルマシンが当時は自宅にはなかった。バーコードの開発で知り合ったシステムハウスの方が知り合いが技術評論社にいるからと紹介してくれた。彼らには、コンパイラ記事の掲載を約束するなかで原稿書きと移植用マシンとしてパソコンを借り受けることに成功した。借り受けたパソコンはNECから評価用に預かっていたらしいPC98のVF2だった。残念ながら原稿期限には間に合わなかった。当初は、これを利用してミドルモードなどでツールをコンパイルした。暫く利用した後に、やはり知人のサザンパシフィックの片山氏が取り扱ったTurboCがより実用的なコンパイル時間と性能を提供してくれたためこれに乗り換えた。出来上がったコンパイラはPC98LTの制限されたメモリサイズでも十分に稼動出来るものとなった。課題は、懸案となっていた分岐処理の最適化である。UNIX版で利用していたXA8というアセンブラで保有していた自動距離認識形の分岐最適化機能が一般的なアセンブラには搭載されていなかったからである。

とりあえず、コンパイルした成果が届かない場合のみ手を入れるという暫定策でクロスアセンブラを捜した。インタフェース誌に広告を出していた京都マイクロコンピュータのPROASM2をターゲットにしてアセンブラ命令の幾つかが対応可能な形にコードを書き起こした。HPの開発ツールあるいはUNIXのXA8あるいはDOSのクロスという形で対応が可能なようにしたのである。

日常の業務のサイクルで達成したき成果は何時しか、他のターゲットを捜していた。季節は春を迎えて新人が配属されてきた。宇宙工学科の卒業という優秀な女子社員の研修を仰せつかる事になった。まずはC言語のお手並み拝見ということで少し意地悪なテーマとして、分岐オプティマイザの開発を命じた。初めてみるコンパイラーが生成したCソースのコンパイル出力結果であるアセンブラーソースを説明して、命令の語長などを解説して分岐命令が届くか届かないのかを判断しながら分岐先への命令を条件分岐もしくは逆条件分岐と遠方分岐命令の組み合わせかを選定するというファジイなテーマである。当時流行していた鉛筆回しをしながら考えていた新入社員にこれで暫くはテーマに事欠かないと高を括っていたら週末には「出来ました」と成果を繰り出してくれた。「確かに正解だ、優秀な学生がいるのはさすが東大なのか・・・。ここまで論理的な考えで進められる、この優秀な社員であれば・・・」と悪巧みは次の段階に進んでいった。

初めてのCの組み込み開発
先に開発していた、バーコードリーダーの接続アダプターには実はシリアルポートが二つ搭載されていて、一つはプリンターに接続されて、残りの一つはホストコンピュータに接続される仕様になっていた。見方を変えれば、二つのシリアルポートを保有する制御マイコンとも見えるのである。私が、こうした細かい世界に没頭している中で、仲間達にはもっと大きな共通ボードの開発をしているもの達もいて、ある組み込みOSを搭載した共通ボードの開発に苦労していた。開発環境は当然のようにUNIXである。開発したオブジェクトのダウンロードが課題の一つであった。今となっては笑い話なのかも知れないのだが・・・。当時から、そのOSはソースでは提供されていなかった。完成されたツールチェーンとして自信作として引っさげられての提供だったが実際に適用されたUNIXマシンであるVAX11-780の構造が問題を引き起こしていたのだった。シリアルでオブジェクトのダウンロードを行うと聞けば、「ははん」と納得する方もいるのかも知れない。フロー制御の問題である。ダウンロード側のOSもディスクを搭載しているシステムであるためにファイルの書き込みとシリアルの制御の間にはクリティカルなバッファ制御が必要なのである。

UNIXと同様な、その組込みRTOSシステムでは標準化されたシリアルからファイルへのリダイレクトも自在なのであったがOSレベルで考えていたフロー制御のレスポンスを狂わすほどVAX11で持ち合わせているフロントエンドにある入出力チャネルコントローラとUNIXカーネルの組み合わせではストップキャラクタがカーネルに到達して制御をするまでの間に入出力チャネルコントローラが溜まっていたデータを吐き出してしまうのであった。フロー制御文字のバッファ管理と反応速度が相互の環境でマッチしなかったのである。何かアダプターを開発する必要があった。そんな状況に登場した、優秀な女性技術者の卵は、組み込みソフトという業界が、変貌しうるのかどうかの試金石でもあった。彼女には、自分が慣れ親しんだユニットである制御マイコンボードの回路図と雛型になるであろうソースコードを提供した。私自身は同時に二つのシリアルデバイスを制御することは無かったが、それぞれの割込みドライバーは書いておいた。後は、彼女が実際のシリアルデータのやり取りの渦中に割って入ってバッファリングすればよいのだ。ただし許されたRAMは内蔵の192バイトでありROMは16kBほどのサイズである。当然なのだが、ICEは与えず、ROMライターでコンパイルしたコードを焼きこむ開発サイクルを示した上での研修開始である。さて、首尾は・・・・。

点滅するランプの意味するもの
彼女が開発が進めているのはユニークで通信アダプターに搭載されていた発光ダイオードを使ってモールスのような点滅パターンで状態を示す機能を入れていたようだった。テストをしていると、そのランプが「パパパー」と点滅した。意味を聞いてみると、「これは、ですね・・・オーバーランエラーっていうビットが立ったみたいです。」と説明してくれた。さすがに9600bpsの同時送受信なので割り込み時間は間に合うはずだが・・・。割り込み処理が二重化されていたために割り込み処理の最中にもう一つの処理が間に合わないようだった。「割り込み処理が間に合わないみたいだね、何か対策しなきゃね」と説明した。コンパイラの機能としては、割り込みの禁止許可という制御が特殊関数の形で呼び出すことが出来るようにしていたので、その機能を説明した。処理時間としては間に合うだろうという見解を伝えて工夫をするようにという指示を出した。その日の内に彼女は課題をクリアした。

LEDを点滅させてコンパイラとROMライターのみで、このシステム開発を彼女は達成することが出来た。開発するシステムが簡単だったのかも知れないが、ロジックとして机上で追いかけて動作させうるということが誰でも達成しうるということの事実の方が衝撃的だった。まだ、Cコンパイラに移行できずにICEとアセンブラにしがみついて開発している他の仲間達との間で効率改善や開発スタイルの大きなうねりを予感せずにはいられなかった。ソフト開発を一通り経験した彼女は、実際にはハードウェア技術者として製品の担当者として活躍していった。ソフトウェア開発の指示を次々と繰り出してシステム上のトラブルもハードとソフトの境界線を確認して解決していった。

彼女は私が開発していた無線機の次機種を担当して、何のトラブルも出さずに開発を完了させてしまった。開発にトラブルが無いために工場や品質管理などから名前を覚えられることもなかった。仕事の出来る人を見極める仕組みは、この会社にはないようだった。トラブルを出して解決していくというのは、その人間の力不足の投影以外でないという見方も出来るのだが・・・。「よくやっているなあいつは・・・」というサイクルで評価が高まっていくのだろう。

地方巡業などを経て
先に開発したバーコードリーダーのソフトウェア開発キット(SDK)の開発が正式にはじまって、京都マイコンに会いに行くことにした。開発キットの企画台数は50セットである。OEMというには少なすぎるだろう。開発キットの価格としては150000円程度という破格の価格を考えていたので原価ベースで考えるとアセンブラの費用としては15000円程度が関の山であった。費用のお願いをしてまとめても100万円程度にしかならないのだが・・・と切り出しつつも社長の山本さんも専務の塚越さんも技術屋仲間であり高専仲間でもあったので話が通じたのである。組込み業界のの黎明期ということも手伝い開発の苦労話などを一升瓶を携えて持っていたのが功を奏したようだ。快諾していただく中で開発で当時活躍していたHPのROM-ICEの効用について語っていた。ROMのピギーパックが流行っていたこともあり殆ど全ての組込み機器の開発をROM-ICEで行っていた当時の実情だった。トレースが取れてResetからの動作が確実にキャプチャーできるという機能は他にはないものだったからだ。残念ながら、そうしたICEが安価に手に入らないのだと悔やんでいたのだが、後年、更に踏み込んだ機能を登載したROM-ICEとして京都マイコンが開発したのは、このときの話がきっかけだったかも知れない。

京都マイコンで開発されたクロスアセンブラは、当時岩崎技研の取り扱いとなっていた。直接話を持ち込んでマニュアルの原稿などを元にJstarに打ち込みなおした。ビルドする為の機能をDOSツールとして開発して、またソフトウェアダウンロードとデータの受信ツールなどを組み込んでいた。シリアルのインタフェースを駆使して各種のパソコンに対応させるのには幾つかの苦労があった。IBM/富士通/NECの三社をカバーすることで漸くツールとしての完成となった。開発した開発キットは、 コンパイラ、リンカ、アセンブラ、ライブラリアンのマニュアル、開発SDKのマニュアル、バーコード端末のBIOS仕様書とサンプルアプリケーションのソースコードだった。

開発説明会を地方の御客様を支えているソフトハウスなどを対象に行った。まだまだC言語自体が一般化していない時期でもあり、現場の方々からは「ベーシックはないのか・・」などという質問などが横行していたが実際問題としてBASIC以上の表現力はあるとはいえ、コンパイルするという手間があったのだろう。BIOSもコンパイラも自分で開発したので何が問題となって起こっても自分の責任である。開発環境としての精度を高めていく上でコンパイラの公開がより効果を生むだろうと考えて時期を遅れてしまってはいたが、技術評論社のプロセッサ誌上に掲載すると共にNIFTYのC言語フォーラムで公開した。会社で作成したマニュアルを当時のワープロであるP1EXEで書き直したりして配布した。幾つかのバグを検出したり出来たのはそうしたことの成果であった。ネットでしか知らない方が、私のコンパイラを利用して色々な機器の開発に役立てていただき、バグレポートなども寄せていただき感謝している。

社内技術研修のテーマとして
開発途上でお世話になった技術研修所の同僚への恩義もあり、C言語中級という講座を開催することになった。開発したコンパイラを用いてコンパイラの生成するコードを理解して利用したコードでのデバッグを経験する。全てをワークステーションの上で動作環境を構築して実施した。シミュレータはFortranで書かれていたMicrotec社のシミュレータを利用した。ICEを使わない形でのデバッグ開発を全て出来るわけではなかったが、クロスコンパイラを利用したデバッグの雰囲気を学んでもらうことが出来た。コンパイラ自体は1passのフィルタのように振舞うので気軽に引数なしで起動した場合には、標準入力から投入されたCソースに対応したアセンブラコードを生成するのでコンパイラーの展開するコードの規模や意味などについて理解するためにも良いツールになったようだ。実際に、協力会社の中には気に入って早期からワークステーションを導入してUNIX版の頃から利用いただいてた会社もある。実は当時、社内で開発ツールを事業化するという話などもあったのであるが世の中のペースと折り合わず、その事業は立ち消えてしまった。組込み開発環境としてC言語を利用していこうという会社の方針がグループとしては立ち上がり、開発してきたコンパイラは社内のツールとして認定された。事業部の名前が冠されたこのコンパイラが会社の規格書の中に規定されたのは異質なことであった。

その後開発経験に基づいてBASICコンパイラの開発に着手したり、別の系統のマイコンのCコンパイラ開発などにも手を染めたりしたが、進んできた世の中の流れにとっては古臭い手法となってしまったようだ。ただし、真剣に開発までして対抗していくというスタンスがチップメーカーに伝わり競走することで半導体メーカーのコンパイラの精度も高まり性能的には問題もなくなっていった。機械語命令の機能を使い切れないコンパイラや譜面処理の不手際などについては、事例や対抗策を示すことで良い刺激になったようだ。コンパイラー開発の経験をベースにキャリアへの技術提案の中に盛り込むこともあった。特定の通信キャリアでは仕様が提示されて各社が技術提案をしていくのである。低消費電力の16ビットマイコンを高性能で利用していくためにRTOSの概念を盛り込んだコード生成を実現することで高性能な処理を実現させるという提案などを持ちかけた。こうした内容の真意が理解されたとは思えなかったが、技術屋として当時考えていた最善策を提案した。こうした提案において、彼らが要望している答えからはみ出た異質の提案は、決して受け入れられないというのが風土であるようだ。

人が全く使い物にならないとか、いろいろ文句のみをつけている技術があったりする。しかし、それに面と向かって進めていくことが技術屋としては、必要なことであると思う。無論、そうした中に自分の尺度として、その完成に向けた勘や、いくつかの技術的なアイデアがそれを支えてのことではあるが・・・。コンパイラが使いものにならないといわれていた時代に、実用化に取り組んできたのはある意味で、開発に苦しんでいる仲間達への愛も含まれていたのかも知れない。こうした開発の流れを経験させてもらう契機を与えてくれた上司に感謝したいし、その会社での技術者人生としても後輩に対して、そのような対応をしてきたと自負はしている。しかし、現在では、そうした会社を離れてしまったこともあり、ここに不十分ではあるが先達として考えてきたことの参考になれば書き綴る次第である。

Cコンパイラ開発顛末記 小窓次郎」への3件のフィードバック

  1. 湊さん、こんにちはブログなので投稿ポストするようにはしていませんが、コメントは承認の上で反映しています。更新が遅くてもうしわけありません。

  2. 湊さん、遅くなってもうしわけありません。ソースコードその他がサーバー移転でコンテンツ自体がアクセスできなくなっていましたね。控えのCDから再度構築しなおしましたので今はそのままリンクでセーブできると思います。LZHでアーカイブしてあります。

小窓次郎 へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。