みなさん、再びプロのプログラマに復帰したおいちゃんです。さてわたくしは、杉之原氏から「あんなもん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活用マニュアルを参照してください。
おしまひ
|