MS-DOS割り込み
MS-DOS割り込みとは
MS-DOS割り込みとは、OSが提供しているAPIです。BIOSとアプリの間に位置し、BIOSで互換性のないハードでアプリの互換性を保つのに役立ちます。
ハードウェアの仕様(I/Oポートやマッピングアドレス)が異なっていても、BIOSレベルでの互換性があれば、BIOSコールのみで作られたアプリは互換性を保つ事ができます。
しかしながら、PC-9801やJ-3100、PC/AT互換機、AX機、FM-RなどBIOSレベルで大幅に仕様の異なるPC間ではとてもBIOSコールでは互換性を保つ事ができません。そのため、当時のアプリは今のようなWindows用といった互換性の高いものはなく、FM-R用、J-3100用、PC-9801用といった機種別に発売されているのが普通でした。
MS-DOS割り込みでは、ファイルの入出力や画面への(テキストレベルでの)表示をサポートしています。そのため、グラフィカルな画面でなくとも良いのであれば、MS-DOS割り込みのみでアプリを作る事ができ、MS-DOSが動作しているPC上で共通して使えるアプリを作る事も可能でした。実際、MicroFocus Level II COBOLはDOSコールのみで作られていたため、コンパイラだけで言えばMS-DOSレベルでの互換性はありました。(当然、Level II COBOLを使ってグラフィカルなアプリを作れば、互換性はなくなりますが・・・)
ハードウェアの仕様(I/Oポートやマッピングアドレス)が異なっていても、BIOSレベルでの互換性があれば、BIOSコールのみで作られたアプリは互換性を保つ事ができます。
しかしながら、PC-9801やJ-3100、PC/AT互換機、AX機、FM-RなどBIOSレベルで大幅に仕様の異なるPC間ではとてもBIOSコールでは互換性を保つ事ができません。そのため、当時のアプリは今のようなWindows用といった互換性の高いものはなく、FM-R用、J-3100用、PC-9801用といった機種別に発売されているのが普通でした。
MS-DOS割り込みでは、ファイルの入出力や画面への(テキストレベルでの)表示をサポートしています。そのため、グラフィカルな画面でなくとも良いのであれば、MS-DOS割り込みのみでアプリを作る事ができ、MS-DOSが動作しているPC上で共通して使えるアプリを作る事も可能でした。実際、MicroFocus Level II COBOLはDOSコールのみで作られていたため、コンパイラだけで言えばMS-DOSレベルでの互換性はありました。(当然、Level II COBOLを使ってグラフィカルなアプリを作れば、互換性はなくなりますが・・・)
ファンクションコール
MS-DOSはINT 20H~INT 3FHまでのソフトウェア割り込みを使います。しかし、アプリで主に使うのはINT 21H(ファンクションコール)でしょう。このINT
21HはMS-DOSで用意されたさまざまなファンクションを使うことができます。
使い方は、AHレジスタに機能番号をセットし、その他必要に応じて他のレジスタやメモリの確保を行った後、INT 21Hを呼ぶだけです。
使い方は、AHレジスタに機能番号をセットし、その他必要に応じて他のレジスタやメモリの確保を行った後、INT 21Hを呼ぶだけです。
AHレジスタ | 機能 | 入力 | 出力 | |
---|---|---|---|---|
10進 | 16進 | |||
0 | 00H | プログラム終了 | ||
1 | 01H | キーボード入力 | AL 入力文字 | |
2 | 02H | スクリーン表示 | DL 出力文字 | |
3 | 03H | 補助入力 | AL 入力文字 | |
4 | 04H | 補助出力 | DL 出力文字 | |
5 | 05H | プリンタ出力 | DL 出力文字 | |
6 | 06H | 直接コンソールI/O | DL 出力文字 | |
DL FFH | AL 入力文字または0 | |||
7 | 07H | 直接コンソール入力 | AL 入力文字 | |
8 | 08H | エコーなし入力 | AL 入力文字 | |
9 | 09H | 文字列の表示 | DS:DX 出力文字 | |
10 | 0AH | バッファードキーボード入力 | DS:DX 入力バッファ | DS:DX 入力データー |
11 | 0BH | キーボードステータスの検査 | AL 入力データー | |
12 | 0CH | バッファを空にしてキーボード入力 | AL 機能 | AL 入力データー |
13 | 0DH | ディスクリセット | ||
14 | 0EH | カレント装置の変更 | DL 装置番号 | AL ディスク設置数 |
15 | 0FH | ファイルオープン | DS:DX FCB | AL リターンコード |
16 | 10H | ファイルクローズ | DS:DX FCB | AL リターンコード |
17 | 11H | 最初に一致するエントリーを見つける | DS:DX FCB | AL リターンコード |
18 | 12H | 次に一致するエントリーを見つける | DS:DX FCB | AL リターンコード |
19 | 13H | ファイル削除 | DS:DX FCB | AL リターンコード |
20 | 14H | シーケンシャルリード | DS:DX FCB | AL リターンコード |
21 | 15H | シーケンシャルライト | DS:DX FCB | AL リターンコード |
22 | 16H | ファイルの作成 | DS:DX FCB | AL リターンコード |
23 | 17H | ファイル名の変更 | DS:DX FCB DS:DX+11H 変更後の名前 |
AL リターンコード |
24 | 18H | 予約済 | ||
25 | 19H | カレント装置を求める | AL リターンコード | |
26 | 1AH | ディスク転送アドレスセット | DS:DX ディス転送アドレス | |
27 | 1BH | カレント装置の情報を求める | AL 1クラスタのセクタ長 CX 1セクタのバイト数 DX 総クラスタ数 DS:BX FAT ID |
|
28 | 1CH | 指定装置の情報を求める | DL 装置番号 | AL 1クラスタのセクタ長 CX 1セクタのバイト数 DX 総クラスタ数 DS:BX FAT ID |
29 | 1DH | 予約済 | ||
30 | 1EH | 予約済 | ||
31 | 1FH | カレント装置のDPBを求める | DS:DX DPE | |
32 | 20H | 予約済 | ||
33 | 21H | ランダムリード | DS:DX FCB | AL リターンコード |
34 | 22H | ランダムライト | DS:DX FCB | AL リターンコード |
35 | 23H | ファイルサイズ | DS:DX FCB | AL リターンコード |
36 | 24H | レコード番号セット | DS:DX FCB | DS:DX FCB |
37 | 25H | 割り込みベクタのセット | AL 割り込み番号 DS:DX 割り込みベクタ |
|
38 | 26H | 新しいプログラムセグメントの作成 | DX プログラムセグメントアドレス | |
39 | 27H | ランダムブロックリード | DS:DX FCB CX レコード数 |
AL リターンコード CX レコード数 |
40 | 28H | ランダムブロックライト | DS:DX FCB CX レコード数 |
AL リターンコード レコード数 |
41 | 29H | ファイル名の解析 | AL 解析方法 DS:SI コマンド行 ES:DI FCB |
AL リターンコード DS:SI コマンド行の次に解析する位置 ES:DI FCB |
42 | 2AH | 日付の取り出し | CX 年 DH 月 DL 日 |
|
43 | 2BH | 日付のセット | CX 年 DH 月 DL 日 |
AL リターンコード |
44 | 2CH | 時刻の取り出し | CH 時 CL 分 DH 秒 DL 1/100秒 |
|
45 | 2DH | 時刻のセット | CH 時 CL 分 DH 秒 DL 1/100秒 |
AL リターンコード |
46 | 2EH | べりファイフラグのセット/リセット | AL 1セット 0リセット | |
47 | 2FH | ディスク転送アドレスを求める | ||
48 | 30H | MS-DOSのバージョンを求める | AL メジャーバージョン番号 AH マイナーバージョン番号 BL:CX ユーザー番号(24ビット長) |
|
49 | 31H | プロセスを常駐させる | AL 終了コード DX 常駐部のサイズ |
|
50 | 32H | DPBを求める | DL 装置番号 | AL リターンコード DS:BX DPB |
51 | 33H | 拡張BREAKのオン/オフ | AL 0 現在の状態の取得 AL 1 オン/オフの切り替え DL 0オフ 1オン |
DL 現在の状態(AL=0の時) |
52 | 34H | lndosフラグのアドレスを求める | ES:BX lndosフラグのアドレス | |
53 | 35H | 割り込みベクタアドレスを求める | AL 割り込み番号 | ES:BX 割り込みベクタ |
54 | 36H | ディスクの空き容量を求める | DL 装置番号 | BX 空きクラスタ数 DX 総クラスタ数 CX セクタサイズ AX 1クラスタのセクタ数 AX=FFFFH エラー |
55 | 37H | 構成パラメータの変更 | AL 0 現在の状態の取得 AL 1 変更 DL スイッチ文字 |
DL スイッチ文字(AL=0の時) |
56 | 38H | 国別情報の取得 | DS:DX 国情報取得用エリア AL 国コードまたはFFH BX 国コード(AL=FFHの時) |
DS:DX 国情報コード(取得の時) F キャリーフラグオンならエラー AX エラーコード |
国別情報の設定 | DX FFFFHなら設定 AL 国コードまたはFFH BX 国コード(AL=FFHの時) |
|||
57 | 39H | ディレクトリの作成 | DS:DX パス | F キャリーフラグオンならエラー AX エラーコード |
58 | 3AH | ディレクトリの削除 | DS:DX パス | F キャリーフラグオンならエラー AX エラーコード |
59 | 3BH | カレントディレクトリの変更 | DS:DX パス | F キャリーフラグオンならエラー AX エラーコード |
60 | 3CH | ファイル作成 | DS:DX パス CX 属性 |
F キャリーフラグオンならエラー AX エラーコード |
61 | 3DH | ファイルオープン | DS:DX パス AL アクセスモード |
F キャリーフラグオンならエラー AX エラーコード |
62 | 3EH | ファイルクローズ | DS:DX パス | F キャリーフラグオンならエラー AX エラーコード |
63 | 3FH | ファイル読み込み | BX ファイルハンドル CX バイト数 DS:DX バッファアドレス |
AX 読み込んだバイト数 DS:DX データー F キャリーフラグオンならエラー AX エラーコード |
64 | 40H | ファイル書き込み | BX ファイルハンドル CX バイト数 DS:DX バッファアドレス |
AX 書き込んだバイト数 DS:DX データー F キャリーフラグオンならエラー AX エラーコード |
65 | 41H | ファイル削除 | DS:DX パス | F キャリーフラグオンならエラー AX エラーコード |
66 | 42H | 読み込み/書き込みポインタ移動 | BX ファイルハンドル AL 操作方法 CX:DX 移動量 |
DX:AX 移動後のポインタ F キャリーフラグオンならエラー AX エラーコード |
67 | 43H | ファイル属性の取得/変更 | AL 0取得 1変更 DS:DX パス CX 属性 |
CX 属性(AL=0の時) F キャリーフラグオンならエラー AX エラーコード |
68 | 44H | 装置情報の取得/設定 | AL 0取得 1設定 DS:DX パス CX 属性 |
DX 装置情報(取得の時) F キャリーフラグオンならエラー AX エラーコード |
文字型装置の制御 | AL 2送信 3受信 BX ファイルハンドル CX 制御文字の長さ DS:DX 制御文字バッファ |
AX 転送したバイト数 DS:DX 制御文字 F キャリーフラグオンならエラー AX エラーコード |
||
ブロック型装置の制御 | AL 4送信 5受信 BL 装置番号 CX 制御文字の長さ DS:DX 制御文字バッファ |
AX 転送したバイト数 DS:DX 制御文字 F キャリーフラグオンならエラー AX エラーコード |
||
入出力ステータス | AL 6入力 7出力 BX ファイルハンドル |
AL 0=busy FFH=ready F キャリーフラグオンならエラー AX エラーコード |
||
媒体の交換性 | AL 8 BL 装置番号 |
AX 0交換可 1交換不可 F キャリーフラグオンならエラー AX エラーコード |
||
リモート装置 | AL 9 BL 装置番号 |
DX 属性 F キャリーフラグオンならエラー AX エラーコード |
||
リモートハンドル | AL 0AH BX ファイルハンドル |
DX 属性 F キャリーフラグオンならエラー AX エラーコード |
||
再試行回数/間隔の設定 | AL 0BH DX 再試行する回数 CX 再試行間隔 |
F キャリーフラグオンならエラー AX エラーコード |
||
ブロックデバイスに対する 一般IOCTL |
AL 0DH BL ドライブ番号 CH カテゴリーコード CL ファンクション・コード DS:DX パラメーターブロック |
F キャリーフラグオンならエラー AX エラーコード |
||
論理ドライブマップの取得/設定 | AL 0EH 取得 0FH 設定 BL ドライブ番号 |
AL マッピングコード(取得の時) F キャリーフラグオンならエラー AX エラーコード |
||
IOCTLハンドルの問い合わせ | AL 10H BX ハンドル CH カテゴリーコード CL ファンクションコード |
F キャリーフラグオンならエラー AX エラーコード |
||
OICTLデバイスの問い合わせ | AL 11H BL ドライブ番号 CH カテゴリーコード CL ファンクションコード |
F キャリーフラグオンならエラー AX エラーコード |
||
69 | 45H | ファイルハンドルの複写 | BX ファイルハンドル | AX 複写したファイルハンドル F キャリーフラグオンならエラー AX エラーコード |
70 | 46H | ファイルハンドルの強制複写 | BX ファイルハンドル CX 新しいファイルハンドル |
F キャリーフラグオンならエラー AX エラーコード |
71 | 47H | カレントディレクトリのパスを求める | DL 装置番号 DS:SI バッファアドレス(64バイト) |
DS:SI アドレス F キャリーフラグオンならエラー AX エラーコード |
72 | 48H | メモリの割付 | BX ブロック数 | AX セグメント F キャリーフラグオンならエラー AX エラーコード BX 空きブロック数 |
73 | 49H | メモリ割付の解除 | ES メモリブロックのセグメント | F キャリーフラグオンならエラー AX エラーコード |
74 | 4AH | 割り付けたメモリブロックの変更 | ES メモリブロックのセグメント BX 変更後のサイズ |
F キャリーフラグオンならエラー AX エラーコード BX 変更可能な最大のサイズ |
75 | 4BH | プログラムのロード、実行 | AL 機能コード 0 3 DS:DX パス ES:BX パラメーター |
ES:BX パラメーター F キャリーフラグオンならエラー AX エラーコード |
76 | 4CH | プログラムの終了 | AL 終了コード | |
77 | 4DH | 子プロセスの終了コード取得 | AX 終了コード | |
78 | 4EH | 最初に一致するファイルを見つける | DS:DX パス CX 属性 ディスク転送領域を確保しておく |
F キャリーフラグオンならエラー AX エラーコード ディスク転送領域に情報が入る |
79 | 4FH | 次に一致するファイルを見つける | ディスク転送領域を確保しておく | F キャリーフラグオンならエラー AX エラーコード ディスク転送領域に情報が入る |
86 | 56H | ディレクトリエントリの移動 | DS:DX 移動前のパス ES:DI 移動後のパス |
F キャリーフラグオンならエラー AX エラーコード |
87 | 57H | タイムスタンプの取得と変更 | AL 0 (取得) BX ファイルハンドル |
CX:DX 日時 F キャリーフラグオンならエラー AX エラーコード |
AL 1 (変更) BX ファイルハンドル CX:DX 変更日時 |
F キャリーフラグオンならエラー AX エラーコード |
|||
88 | 58H | メモリー割付方法の取得と設定 | AL 0 取得 | AX 割付方法 |
AL 1 変更 BX 割付方法 |
F キャリーフラグオンならエラー AX エラーコード |
|||
89 | 59H | 拡張エラーコードの取り出し | BX 0 | AX 拡張エラーコード BH エラーの種類 BL 行える処理 CH 発生場所 |
90 | 5AH | 一時ファイルの作成 | CX 属性 DS:DX ファイル名 |
AX ファイルハンドル F キャリーフラグオンならエラーで AXにエラーコード |
91 | 5BH | 空ファイルの作成 | CX 属性 DS:DX ファイル名 |
AX ファイルハンドル F キャリーフラグオンならエラーで AXにエラーコード |
92 | 5CH | ファイルのロックとアンロック | AL 0 ロック BX ファイルハンドル CX:DX オフセット SI:DI バイト数 |
F キャリーフラグオンならエラー AX エラーコード |
AL 1 アンロック BX ファイルハンドル CX:DX オフセット SI:DI バイト数 |
F キャリーフラグオンならエラー AX エラーコード |
|||
94 | 5EH | マシン名の取り出し プリンタのセットアップ |
AL 0 マシン名の取り出し DS:DX マシン名の領域16バイト |
DS:DX マシン名 CX 識別番号 F キャリーフラグオンならエラー AX エラーコード |
AL 2 プリンタのセットアップ BX アサインリストインデックス DS:SI 制御文字列 |
F キャリーフラグオンならエラー AX エラーコード |
|||
95 | 5FH | アサインリストの取出、作成、取消 | AL 2 取り出し BX アサインリストインデックス DS:SI ローカル名 ES:DI リモート名 |
DL 3か4 CX ユーザーが定義した値 F キャリーフラグオンならエラー AX エラーコード |
AL 3 作成 BL 3か4 CX 任意の値 DS:SI 装置名 ES:DI リモート名 |
F キャリーフラグオンならエラー AX エラーコード |
|||
AL 4 取り消し DS:SI 装置名 |
F キャリーフラグオンならエラー AX エラーコード |
※MS-DOSシステムが内部的に使用するファンクションコールは省いています。
キー入力
キーボードから文字入力を行うファンクションです。Ctrl-C割り込みを受け付けてくれるものもあります。ここでは日本語入力システムの制御は行いませんので、日本後入力を促すのであれば、別途ATOK割り込み等のFEP制御を使う必要があります。
AH=01H 06H 07H 08H 1文字入力
キーが押されるまで待って、押されたらALレジスタに文字コードが入ります。ALレジスタに00が入った場合はもう1回同じファンクションをコールします。エコーありの時は入力された文字を画面に表示します。Ctrl-Cチェックありの時は、Ctrl-Cが押されたらプログラムが強制中断され
プロンプト(C:\>とか)に戻ります。
IN
AH
01H エコーあり Ctrl-Cチェックあり
06H エコーあり Ctrl-Cチェックなし
07H エコーなし Ctrl-Cチェックなし
08H エコーなし Ctrl-Cチェックあり
OUT
AL 文字コード
AH=0AH 文字列の入力
[Enter]キーが押されるまで文字列を入力します。
IN
AH 0AH
DS:DX 文字列バッファ(256バイト)
256バイト確保しておく必要があります。
Ctrl-Cキーが押されたらプログラムを中止してプロンプトに戻ります。
AH=0BH キーバッファのチェック
キーバッファの先頭をチェックして先頭をクリアします。
AH 0BH
AH=0CH キーバッファクリア後文字入力
バッファをクリアした後、キー入力をします。どのモードでキー入力を行うかをALレジスタで指定します。
AH 0CH
AL
01H エコーあり Ctrl-Cチェックあり
06H エコーあり Ctrl-Cチェックなし
07H エコーなし Ctrl-Cチェックなし
08H エコーなし Ctrl-Cチェックあり
AH=01H 06H 07H 08H 1文字入力
キーが押されるまで待って、押されたらALレジスタに文字コードが入ります。ALレジスタに00が入った場合はもう1回同じファンクションをコールします。エコーありの時は入力された文字を画面に表示します。Ctrl-Cチェックありの時は、Ctrl-Cが押されたらプログラムが強制中断され
プロンプト(C:\>とか)に戻ります。
IN
AH
01H エコーあり Ctrl-Cチェックあり
06H エコーあり Ctrl-Cチェックなし
07H エコーなし Ctrl-Cチェックなし
08H エコーなし Ctrl-Cチェックあり
OUT
AL 文字コード
AH=0AH 文字列の入力
[Enter]キーが押されるまで文字列を入力します。
IN
AH 0AH
DS:DX 文字列バッファ(256バイト)
256バイト確保しておく必要があります。
Ctrl-Cキーが押されたらプログラムを中止してプロンプトに戻ります。
AH=0BH キーバッファのチェック
キーバッファの先頭をチェックして先頭をクリアします。
AH 0BH
AH=0CH キーバッファクリア後文字入力
バッファをクリアした後、キー入力をします。どのモードでキー入力を行うかをALレジスタで指定します。
AH 0CH
AL
01H エコーあり Ctrl-Cチェックあり
06H エコーあり Ctrl-Cチェックなし
07H エコーなし Ctrl-Cチェックなし
08H エコーなし Ctrl-Cチェックあり
画面出力
画面表示を行うファンクションです。画面にただズラズラ表示させるだけでなく、エスケープシーケンスを使うことでライン/カラムの指定を行う事もできます。日本語MS-DOSはほぼ画面が80カラム20ライン(または25ライン)に固定でしたので、MS-DOS用アプリを作る際には、エスケープシーケンスによるライン/カラム指定は長方重宝しました。
AH=02H 文字の表示
ALレジスタで示した文字1文字を表示します。全角を表示させる時は上位バイト/下位バイトの2回呼びます。
AH=09H 文字列の表示
DS:DXで示したアドレスから$(24H)が来るまで文字列を表示します。ガイドメッセージを表示させるには便利ですが、$マークを表示させる事が
できないため、ユーザーから入力された文字列や商品名のような実データーを表示させるには不向きです。
AH=02H 文字の表示
ALレジスタで示した文字1文字を表示します。全角を表示させる時は上位バイト/下位バイトの2回呼びます。
AH=09H 文字列の表示
DS:DXで示したアドレスから$(24H)が来るまで文字列を表示します。ガイドメッセージを表示させるには便利ですが、$マークを表示させる事が
できないため、ユーザーから入力された文字列や商品名のような実データーを表示させるには不向きです。
割り込みベクタの読み込み/設定
ソフトウェア割り込み(int XXH)をかけた時に処理されるアドレスを求めます。
例えばBIOSのプリンタドライバを拡張する場合、いったん割り込みベクタアドレスを退避させておいて、自前のルーチンに書き換えて、自前のルーチンから元々の割り込み処理を呼ぶ場合に使ったりします。
AH
25H 設定
35H 読み出し
DS:DX 新しい割り込み処理アドレス(設定の時)
ES:BX 今までの処理アドレス(読み出しの時)
例えばBIOSのプリンタドライバを拡張する場合、いったん割り込みベクタアドレスを退避させておいて、自前のルーチンに書き換えて、自前のルーチンから元々の割り込み処理を呼ぶ場合に使ったりします。
AH
25H 設定
35H 読み出し
DS:DX 新しい割り込み処理アドレス(設定の時)
ES:BX 今までの処理アドレス(読み出しの時)
ファイル入出力
MS-DOSのファイルシステムはMS-DOS3.0が主流になりはじめてから、Windows2000以降のNTFSファイルシステムが主流になるまでの間、比較的長い期間主流で使われてきました。
8ビットパソコン(のうちのFM-7やPC-8801など)ではフロッピーの使い方は各ゲームまちまちで、セクタ長やセクタ数などもそれぞれゲームごとに変わっていました。そして、何トラックの何セクタには何が入って・・といった、フロッピーの決まった場所に決まったデーターを入れる事が多かったです。
MS-DOSファイルシステムが主流になるにつれ、そういったフロッピーの特定の場所に特定のデーターを入れるのではなく、データーを「ファイル」という単位で扱うものが多くなりました。ファイルという単位で扱う事で、規格の違うフロッピー(例えば、2DDから2HDとか)にファイルコピーという形でコピーを行ったり、フロッピーからハードディスク、ハードディスクからMOといった、物理的にもセクタ割り的にもまったく異なるメディアにデーターをコピーする事も可能となりました。
ここでは、DOSコールによりファイルの入出力のファンクションを紹介します。Windows95以降のロングファイル名のファイルはこのファンクションでは扱えませんが、ショートファイル名(新しい~1みたいなの)を指定すればアクセスできる可能性もあります。
ファイルコントロールブロック(FCB)
ファイルコントロールブロックを使ったファイルへのアクセスは、AH=0FH~AH=29Hあたりに用意されています。これらのファンクションを使うためには、あらかじめファイルコントロールブロックという37バイトのメモリーを確保しておく必要があります。
8ビットパソコン(のうちのFM-7やPC-8801など)ではフロッピーの使い方は各ゲームまちまちで、セクタ長やセクタ数などもそれぞれゲームごとに変わっていました。そして、何トラックの何セクタには何が入って・・といった、フロッピーの決まった場所に決まったデーターを入れる事が多かったです。
MS-DOSファイルシステムが主流になるにつれ、そういったフロッピーの特定の場所に特定のデーターを入れるのではなく、データーを「ファイル」という単位で扱うものが多くなりました。ファイルという単位で扱う事で、規格の違うフロッピー(例えば、2DDから2HDとか)にファイルコピーという形でコピーを行ったり、フロッピーからハードディスク、ハードディスクからMOといった、物理的にもセクタ割り的にもまったく異なるメディアにデーターをコピーする事も可能となりました。
ここでは、DOSコールによりファイルの入出力のファンクションを紹介します。Windows95以降のロングファイル名のファイルはこのファンクションでは扱えませんが、ショートファイル名(新しい~1みたいなの)を指定すればアクセスできる可能性もあります。
ファイルコントロールブロック(FCB)
ファイルコントロールブロックを使ったファイルへのアクセスは、AH=0FH~AH=29Hあたりに用意されています。これらのファンクションを使うためには、あらかじめファイルコントロールブロックという37バイトのメモリーを確保しておく必要があります。
+0 ドライブ番号 +1 ファイル名 +9 拡張子 +12 カレントブロック番号 +14 レコードサイズ +16 ファイルサイズ(4バイト) +20 日付 +22 時刻 +24 予備 +32 ブロック内レコード番号 +33 絶対レコード番号(4バイト) |
ただし、これはMS-DOS 2.X時代のアプリとの互換性のために用意されているもので、階層化ディレクトリに対応してなかったり(全てカレントディレクトリに対する操作になる)、ファイルをブロック単位でアクセスしたりと、あまり便利が良くありません。
ファイルハンドルを使ったファイルの読み書き
MS-DOS3.XX以降で使うのであれば、FCBを使ったファイルアクセスではなく、AH=3DHあたりから用意されているファイルハンドルを使ったアクセスを使うべきです。すでに、J-3100ではMS-DOS2.XXで動作する環境はほとんどなく、全ての機種がMS-DOS3.XX以降であるとみなしてアプリを作っても、特に問題はなかったと思います。
古いシステムの解析やレベルアップを行う際にも、ファイルハンドル方式さえ把握していればまず大丈夫と思います。
ファイルのオープン
ファイルのオープンは、AH=3DH、ALにアクセスモードを入れます。アクセスモードはALレジスタの8ビットをさらに3つに分けて考えます。
ビット 0~3 アクセスコード
ビット 4~6 共有モード
ビット 7 引継ぎビット
引継ぎビットは0の時に子プロセスにオープン状態が引き継がれます。
共有モードは下記の通りです。
000 コンパチブル
001 読み込み書込み禁止
010 書込み禁止
011 読み込み禁止
100 読み込み書き込み可
コンパチブルモードでオープンすると、他のプロセスが同じファイルをオープンする事ができます。DOSでLANを組んだ場合などで使いました。
コンパチブルモード以外のモードは、他のプロセスがコンパチブルモードでオープンしている場合、オープンができません。共有違反になります。また、他のプロセスが、読み込み書き込み禁止/書き込み禁止/読み込み禁止とそれぞれ指定しているモードでオープンする事ができません。
アクセスコードは下記の通りです。
0000 読み込み
0001 書き込み
0010 読み書き
読み込みモードとは、CやPHPでいうところの"r"モード、COBOLでいうところの open input です。シーケンシャルファイル等を読み込み専用でオープンします。
書き込みモードとは、CやPHPでいうところの"w"モード、COBOLでいうところの open output、Perlでいうところの >ファイル名のことで、ファイルを書き込み専用でオープンします。
読み書きモードとは、Cで低水準ファイル入出力の読み書きモード、COBOLの open i-oと同じで、読むことも書くこともできるモードになります。
下記の例では、SFILEで示した場所にあるファイル名を、コンパチブルモードの読み込みモードでオープンし、ファイルハンドルをSHANDLEに格納しています。
ファイルハンドルを使ったファイルの読み書き
MS-DOS3.XX以降で使うのであれば、FCBを使ったファイルアクセスではなく、AH=3DHあたりから用意されているファイルハンドルを使ったアクセスを使うべきです。すでに、J-3100ではMS-DOS2.XXで動作する環境はほとんどなく、全ての機種がMS-DOS3.XX以降であるとみなしてアプリを作っても、特に問題はなかったと思います。
古いシステムの解析やレベルアップを行う際にも、ファイルハンドル方式さえ把握していればまず大丈夫と思います。
ファイルのオープン
ファイルのオープンは、AH=3DH、ALにアクセスモードを入れます。アクセスモードはALレジスタの8ビットをさらに3つに分けて考えます。
ビット 0~3 アクセスコード
ビット 4~6 共有モード
ビット 7 引継ぎビット
引継ぎビットは0の時に子プロセスにオープン状態が引き継がれます。
共有モードは下記の通りです。
000 コンパチブル
001 読み込み書込み禁止
010 書込み禁止
011 読み込み禁止
100 読み込み書き込み可
コンパチブルモードでオープンすると、他のプロセスが同じファイルをオープンする事ができます。DOSでLANを組んだ場合などで使いました。
コンパチブルモード以外のモードは、他のプロセスがコンパチブルモードでオープンしている場合、オープンができません。共有違反になります。また、他のプロセスが、読み込み書き込み禁止/書き込み禁止/読み込み禁止とそれぞれ指定しているモードでオープンする事ができません。
アクセスコードは下記の通りです。
0000 読み込み
0001 書き込み
0010 読み書き
読み込みモードとは、CやPHPでいうところの"r"モード、COBOLでいうところの open input です。シーケンシャルファイル等を読み込み専用でオープンします。
書き込みモードとは、CやPHPでいうところの"w"モード、COBOLでいうところの open output、Perlでいうところの >ファイル名のことで、ファイルを書き込み専用でオープンします。
読み書きモードとは、Cで低水準ファイル入出力の読み書きモード、COBOLの open i-oと同じで、読むことも書くこともできるモードになります。
下記の例では、SFILEで示した場所にあるファイル名を、コンパチブルモードの読み込みモードでオープンし、ファイルハンドルをSHANDLEに格納しています。
;ソースファイルオープン(INPUT) NASI = $ MOV AX,3D00H MOV DX,OFFSET SFILE INT 21H MOV [SHANDLE],AX JNC ACHK1 JMP ERR
ファイルのシーク
ファイルの読み書きポインタを移動します。これを使うことで事実上ランダムアクセスを実現可能にします。(ポインタの移動量は別途計算しなければなりませんが)
AX=42H
AL=0 ポインタを先頭からCX:DXの位置に移動します。
AL=1 ポインタを現在位置からCX:DXの位置に移動します。
AL=2 ポインタを一番最後からCX:DXの位置に移動します。
また、この機能はファイルサイズを調べる際にも使います。下記例では、ポインタを最後に移動して現在のポインタを調べることでファイルサイズを得ています。
ファイルの読み書きポインタを移動します。これを使うことで事実上ランダムアクセスを実現可能にします。(ポインタの移動量は別途計算しなければなりませんが)
AX=42H
AL=0 ポインタを先頭からCX:DXの位置に移動します。
AL=1 ポインタを現在位置からCX:DXの位置に移動します。
AL=2 ポインタを一番最後からCX:DXの位置に移動します。
また、この機能はファイルサイズを調べる際にも使います。下記例では、ポインタを最後に移動して現在のポインタを調べることでファイルサイズを得ています。
;コピー元のファイルサイズをチェック ACHK1 = $ MOV AH,42H MOV AL,2 MOV BX,[SHANDLE] MOV CX,0 MOV DX,0 INT 21H MOV [SIZ1],DX MOV [SIZ2],AX
ファイルの読み書き
AH=3FH 読み込み
AH=40H 書き込み
BX ファイルハンドル
CX 読み込む量、書き込む量
DS:DX バッファ
CXレジスタには読み込むバイト数、書き込むバイト数をセットしますが、実際にそのバイトまで読み書きできるとは限らないため、DOSコール後にCXレジスタをチェックする必要があります。
下記の例では、ファイルハンドルSHANDLEから、DHANDLEに中身をコピーしています。
AH=3FH 読み込み
AH=40H 書き込み
BX ファイルハンドル
CX 読み込む量、書き込む量
DS:DX バッファ
CXレジスタには読み込むバイト数、書き込むバイト数をセットしますが、実際にそのバイトまで読み書きできるとは限らないため、DOSコール後にCXレジスタをチェックする必要があります。
下記の例では、ファイルハンドルSHANDLEから、DHANDLEに中身をコピーしています。
;ファイルリード READ1: MOV AH,3FH MOV BX,[SHANDLE] MOV CX,5000H MOV DX,OFFSET BUFF INT 21H JNC READ2 JMP ERR READ2 = $ CMP AX,0 JE CLOSE ;ファイルライト MOV CX,AX MOV AH,40H MOV BX,[DHANDLE] MOV DX,OFFSET BUFF INT 21H JNC READ3 JMP ERR READ3 = $ JMP READ1
ファイルのクローズ
ファイルを閉じます。下記例ではコピー元、コピー先を閉じています。一応、プログラムの終了(AH=4CH)をコールすれば自動的に全ファイルがクローズされますが、オープンしたファイルはきちんとそのプログラム内でクローズする習慣をつけておきましょう。
ファイルを閉じます。下記例ではコピー元、コピー先を閉じています。一応、プログラムの終了(AH=4CH)をコールすれば自動的に全ファイルがクローズされますが、オープンしたファイルはきちんとそのプログラム内でクローズする習慣をつけておきましょう。
; ファイルクローズ MOV AH,3EH MOV BX,[SHANDLE] INT 21H MOV AH,3EH MOV BX,[DHANDLE] INT 21H
ワイルドカードの処理
ワイルドカードにてファイル名を指定された場合に、一致するファイルを検索する機能が用意されています。コマンドライン引数を受け取り、ワイルドカードに合致するファイルを順に処理したい場合に用います。
AH=1AHファンクションコールを用いてディスク転送アドレスをセットした後、AH=4EHの最初に一致するファイルを見つけるファンクションコールを呼びます。2回目以降はキャリーフラグが立つまでAH=4FHファンクションコールを呼び、取得したファイル名に対して処理(この例ではDUMP_MAIN1)を呼び出します。もちろん1回目の時にキャリーフラグが立った場合は、file not foundという事になります。
AH=1AHファンクションコールを用いてディスク転送アドレスをセットした後、AH=4EHの最初に一致するファイルを見つけるファンクションコールを呼びます。2回目以降はキャリーフラグが立つまでAH=4FHファンクションコールを呼び、取得したファイル名に対して処理(この例ではDUMP_MAIN1)を呼び出します。もちろん1回目の時にキャリーフラグが立った場合は、file not foundという事になります。
;------------------------------------------------------------------- ; ワイルドカードの検査 ;------------------------------------------------------------------- ;------------- 最初に一致するファイルを見つける FIND_1 = $ MOV AH,1AH MOV DX,OFFSET FIND_BUF INT 21H MOV AH,4EH MOV DX,OFFSET SFILE MOV CX,0 INT 21H JNC $+5 JMP NAI CALL KAIG CALL DUMP_MAIN1 ;------------- 次に一致するファイルを見つける FIND_2 = $ MOV AX,2020H MOV DI,OFFSET FIND_PNAME MOV CX,13 CLD REP STOSB MOV AH,4FH INT 21H JNC $+5 JMP OWARI CALL DUMP_MAIN1 JMP FIND_2
参考文献
『J-3100解析ハンドブック』 1989年 土屋勝著 ナツメ社
『DOS/Vテクニカル・リファレンス・マニュアル』 1993年 芦達剛著 ソフトバンク
『J-3100シリーズ・テクニカルマニュアル』 1994年 南部武彦著 ソフトバンク
『ATOK読本』 1994年 山田祥平 ジャストシステム
『東芝パソコンハンドブック94年版』 平成6年3月1日
このページの先頭へ
『J-3100解析ハンドブック』 1989年 土屋勝著 ナツメ社
『DOS/Vテクニカル・リファレンス・マニュアル』 1993年 芦達剛著 ソフトバンク
『J-3100シリーズ・テクニカルマニュアル』 1994年 南部武彦著 ソフトバンク
『ATOK読本』 1994年 山田祥平 ジャストシステム
『東芝パソコンハンドブック94年版』 平成6年3月1日
広告