---------------------------------------------------------------- AUX driver with IRCS "IAUX" version 0.50 API一覧 Copyright (c) G-HAL 1997 / 01 - 1997 / 06 ---------------------------------------------------------------- ★☆ 規格 ☆★ IAUX98.doc のソフトウェア規格/物理層規格を見て下さい。 重要な事はそちらに書いてあります。タブン ★☆ 総覧 ☆★ IAUX では、以下の5種類のAPIをサポートしています。 ・デバイスドライバ ・Read I/O CTRL ・Direct PASCAL call ・Direct call ・Direct C call 基本的な流れとして、 1.デバイスドライバとしてのAPIを用い、組み込まれている事を確認。 2.Read-IOCTRL を用い、本当に IAUX であるかを確認。 3.Direct PASCAL call の呼び出しアドレスを取得。 4.Direct PASCAL call を用い、IAUX を使用。 となっています。 しかしながら、簡易的に IAUX を使用する場合は、デバイスドライバとしての APIだけを用いて、IAUX を使用する事が可能になっています。 え、高級言語から使用する方法ですか? 説明が長くなって面倒なので、どこかのネットで聞いて下さい。(^^; 基本的に MCD ver0.9 互換にして有ります。(Direct PASCAL call 推奨) ★☆ デバイスドライバ ☆★ 凡例 ●オープン(13:DEVICE OPEN) AH=3Dh ↑ ↑ ↑ ↑int 21h でのファンクションコード ↑ ↑ ↑ ↑ ↑ 機能名称 ま、大した意味は有りません。 ↑ ↑ ↑ 機能番号 MS-DOS 内部で使用されるものなので、 ↑ 気にする必要は有りません。 ↑ 機能内容 気にして下さい。(^^; 基本的には通常のファイルと全く同様に、int 21h とファイルハンドルを 用いて、使用します。 デバイスドライバとしてのAPIだけを用いて IAUX を使用する場合は、 「初期化(0:INIT)」「オープン(13:DEVICE OPEN)」「クローズ(14:DEVICE CLOSE)」 「読込(4:INPUT)」「書込(8:OUTPUT)」を主に使用します。 Direct PASCAL call を使用する場合は「初期化(0:INIT)」 「オープン(13:DEVICE OPEN)」「クローズ(14:DEVICE CLOSE)」 「リードI/Oコントロール(3:READ I/O CTRL)」を使用します。 ●初期化(0:INIT) CONFIG.sys 内での指定や adddrv,adddev などで組み込んだ時に 自動的に呼ばれます。アプリケーション側で気にする必要は有りません。 初期化に成功した場合、 > Installed successfully. と表示されます。その時同時に、例の copyright表示も表示されます。 また、初期化時に > IRCS was not found... と表示される事が有りますが、これはパソコン側の初期化には 成功したものの、IRCSの接続が確認出来ない事を意味します。 しかしながら、メッセージが表示される以外、違いは有りません。 初期化終了後は、負荷を軽くする為に、IAUX の処理を凍結して しまいますので、後述の(13:DEVICE OPEN)にて解凍する必要があります。 ●オープン(13:DEVICE OPEN) AH=3Dh IRCSの初期化,検出を行い、負荷を軽くする為に凍結していた IAUX の処理を解凍し、IAUX を使用出来るようにします。 使用前に必ず行う必要があります。 IRCSが検出できない場合でも、エラーを返しません。 (SHARE.exe, COMMAND.com のバグ対策)気をつけて下さい。 なお、IRCSではなくモデムがつながった状態で open すると IRCSとモデムとの判別に4秒程度かかるので気をつけて下さい。 また、既に初期化,検出,解凍を行っていた場合は、 何もしません。 ●クローズ(14:DEVICE CLOSE) AH=3Eh 負荷を軽くする為に IAUX の処理を凍結します。 使用が終わった後、出来るだけ行った方が良いでしょう。 なお、open した回数よりも close した回数が少ない場合、 SHARE.exe が暴走します(SHARE.exe の仕様らしい)。 ●読込(4:INPUT) AH=3Fh 送られてきたデータを読み込みます。 送られていなければ、当然読めません。 IAUX は物理層と一部のリンク層しか搭載していないので、 送られたパケットが必ず届くとは限りません。 ただし、データ化けが無い事は保証されます。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 ●書込(8:WRITE) AH=40h ●確認付き書込(9:WRITE with VERIFY) AH=40h ●終了確認書込(16:WRITE until BUSY) データを送信します。KISS 処理を行ってある必要があります。 IAUX は物理層と一部のリンク層しか搭載していないので、 送ったパケットが必ず届くとは限りません。 ただし、データ化けが無い事は保証されます。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 また、送信していないにもかかわらず、送信した事にしてしまいます。 送信バッファが用意されていない場合は、DEVICE WRITE PROTECTED を 返します。 ●非破壊読込(5:NON-DESTRUCTIVE INPUT NO WAIT) データを読み込みますが、バッファから消しません。 ふたたび、この機能や「読込(4:INPUT)」をもちいて、 同じデータを読めます。 MS-DOS がサポートしていないらしいので、通常の int 21h では 使用できないようです。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 ●リードI/Oコントロール(3:R_IOCTL) AX=4402h IAUX を使用するために必要な情報を得ます。 次の「Read I/O CTRL」の章で説明します。 ●読込状態(6:INPUT STATUS) AX=4406h データを受信したか否かの状態を取得します。 相手に確認する訳ではなく、バッファの状態を確認するだけです。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 ●書込状態(10:OUTPUT STATUS) AX=4407h データを送信したか否かの状態を取得します。 相手に確認する訳ではなく、バッファの状態を確認するだけです。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 ●受信初期化(7:INPUT FLUSH) これまでに受信したデータを破棄します。 MS-DOS がサポートしていないらしいので、通常の int 21h では 使用できないようです。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 ●送信初期化(11:WRITE FLUSH) これまでに送信したデータを破棄します。 MS-DOS がサポートしていないらしいので、通常の int 21h では 使用できないようです。 IRCSが検出できない場合は、DEVICE NOT READY を返します。 ●メディア交換確認(1:MEDIA CHECK) AX=4408h ●BPB作成(2:BUILD BPB) ●メディア交換可能性確認(15:REMOVABLE MEDIA) これらの機能は使用出来ません。 ●アウトプットI/Oコントロール(12:W_IOCTL) AX=4403h この機能には対応していません。 ★☆ Read I/O CTRL ☆★ ファンクションコールの AX=4402h を用いて IAUX の情報を得ます。 サポートしている機能が呼ばれた場合は DEVICE DONE が返されますが、 サポートしていない機能が呼ばれた場合、DEVICE NO COMMAND が返されます。 呼び出し方法 引数 AX = 4402h BX = IAUX のファイルハンドル 「オープン(13:DEVICE OPEN)」にてMS-DOSから割り当てられたもの DS:DX = IOCTLパケットの先頭アドレス CX = IOCTLパケットの大きさ 返値 set CY エラー non CY 正常終了 AX = IAUX から得たIOCTLパケットの大きさ IOCTLパケットには次のような構造体を使用します。 +-------------------------------+ ↑ | 機能番号 (1 word) | | パケット長(CX) +-------------------------------+ | | 各ファンクションの返値 | | | (大きさは各機能毎に異なる) | | | : | | +-------------------------------+ ↓ 凡例 ●ID取得(9:GETID) mcd_getid_t ↑ ↑ ↑ ↑構造体名 IOCTLパケット構造体の ↑ ↑ ↑ MCDIF.inc 内での名称 ↑ ↑ ↑ ↑ ↑ 機能名称 MCDIF.inc 内で定義されて……無いな。 ↑ ↑ ↑ 機能番号 上記 IOCTLパケットの機能番号にて ↑ 指定して下さい。 ↑ 機能内容 内容が無いよう。 IOCTLパケットの構造の説明 +---------------------------------------+ |W 機能番号 = 0009h |パケット長(CX=0008h) +---------------------------------------+ |B minver: マイナーバージョン | |B majver: メジャーバージョン | |D id_str: ID文字列格納域へのポインタ | +---------------------------------------+ ↑ ↑ ↑返値の内容 ↑パケット長 ↑ ↑ 引数での CX,返値での AX が ↑ ↑ この大きさと違っていた場合、 ↑ ↑ エラーです。 ↑ ↑ ↑ 項目名 MCDIF.inc 内での IOCTLパケット ↑ 構造体での項目名 ↑ 項目サイズ B:バイト W:ワード(2バイト) D:ダブルワード(4バイト) その他:見たまま。 ●ID取得(9:GETID) mcd_getid_t +---------------------------------------+ |W 機能番号 = 0009h |パケット長(CX=0008h) +---------------------------------------+ |B minver マイナーバージョン | |B majver メジャーバージョン | |D id_str ID文字列格納域へのポインタ | +---------------------------------------+ char _far *id_str; 互換性のある MCD のバージョン、および、ID文字列を取得します。 Direct PASCAL/ASSEMBLY/C call を使用する前に、必ずこの機能にて、 バージョン、ID文字列を確認して下さい。 なお、id_str:dword はポインタですので、お間違いなく……。 この機能を呼び出す時には、IOCTLパケットの id_str:dword を 00000000h に初期化してから呼び出して下さい。 0 でなかった場合は、id_str:dword で指定したアドレスへ、 ID文字列を複写します。 マイナーバージョン:09h メジャーバージョン:00h ID文字列:"MCD",0 で有った場合は、正常に IAUX を使用出来ます。 ただし、本物の MCD でもまったく同様の返値となります。 なお、id_str:dword を 00000000h にして呼び出された時の、 ID文字列の 1byte 前には、ID文字列数 03h が格納されています。 IAUX 独自の隠し返値として id_str:dword を 00000000h にして 呼び出された場合は、 ID文字列:"MCD",0,"IAUX",0,0 へのポインタを返しています。 ●Direct call エントリ取得(20:GETENT) mcd_entry_t +---------------------------------------+ |W 機能番号 = 0014h |パケット長(CX=0006h) +---------------------------------------+ |D offs エントリアドレス | +---------------------------------------+ Direct call のエントリアドレスを取得します。 内部で Direct PASCALL call に変換しています。 また、KTX で十分に動く程度にしかデバッグしていません。 Direct PASCAL call を利用して下さい。 ●Direct C call エントリ取得(21:GETCENT) mcd_c_entry_t +---------------------------------------+ |W 機能番号 = 0015h |パケット長(CX=000Ah) +---------------------------------------+ |D offs テーブルの先頭アドレス | |W cseg コードセグメントの値 | |W tblnum テーブルの項目数 | +---------------------------------------+ Direct C call のエントリテーブルアドレスを取得します。 Direct C call の各関数は全て同じコードセグメント cseg に あり、オフセットのテーブルは offs で指定されるアドレスに有ります。 内部で Direct PASCALL call に変換しています。 また、ほとんどデバッグしていません。 Direct PASCAL call を利用して下さい。 ●Direct PASCAL call エントリ取得(22:GETPENT) mcd_p_entry_t +---------------------------------------+ |W 機能番号 = 0016h |パケット長(CX=0010h) +---------------------------------------+ |D offs テーブルの先頭アドレス | |W cseg コードセグメントの値 | |W tblnum テーブルの項目数 | |6BYTE reserved_p_entry リザーブ | +---------------------------------------+ void MK_FP(cseg, (_far *offs)[tblnum])(...); デ、イイノカナ Direct PASCAL call のエントリテーブルアドレスを取得します。 Direct PASCAL call の各関数は全て同じコードセグメント cseg に あり、オフセットのテーブルは offs で指定されるアドレスに有ります。 詳細は DPCALL1.asm を見て下さい。 各関数の利用法は、次の「Direct PASCAL call」の章で説明します。 ●情報取得(23:MCDINFO) mcd_mcdinfo_t +---------------------------------------+ |W 機能番号 = 0016h |パケット長(CX=0010h) +---------------------------------------+ |D inmcd_addr inMCDフラグのアドレス | |W tint_times ダミー | |D timer_addr ダミーポインタ | |D iocnt_addr 送受信カウンタのアドレス | |16BYTE reserved_mcdinfo リザーブ | +---------------------------------------+ byte volatile _far *inmcd_addr; dword volatile (_far *)iocnt_addr[2]; inMCDフラグ,送受信カウンタのアドレスを取得します。 MCDではタイマーカウンタのアドレスも取得出来ますが、 IAUX ではタイマーは対応していないので、ダミーとなります。 inMCDフラグの大きさは 1byte であり、この値が0の時にしか、 IAUX を呼び出してはいけません。0以外の時に呼び出した場合、 暴走する恐れが有ります。通常のアプリケーションから呼び出す場合は 検査する必要は有りませんが、割込により動作するアプリケーションの 場合は検査する必要があります。 送受信カウンタのアドレスが指し示す先には、1dword の大きさの 受信カウンタが有り、その直後に 1dword の大きさの送信カウンタが 有ります。送受信バイト数をカウントアップしています。 アプリケーションで自由に参照,変更して構いません。 ●タイマー割当取得(24:GETTIMER) mcd_timer_t ●タイマー割当設定(25:SETTIMER) mcd_timer_t タイマーはサポートしていません。 したがって、この機能は使用出来ません。エラーを返します。 ●機種固有情報取得(30:MACHINEIO) mcd_machineio_t 詳細不明の為、サポートしていません。 ★☆ Direct PASCAL call ☆★ IAUX に内蔵された機能を直接呼び出すAPIです。 global PASCAL xxx:far な関数と全く同様に扱う事が出来ます。 一部の関数で、一時的に割込禁止になる事が有りますが、 全ての関数で、割込禁止状態で呼ばれたならば、割込許可状態に ならない事が保証されます。 また、SI,DI,DS,BP,ディレクションフラグは保存されます。 (Cにて、保存が要求されるレジスタ全て) 引数の数を間違えると SP が狂います(当たり前)。 ●extern void (_far _pascal *MCD_getid)(mcd_getid_t _far *buf); Read I/O CTRL APIの「ID取得(9:GETID)」の実体です。 Direct PASCAL call で使う必要はないでしょう。 ●extern void (_far _pascal *MCD_getlinepara)(mcd_lprm_t _far *param); ●extern void (_far _pascal *MCD_setlinepara)(mcd_lprm_t _far *param); 通信パラメータを取得/設定します。 mcd_lprm_t.baud 以外はダミーです。 mcd_lprm_t.baud は 1word なので、0〜65535 までしか 指定出来ません。それ以上の時は、getspeed/setspeed を使って下さい。 setlinepara にて mcd_lprm_t.baud が 0 の時は、65536以上であるとし、 何もしません。また、getlinepara にて、mcd_lprm_t.baud が 0 の時は、 65536以上である事を意味します。 ●extern unsigned short (_far _pascal *MCD_getlinestat)(void); ●extern void (_far _pascal *MCD_setlinestat)(unsigned short stat); ●extern unsigned short (_far _pascal *MCD_linectrl)(unsigned short ctrl); IRCS状態/エラー発生状況を取得/設定します。 返値/引数は以下のビットフィールドになっています。 MSB LSB +---------------+---------------+---------------+---------------+ | *|CTS| *| ×|RXF|OER|FER|PER|DSR| *|RTS| ×| ×| ×|DTR| ×| +---------------+---------------+---------------+---------------+ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 この中で、×は未定義ビット、*はダミービットです。 これらの元々の語源は次のとおりです。 CTS Clear To Send RXF RX buffer Full OER Overrun ERror FER Framing ERror PER Parity ERror DSR Data Set Ready RTS Request To Send DTR Data Terminal Ready 各状況に応じ、次のようなビットが立ちます。 物理層での異常構造 FER 物理層での長さ超過 OER | RXF 受信バッファ超過 RXF データ長が octet 単位でない OER CRCにてエラー検出された PER また、CTS,DSR,RTS,DTR は本来の意味と異なり、IRCSの 初期化,検出に成功した場合に1になり、失敗した場合に0になります。 setlinepara にて、RTS,DTR のどちらか,もしくは両方を1に 設定しようとした時に、IRCSの初期化,検出に失敗していた場合、 再度IRCSの初期化,検出を行います。0に設定しようとした時、 およびすでに初期化,検出に成功していた時は、setlinepara は何も 行いません。 linectrl では RTS,DTR ビットのみ有効で、1のビットを BIT0 の状態に します。BIT0 が1で、かつ RTS,DTR のどちらか,両方が1で、さらに IRCSの初期化,検出に失敗していた場合、setlinepara 同様、 IRCSの初期化,検出を行います。 ●extern void (_far _pascal *MCD_getbufstat)(mcd_bufstat_t _far *stat); ●extern void (_far _pascal *MCD_setbufstat)(unsigned short stat); 送受信バッファの状態取得/設定を行います。 getbufstat では、mcd_bufstat_t.txnum, mcd_bufstat_t.rxnum しか 意味を持ちません。それぞれ、送信バッファ内文字数, 受信バッファ内文字数,です。 setbufstat では、BIT0,BIT1 しか意味を持ちません。 BIT0:送信バッファ初期化 BIT1:受信バッファ初期化 ●extern unsigned short (_far _pascal *MCD_blockread)( unsigned char _far *buf, unsigned short size); ●extern unsigned short (_far _pascal *MCD_blockwrite)( unsigned char _far *buf, unsigned short size); ブロック読込/書込を行います。 far *buf にて指定されたデータ列の、size で指定したバイト(オクテット)数だけ 送信/受信を行います。実際には送受信バッファに転送されるだけです。 バッファからの送受信は割込によりタイミングを見計らい自動で行われます。 受信したバイト数が size より小さい,送信バッファの残りバイト数が size より小さい,場合は、可能な大きさだけ行います。 返値は、実際に送受信されたバイト数です。 なお、IRCSの初期化,検出に失敗していた時に呼ばれると、 送信していないにもかかわらず、送信した事にしてしまいます。 ●extern unsigned short (_far _pascal *MCD_chkbrksig)(void); ●extern void (_far _pascal *MCD_sndbrksig)(void); ブレーク信号の受信確認/送信を行います。 IRCSにはその様な概念はないので、何も行われません。 常に0が返されます。 ●extern void (_far _pascal *MCD_getbuffer)(mcd_buffer_t _far *buf); ●extern void (_far _pascal *MCD_setbuffer)(mcd_buffer_t _far *buf); 送受信バッファを取得/設定します。 setbuffer にて、送受信のバッファアドレスが 00000000h の時は、 設定を変更しません。送受信バッファのどちらかの設定だけを変更する場合、 00000000h にして下さい。 ●extern void (_far _pascal *MCD_rstbuffer)(void); 送受信バッファを、デバイスドライバのオプションとして 指定した時の状態に戻します。 IAUX 独自の隠し返値として、 ES:AX 組み込まれた IAUX の最終アドレス が返されますが、内部的に使用しているものなので、 保証出来ません。 ●extern signed short (_far _pascal *MCD_getc)(void); ●extern signed short (_far _pascal *MCD_putc)(unsigned char c); ●extern unsigned short (_far _pascal *MCD_ndread)(void); 1バイトだけ受信/送信を行います。 getc にて受信データが無ければ -1 を返します。 putc にて送信バッファがいっぱいならば0を返し、 そうでなければ -1 を返します。 nd_read は getc と同様ですが、受信バッファの変更をしません。 次の nd_read や getc にて同じデータを得る事が出来ます。 なお、IRCSの初期化,検出に失敗していた時に送信しようとすると、 送信していないにもかかわらず、送信した事にしてしまいます。 ●extern unsigned short (_far _pascal *MCD_sbufchars)(void); ●extern unsigned short (_far _pascal *MCD_rbufchars)(void); 送信/受信バッファに溜まっているバイト数を得ます。 ●extern unsigned short (_far _pascal *MCD_sbuffree)(void); ●extern unsigned short (_far _pascal *MCD_rbuffree)(void); 送信/受信バッファの空きバイト数を得ます。 ●extern unsigned long (_far _pascal *MCD_getspeed)(void); ●extern void (_far _pascal *MCD_setspeed)(unsigned long speed); ボーレートを取得/設定します。 102400〜9600 の範囲で設定出来ます。範囲外の場合は最大,最小に 合わせます。また、設定出来ない値の場合は一番近い値になります。 (div って上に合わせるんだっけ,下に合わせるんだっけ) 5MHz系/8MHz系の判別は BIOS ワークエリア を利用しています。 なお、範囲内で任意に設定出来ますが、IRCSは 76800 で 動作するように作られています。76800 からかけ離れた値を指定した場合は 正常に送受信出来ません。 デフォルトで 76800 です。 ●extern void (_far _pascal *MCD_getflwsize)(unsigned short _far *stop, unsigned short _far *start); ●extern void (_far _pascal *MCD_setflwsize)(unsigned short stop, unsigned short start); ●extern void (_far _pascal *MCD_setflow)(unsigned short flow); フロー制御に関し取得/設定します。 IRCSはフロー制御出来ないので、ダミーの値を返します。 ●extern void (_far _pascal *MCD_getdevopen)(signed short _far *ignore, signed short _far *count); ●extern void (_far _pascal *MCD_setdevopen)(signed short ignore, signed short count); DEVICE OPEN/CLOSE カウンタの値を取得/設定します。 ignore はダミーで常に0を返します。 count にてオープンされている数を取得/設定します。 setdevopen にて count が -1 ならば変更しません。 基本的に、常駐ソフトを使った時などで open/close の回数に 矛盾が出たのを補正するために有ります。 setdevopen にて0が指定された場合は、IRCSの処理を凍結し、 電源を落とします。正の値が指定された場合は、IRCSの初期化,検出を 再度行います。 ★☆ MCDとの互換性 ☆★ MCDでサポートされている機能の内、以下のものは IAUX では サポートしていません。 ・タイマーサービス ・フロー制御(ダミー値を返す) ・ライン制御(一部を IRCS の初期化の為のトリガに使用、残りはダミー) アプリケーション側で以下の事を余計に処理しなければなりません。 ・KISS処理 ・OSIリンク層処理(エラー検出を除く) 以下の事は IAUX が自動的に行っています。 ・エラー検出,及びエラーデータの破棄 ・1-persistent CSMA処理 ・DWAIT 5 / TXDELAY 0 / AXDELAY 0 / PACLEN 256+α (プゲHiHiHi --- G-HAL --- /// 1997 Jun.01 Sun. ///