[index > X68kの読み物や資料の部屋]

[前へ戻る] [次へ進む]

関数定義とイベント


外部関数の構造

外部関数ファイル(.FNC)は実行形式でありながらファイル内に関数定義を持つ、 多少特殊な実行形式ファイルです。

ファイルは、大雑把にいって下のようなブロックから成っています。

各領域は以下のように繋がっています。

  ┌─────────────┐
  │インフォメーションテーブル│
  └──┬────────┬─┘
        │                │
┌───┴────┐  ┌─┴──┐
│イベントハンドラ│  │関数定義│
└────────┘  └─┬──┘
                          │
                      ┌─┴──┐
                      │関数本体│
                      └────┘

このファイルでは関数本体を除く部分について解説します。 関数本体については次のファイルで説明します。

[戻る]


インフォメーションテーブル

インフォメーションテーブルは、ファイルの先頭に位置する64バイトの領域です。 ファイルに関する各情報が格納されているアドレスが並んでいます。

ファイル先頭から順に、以下のような情報が書き込まれています。 サイズはすべて1ロングワード(4バイト)です。

Ofs. 意味
---- ------------------------------------------------------------
00h  BASIC起動時・!命令による子プロセスからの復帰時に呼ぶアドレス
04h  run命令実行時に呼ぶアドレス
08h  end命令実行時に呼ぶアドレス
0Ch  system命令、exit()関数実行時(X-BASIC終了時)に呼ぶアドレス
10h  BREAKキー(CTRL+C)押下時に呼ぶアドレス
14h  CTRL+D押下(関数初期化リクエスト)時に呼ぶアドレス
18h  予備1。rts命令を指す
1Ch  予備2。rts命令を指す
20h  トークンテーブルを指す
24h  パラメータアドレステーブルを指す
28h  実行アドレステーブルを指す
2Ch  予備3。常に0
30h  予備3。常に0
34h  予備3。常に0
38h  予備3。常に0
3Ch  予備3。常に0

00h〜1Chには各種イベント発生時にサブルーチンコールしたいアドレスを指定します (X-BASICはこれらのイベントが発生したときにこのアドレスをサブルーチンコールします)。 普通はこれといって辻褄を合わせる必要がないので、すべてrts命令を指すようにします。

20h〜28hには関数定義のテーブルの先頭アドレスを指定します。 詳細は後述します

[戻る]


イベント

インタプリタは、特定のイベントが発生すると、 インフォメーションテーブルの00h〜1Chに定義されたアドレスをサブルーチンコールしてきます。

なお、stop命令実行時にイベントが発生するかどうかは不明です(調べていない)。

呼び出す条件については前記の表の通りです。注意すべき点は以下の通り(多分)。

なお、資料には引数や戻り値を持てるか、とか、レジスタを破壊していいか、 などといった情報は一切載っていません。 安全運転を心がけましょう(レジスタは破壊してもよさそうですが)。

[戻る]


関数定義

関数定義は、トークンテーブルで関数名を、パラメータアドレステーブルで引数・戻り値を、 実行アドレステーブルで各関数のアドレスを指定する形で行います。

1つの外部関数ファイルに複数の関数を含ませる場合は、 3つのテーブル内での定義順が同じでないといけません。

  1. 関数名の定義(トークンテーブルの記述方法)

    トークンテーブルでは、関数名の文字列を0で終え、最後の関数の次にはもう1つの0を加えます (例:.dc.b 'foo',0,'bar',0,0)。

  2. 引数・戻り値の定義(パラメータテーブルの記述方法)

    パラメータIDテーブルのアドレスを指定します(例:.dc.l foo_pi,bar_pi)。 1段階のクッションを挟むことで、 引数・戻り値の型が同じ複数の関数が1つの定義を共有することができます (例:foo_pi: .dc.w int_val,int_ret)。

    通常使用する値はFDEF.Hで以下のものが定義されています。なお、X-BASICではこれ以外のものは サポートされていないと考えたほうがいいでしょう。

    Par.ID FDEF.H     意味
    ------ ---------- -----------------------------------
    $0001  float_val  8バイト浮動小数点型実数
    $0002  int_val    4バイト符号付き整数
    $0004  char_val   1バイト符号なし整数
    $0008  str_val    文字列
    $0011  float_vp   float型変数のデータ部のポインタ
    $0012  int_vp     int型変数のデータ部のポインタ
    $0014  char_vp    char型変数のデータ部のポインタ
    $0018  str_vp     str型変数のデータ部のポインタ
    $003F  ary1       1次元配列(すべての型)
    $0032  ary1_i     1次元配列(int型)
    $0037  ary1_fic   1次元配列(float型、int型、char型)
    $0034  ary1_c     1次元配列(char型)
    $0054  ary2_c     2次元配列(char型)
    $0081  float_omt  省略可能な8バイト浮動小数点型実数
    $0082  int_omt    省略可能な4バイト符号付き整数
    $0084  char_omt   省略可能な1バイト符号なし整数
    $0088  str_omt    省略可能な文字列
    
    Par.ID FDEF.H     意味
    ------ ---------- -----------------------------------
    $8000  float_ret  8バイト浮動小数点型実数
    $8001  int_ret    4バイト符号付き整数
    $8003  str_ret    文字列
    $FFFF  void_ret   戻り値なし
    

    引数にはこれ以外の組み合わせもあり、以下の表の該当するビットを立てることで指定可能です。

    ビット15     0:引数  1:戻り値(以下の定義は無効。上の戻り値の表を参照)
    ビット14〜8  常に0
    ビット7      0:引数は省略不可  1:省略可
    ビット6〜5   00:配列でない  01:1次元配列  10:2次元配列  11:3次元以上の配列(?)
    ビット4      0:ポインタでない  1:ポインタ
    ビット3      0:str型でない  1:str型
    ビット2      0:char型でない  1:char型
    ビット1      0:int型でない  1:int型
    ビット0      0:float型でない  1:float型
    

    引数がない場合は、戻り値のみ定義します。戻り値がない場合は、void_retを定義します。

  3. 実行アドレスの定義(実行アドレステーブルの記述方法)

    各関数のアドレスを並べるだけです(.dc.l _foo,_bar)。

[戻る]


インフォメーションテーブルと関数定義の関係図。

┌インフォメーションテーブル┐
│      .dc.l   x_init      │
│      :      :          │
│      .dc.l   token ──────┬─トークンテーブル──┐
│      .dc.l   parameter ───┐│token: .dc.b   'foo',0│
│      .dc.l   exec─────┐││       .dc.b   'bar',0│
│      .dcb.l  5,0         ││││       .dc.b   0      │
└─────────────┘││└───────────┘
┌実行アドレステーブル─┬──┘├──パラメータテーブル───┐
│exec: .dc.l   foo_exec│      │parameter: .dc.l   foo_param──┐
│      .dc.l   bar_exec│      │           .dc.l   bar_param─┐│
└───────────┘      └──────────────┘││
                    ┌─────────────────────┘│
┌─────────┴─パラメータIDテーブル───────────┤
│bar_param: .dc.w   int_val│      │foo_param: .dc.w   int_val  │
│           .dc.w   int_ret│      │           .dc.w   char_omt │
└─────────────┘      │           .dc.w   str_val  │
                                    │           .dc.w   void_ret │
                                    └──────────────┘

この例では、void foo(int,char(省略可),str)とint bar(int)を定義しています。

[戻る]


[前へ戻る] [次へ進む]

[index > X68kの読み物や資料の部屋]

Written by mor.

最終更新は2001年10月31日(水)です。