戻る

13. 拡張コマンド 'EXCOM'


EXCOMとは 'NET-COCK' 本来の機能ではない機能です.
元々はオリジナルである 'NET-COCK ver 3.79' 以降から標準装備らしいのですが,沙希さん system では独自に実現しています.
EXCOM用のプログラムを作成するためにはいくつかの手順があります.
以下に順に説明していきます.


13.1 EXCOMの仕様


プログラム形式 プログラムは完全なリロケータブルでなければならないため *.r ファイルのみとする.
ヘッダ ヘッダはプログラム先頭部分に 32bytes を確保する.

16byte はプログラム領域である.
続く 4bytes に 'NET-COCK' がプログラムであると判断するため,'COCK' の文字列を記述する.
さらに 4bytes が NUL 文字で埋められ,2bytes の使用モード,2bytes のプログラムにとってユニークな識別コード,4bytes の NUL 文字と続く.
先頭部分をダンプすると次のようになる.



$0000:
[プログラム領域]
$0010:
.dc.b 'COCK',$00,$00,$00,$00
$0018:
.dc.w __MODE,__CODE,$0000,$0000
$0020:
[NET-COCK から呼ばれる領域]


13.2 プログラム領域


作成されるプログラムはリロケータブルであるので,通常に実行される場合には,まずここがスタートアドレスとなる.
これらの外部起動プログラムは 'NET-COCK' 上で実行されなければ意味をなさないものであるため,command.x 上で実行した場合にはプログラム自身が注意を促さなければならない.
このためのタイトルやヘルプの出力をこの部分で行なわせる.
実際には 'NET-COCK' から実行された場合はこの部分を無視するため,EXCOMとして実行する限りにおいてはここに何が格納されてあってもかまわない.


13.3 使用モード


'NET-COCK' が起動時か,もしくは 'EXSET' によってプログラムを確保した場合,そのコマンドがどこでどのように扱われるのかを,プログラムの方から教えるためのビット列である.
各ビットごとに意味を持ち使用するモードに合わせてそれらをセットしたものがここに入る.

対応するビットは以下の通り.

bit00:
拡張コマンドとして実行
bit01:
起動時に実行
bit02:
終了時に実行
bit03:
ログインメッセージ前に実行
bit04:
ログインメッセージ後に実行
bit05:
ログオフメッセージ前に実行
bit06:
ログオフメッセージ後に実行
bit14:
マクロ内で実行
bit15:
データ

例えば 'マクロ内と拡張コマンドとして起動する' 場合には使用モードは $4001 となる.


13.4 識別コード


プログラムやデータに個別のコードを設け,'NET-COCK' で確保されたプログラムやデータを識別するためのコードである.
識別コードは '(制作者番号*256+制作番号)' とする.
データの場合はこれに 128 を加算する.
このコードには 0 を入れないよう注意してすること.


13.5 'NET-COCK' 内の情報の取得ルーチンの利用


'NET-COCK' のサービスを利用するためには GRAM 上に展開された関数を参照する.
これらの詳細は function.man に記述されているのでそちらを参照すること.

注意点として外部起動プログラムを起動時に実行する以外は,レジスタ a5 にシステムワークへのポインタ,レジスタ a6 に回線ごとのワークポインタが入っている.
このため GRAM を参照しなくともこれらのポインタからある程度の情報を得ることはできる.
これは work.man にまとめてあるのでそちらを参照すること.

通常,GRAM のアドレスはレジスタ a4 に代入して使用するのが望ましい.
各サービスは,そのほとんどにおいて回線ごとのワークポインタを a6 レジスタを通じて取得するために a6 レジスタを破壊してはいけない.


13.6 'NET-COCK' への復帰


外部起動プログラムの 'NET-COCK' から見た扱いは通常のサブルーチンと同じものであるため,外部起動プログラムから 'NET-COCK' へと復帰するときにはただ単にリターンすればよいだけである.
特別な動作はなにも必要ない.


13.7 インクルードファイル cock.mac から見たEXCOM


外部起動プログラムを作成する際に手助けとなるのが cock.mac である.
これを使用する際の注意点を以下に述べる.


13.7.1 初期化に関する手続き


初期化はマクロ 'INIT' で行なう.
テキストセクションが始まってすぐにこれを行なわなくてはならない.
このマクロではヘッダ領域の確保,レジスタ a4 の初期化などを行なっている.
このマクロに渡すためのシンボルは以下のものがある.

__MODE
使用モード
__CODE
識別コード
__TITLE
タイトルメッセージへのポインタ
__HELP
ヘルプメッセージへのポインタ

cock.mac でのヘッダ内に確保されているプログラム領域では,タイトルとヘルプの表示,プログラムの終了を行なっている.


13.7.2 'NET-COCK' のサービスの利用


外部起動プログラムの中からサービスを利用するためには,GRAM に格納されている各ポインタを参照する.
'NET-COCK' 本体ルーチンをコールするために用意されたマクロが 'COCK' である.
例として,文字列を出力する場合には

lea.lmes(pc),a0* 文字列が格納されているポインタ
COCK_puts* サービスのコール

などとして使用する.また,ワークを参照したい場合は

movea.l_EXCOMDAT(a4),a0

と行なうことにより,用意されたワークを取得することができる.


13.8 'NET-COCK' から見たEXCOM


ここでは 'NET-COCK' にとってのEXCOMの扱いについて説明する.


13.8.1 登録方法


各外部起動プログラムの登録は 'EXSET' を用いて行なう.
'NET-COCK' から確保できるファイルの種類は外部起動プログラム用のファイル,これらが使用するデータ用のファイルの 2種類である.
以下にそれぞれの属性について,確保のプロセスを説明する.


13.8.2 外部起動プログラム


EXCOM番号を入力した後,'P' を入力するとそれ以後確保するべきバッファは外部起動プログラムとして扱う.
設定するものはそのコマンドの使用許諾レベル,コマンド名,コマンドの説明,ファイル名である.

その外部起動プログラムが外部コマンドとして登録する必要がない場合,コマンド名とその説明を登録する必要はないが,なるべくならばそのプログラムの説明を記述するべきである.
これは後々確認を行なうために必要となる.

この時に入力された各パラメータは GRAM 上に指定されている特定のアドレスから $40byte ごとに格納される.
これはEXCOMデータとして保存される領域である.

すべての入力に異常がなく,指定されたファイルが存在しているならば 'NET-COCK' はそのファイルにアクセスし,'NET-COCK' の外部起動プログラムであるかどうかを調べる.

これはプログラム中に埋め込まれているIDを調べることにより実現している.
所定の位置にIDがなかった場合は,これを外部起動プログラムではないと認識し,処理はここで中断する.

IDの確認が終了した後,ファイルサイズを調べ,メモリを確保する.
確保したメモリの先頭アドレスはファンクションコール用データテーブルへ格納される.
また,使用モードと識別コードの取得を行ない,これをEXCOMデータの格納されている領域へと渡す.

さらにこの後,拡張コマンドのコマンドテーブルの成形を行なう.
これはプログラムの解放を行なったときにも行なうプロセスである.
最後に,確保されたプログラムが起動時に実行されるという属性を持っているならば,その外部起動プログラムを実行する.
これはデータ作成,書き換え等の処理を行なう場合に対応させるためであり,各プログラムはこの点を踏まえて作成されなければならない.


13.8.3 データテーブル


EXCOM番号を入力した後,'D' を入力するとそれ以後確保するべきバッファは外部起動プログラムとして扱う.
設定すべきものは識別コード,データの説明,ファイル名である.
これらもプログラム同様EXCOMデータの領域へと保存される.

すべての入力に異常がなく,ファイルが存在しているならばこれを読み込み,確保領域の先頭アドレスはやはり同様にファンクションコール用のデータテーブルへと格納される.

データとしての使用モードは bit15 をセットしたものを使用する.
これは 'D' を入力した時点で自動的に行なわれる.
識別コードは外部起動プログラムがどのデータであるかを確認するためのものであり,これはそのデータを使用するプログラムで参照するコードと一致したものでなければならない.


13.8.4 確保領域の解放


EXCOM番号を入力した後,'F' を入力するとその領域は解放され,EXCOMデータの使用モード,識別コードが格納されている部分をクリアする.
それ以外のパラメータは保存されたままであるが,プログラムやデータが呼び出されることはない.


13.8.5 外部起動プログラムの起動方法


外部起動プログラムの起動方法は

  1. 拡張コマンドとして呼び出す
  2. 所定の動作中に呼び出す
  3. マクロ中から呼び出す

の3種類がある.
これらは外部起動コマンドの使用モードで設定したものがそのまま使用され,'NET-COCK' の判断により呼び出される.
プログラムが呼び出されたならば 'NET-COCK' は現在のすべてのレジスタをメモリ上に格納し,識別コードと呼び出し方法を回線に対応するバッファに保存する.
その後にファンクションコール用のデータテーブルで対応する確保アドレスを参照し,その $20byte 目をサブルーチンとしてコールする.


13.8.6 汎用バッファ


外部起動プログラムは,同じプログラムが異なる回線から同時に呼び出されることを想定して作成しなければならない.
'NET-COCK' では各回線ごとに対応する 4Kbytes の汎用バッファを確保している.
これら対応する回線についての汎用バッファへのポインタは 'NET-COCK' のサービスコールによって簡単に取得することができるので,あまり気にする必要はない.


13.8.7 ファンクションコールテーブルの格納方式


外部起動プログラムから 'NET-COCK' のサービスを利用するためにはここを参照する.
この領域ではポインタの格納,ジャンプ命令とポインタの格納の 2種類の格納方式を用いている.
このため,'NET-COCK' 内のサブルーチンをコールする場合には直接このテーブルをコールすればよい.


13.8.8 'NET-COCK' 起動時の初期化


'NET-COCK' がEXCOMのために行なう初期化は以下の通りである.

  1. EXCOMデータの読み込み
  2. メモリの確保,プログラム,データの読み込み
  3. コマンドテーブルの成形
  4. 起動時実行プログラムの実行

プログラム,データ領域の確保の基準はEXCOMデータ内の各使用モードが 0 でない場合においてのみ行なわれる.


13.9 どのようなことができるのか


プログラム次第でさまざまなことができるが,以下に特殊な具体例を示す.

対戦型ゲームの作成 他の回線で現在使用中の拡張コマンドを参照することができるため,両回線で同じコマンドを実行することにより,プログラム次第では対戦ゲームを行なうことが可能である.
'NET-COCK' 内部の書き換え マクロの処理アドレステーブルやコマンドの処理アドレステーブルへのポインタを取得することが可能なため,そこから目的の処理アドレスを探し出しトラップすることによって,処理ルーチンを外部コマンドに依存することが可能である.
しかし,これを行なうためには,'NET-COCK' の各処理について熟知していなければならないため,改造者以外がこれを作成するのは危険であろう.
外線発信 別の回線を使うことによって外線発信も可能である.
これを用いれば同様な機能を持つホストとのリンクも不可能ではない.


[戻る]