C言語でスーパーバイザCALL
 みなさん、再びプロのプログラマに復帰したおいちゃんです。さてわたくしは、杉之原氏から「あんなもんCじゃないじゃ」と迫害を受けながらもBDSCを愛用しております。他人の作ったモジュールの御利益を賜わりたいと秘かにもくろむわたくしは、ちょっとだけ便利なモジュールを発表することにしました。(う~ん、このもったいのつけかた?)

 P-CP/Mではうれしいことに拡張BIOSコールとしてエントリ29,30に、それぞれSVCとFNCが割り付けてあります。(SVCは2500独自のBIOSと考えてください。FNCは浮動小数点演算のモジュールパッケージです。)ところが、C言語ではマシン語をCALLするときには

call(adr, a, h, b, d);     /* 実行アドレス、レジスタ値を渡してHLレジスタの値が関数値として帰る */

calla(adr, a, h, b, d);    /* 実行アドレス、レジスタ値を渡してAレジスタの値が関数値として帰る  */

でありまして、CYフラグとかBCレジスタに値が入るとかいったルーチンはこのままでは使えません。例えばキーボードからの1行入力に漢字入力を使いたい場合、当然C言語のscanf関数は使えません。「それではSVCを使おう……」となるのですが、残念ながらSVCのGETL(RST 18H:DEFB 0CH)は、入力された文字列のアドレスがDEレジスタに入り、また、SHIFT+BREAK判定がCYに入ります。このように、出力がA,HLレジスタ以外のものがあり、これらのSVCとC言語の間にインタフェースをとる関数が必要となります。この関数はC言語のみでは作れないので、アセンブラを使用しました。

〈〈使用方法〉〉

 あらかじめレジスタに対応する変数を確保します。CYフラグ用にも確保することに注目してください。

svcref(svcnumber, ACC変数のアドレス, BC, DE, HL, CY)

 ACC以降のレジスタは、すべて変数のアドレスを渡します。ここでピィーンときたあなたはかしこひ。各レジスタの結果値はその変数に返ります。

 SVCREFはザイログ表記で書かれていますが、これをBDSCのリンク形式に変換するには特別なツールが必要です。(恐怖のインテル表記ならばそのままBDSCのCASMが使用できますが、わたくしはZCASMをいちまんえんも出して買ったのでした。)

 応用例としまして、svcrefを使ったlinput関数を載せておきます。$E100以降をCALLしているのは共有領域からバッファへ転送するためです。詳しくはP-CP/M活用マニュアルを参照してください。

 おしまひ

C言語でスーパーバイザCALL 全リスト

擬人的システムイメージ?!

※1987年の記事