ドライバの記述例(MS−DOS)


1

Config.sysにドライバ定義の行を追加する

"DEVICE=x:\PATH\APIC21DV.EXE"をConfig.sysに加える
X: APIC21DV.EXEが格納されているドライブを示します
\PATH\ APIC21DV.EXEが格納されているパス(フォルダの位置)を示します

2

ドライバをオープンしサービスルーチンのアドレスを取得

APIC21DV.EXEはIOCTL(I/Oコントロール)デバイスの一つとして、ドライバが
作成されているためアプリケーションプログラムは、ドライバをまず、オープン
しなければなりません。

実際はaPCI用のaPCIドライバをC言語の「open()」関数を使用してオープンします。
前述のように、デバイスとしてオープンするため、ファイル名ではなくデバイス名
("APCIINF$")でオープンします。

以下に、APCICTRL.Cにある、ドライバをオープンしながらドライバサービスルーチンの
エントリアドレスの取得プログラムを示します。

       

/* ============================================================================
//      説明    aPCIドライバのサービスルーチンアドレスを取得する。
//      戻り値  0               aPCIドライバのサービスルーチンのアドレスを取得できた
//              -1              取得できなかった
//      備考    サービスルーチンのアドレスはグローバル変数 glpDrvFunc にセットされる
//========================================================================== */
short ApciGetDriverFunc( void )
{
int                handle;                               /* ファイルハンドル */
short             result;                                /* I/Oコントロールの結果と本関数の戻り値 */
void far        *ptr;

        if ( -1 != ( handle = open( "APCIINF$", O_CREAT | O_RDWR | O_BINARY, S_IWRITE | S_IREAD ) ) ) {
                ptr = ( void far * )&glpDrvFunc;      /* aPCIドライバのエントリアドレスを取得 */
                result = ioctrlRead( handle, 4, ( uchar far * )ptr );
                close( handle );
        }
        else
                     result = -1;                      /* aPCIドライバが存在しない */
        return result;
}
        

3

ボードアドレスを得る

”2”で取得したドライバのサービスルーチンを呼び出し、ボードのI/Oアドレスを取得します。

デバイス設定情報の条件等の設定は下記の構造体に設定します。

typedef struct _APCI_FIND_MES {
    ushort  wIndex;              /* インデックス */
    ushort  wDeviceID;          /* デバイスID */
} APCI_FIND_MES, far *LPAPCI_FIND_MES;

デバイスの情報は下記の構造体に設定されます。

typedef struct _APCI_FIND_RES {
    ushort  wIndex;              /* 検索インデックス */
    ushort  wVendorID;         /* ベンダID */
    ushort  wDeviceID;          /* デバイスID */
    ushort  wNumMemWindows;     /* メモリウィンドウ数 */
    ulong   dMemBase;          /* メモリウィンドウベースアドレス */
    ulong   dMemLength;        /* メモリウィンドウ長 */
    ushort  wNumIOPort;        /* I/Oウィンドウ数 */
    ushort  wIOPortBase;       /* I/Oウィンドウベースアドレス */
    ushort  wIOPortLength;     /* I/Oウィンドウ長 */
    ushort  wNumIRQs;           /* IRQ数 */
    uchar   bIRQRegisters;      /* 使用IRQ */
} APCI_FIND_RES, far *LPAPCI_FIND_RES;

以上のように構造体を定め、2で取得したサービスルーチンを呼び出します。

ushort getAdapterInfo( ushort wDeviceID, ushort wNum )
{
APCI_GET_ADP_MES    msg;
APCI_GET_ADP_RES     inf;
APCI_CMD_PACKET     pkt;

ushort                      pkt_seg,
                              pkt_ofs,
                              res;

void far   *ptr;

    msg.wDeviceID  = wDeviceID;   /* デバイスID */
    msg.wIndex     = wNum;          /* 検索インデックス# */
    pkt.lpMessage  = &msg;
    pkt.lpResponse = &inf;            /* デバイス情報を設定する構造体のポインタ */
    ptr = (void far *)&pkt;
    pkt_seg = FP_SEG( ptr );         /* セグメントアドレス取得 */
    pkt_ofs = FP_OFF( ptr );          /* オフセットアドレス取得 */
    asm {

        push    es
        mov     ax,pkt_seg
        mov     es,ax                    /* es <- セグメントアドレス */
        mov     di,pkt_ofs               /* di <- オフセットアドレス */
        mov     ax, APCIC_GET_ADAPTER_PORT  /* ax <- コマンド */
        call    dword ptr glpDrvFunc  /* サービスルーチンをコールする */
        pop     es
        mov     res,ax
    }
    return res;                           /* 実行結果を返す */
}

4

留意事項

  • aPCIドライバはMS-DOS Ver.5.0以降での動作が確認されています。
  • WindowsのMS-DOSプロンプト上での動作は保証いたしかねます。