MSXディスクシステムの持つ入出力機能はBDOSというかたちで、汎用のサブルーチン形式でROMにまとめられています。ファンクションコールとは、BDOSを呼び出すためにあらかじめ決められた手順のことで、ユーザープログラムはファンクションコールを実行することでファイルの入出力操作が簡単にできます。
ファンクションコールの役割は、大きく分けると2つがあります。
- 基本的な機能をあらかじめ用意することによってプログラムの負担を少なくすること。
- すべてのプログラムが共通の手順を使用することによって、移植性や汎用性を高めること。
ファンクションコールを自由自在に活用することによって、プログラム開発の期間は短縮され、できあがったプログラムは移植性の高いものになります。これは、OSを利用した時の最大のメリットの1つです。
ファンクションコールを実行するには、CPUのCレジスタに決められたファンクション番号を入れ、次のアドレスをコールします。
0005H | MSX-DOS上の外部コマンド |
F37DH | Disk BASIC上のマシン語プログラム |
例えば、ファンクション番号が1FHであり、コール手順としてAレジスタに00Hをセットすることになっているファンクションコールがあるとすると、このファンクションコールは次のようにして実行します。
ld a,00h
ld c,1fh
call 0005h ; Disk BASICのときは0F37DH
CALL文の後には、戻り値(処理の結果)を受け取ったり、退避していたレジスタを復活させたりする事後処理が続きます。
Disk BASICのプログラムからは、CLEAR文で確保した領域にマシン語プログラムを置き、その開始アドレスをUSR関数で呼び出すことでファンクションコールを利用できます。
ここでは、以下の書式によってファンクションコールの使用法を紹介します。
ファンクション番号とは、ファンクションコールの種類を判別するためのもので、それぞれのファンクションコールに対応する番号が決められています。ファンクションコールを実行するときには、このファンクション番号をCレジスタにセットします。
ファンクションコールの前準備として、レジスタやメモリに必要な値をセットしなければならないことがあります。ここでは、これを「コール手順」の部分に示します。
ファンクションコールの結果得られた値は、レジスタやメモリにセットされます。獲得した値が、どこにどのようにセットされるかを、「戻り値」の部分に示します。
ただし、ファンクションコールでは、戻り値がセットされるレジスタ以外にも、ファンクション内での作業に使用され、内容が破壊されるレジスタがあります。ファンクションコールでは原則としてレジスタのもとの内容は保障していません。そこで、ファンクションコールを使用するときには、その前に、破壊されては困るレジスタの内容を、適当な場所(スタックなど)に退避して下さい。
ファンクションコールの解説です。
表3.6 ファンクションコール一覧
ファンクション番号 | 機能 | CP/M※ | ページ |
00 | システムリセット | ○ | 419 |
01 | コンソール1文字入力 | ○ | 419 |
02 | コンソール1文字出力 | ○ | 420 |
03 | 補助装置1文字入力 | ○ | 421 |
04 | 補助装置1文字入力 | ○ | 421 |
05 | プリンタ1文字出力 | ○ | 422 |
06 | コンソール直接入出力(入力時エコーバック、コントロールコードチェック、入力待無) | ○ | 422 |
07 | コンソール直接入出力(入力時エコーバック、コントロールコードチェック無) | | 423 |
08 | コンソール直接入出力(入力時エコーバック無) | | 423 |
09 | コンソール文字列出力 | ○ | 424 |
0A | コンソール1行入力 | ○ | 424 |
0B | コンソール入力チェック | ○ | 425 |
0C | バージョン番号の取り出し | ○ | 425 |
0D | ディスクリセット | ○ | 426 |
0E | ディフォルトドライブの設定 | ○ | 426 |
0F | ファイルのオープン | ○ | 427 |
10 | ファイルのクローズ | ○ | 428 |
11 | ファイルの検索(ワイルドカードに一致する最初のファイル) | ○ | 428 |
12 | ファイルの検索(ワイルドカードに一致する後続のファイル) | ○ | 429 |
13 | ファイルの削除 | ○ | 429 |
14 | シーケンシャル読み出し | ○ | 430 |
15 | シーケンシャル書き込み | ○ | 430 |
16 | ファイルの作成 | ○ | 431 |
17 | ファイル名の変更 | ○ | 432 |
18 | ログインベクトルの獲得 | ○ | 432 |
19 | ディフォルトドライブの獲得 | ○ | 433 |
1A | 転送アドレスの設定 | ○ | 433 |
1B | ディスク情報の獲得 | | 434 |
21 | ランダム読み出し | ○ | 434 |
22 | ランダム書き込み | ○ | 435 |
23 | ファイルサイズの獲得 | ○ | 435 |
24 | ランダムレコードの設定 | ○ | 436 |
26 | ランダムブロック書き込み | | 436 |
27 | ランダムブロック読み出し | | 437 |
28 | ゼロ書き込みを伴うランダム書き込み | ○ | 438 |
2A | 日付の獲得 | | 438 |
2B | 日付の設定 | | 439 |
2C | 時刻の獲得 | | 440 |
2D | 時刻の設定 | | 440 |
2E | ベリファイフラグの設定 | | 441 |
2F | 論理セクタの読み出し | | 441 |
30 | 論理セクタの書き込み | | 442 |
- 「○」は、CP/M 2.2のファンクションとの互換性があるものを示している。
ファンクションコールのファンクション番号は00H〜30Hですが、この中には以下の無効なファンクション番号があります。
これらの無効なファンクションコールを実行したときには、AレジスタとBレジスタに00Hがセットされる以外は何も行いません。また、31H以降のファンクション番号でも結果は同じです。
00H
なし
なし
MSX-DOS上のプログラムからコールしたときには、MSX-DOSがウォームスタートし、DOSのコマンドレベルに戻ります。Disk BASIC上のプログラムからコールしたときには、Disk BASICがウォームスタートし、BASICのコマンドレベルに戻ります。このとき、ロードされているBASICのプログラムは破壊されません。
01H
なし
入力がないとき(キーボードバッファが空のとき)には、入力を待ちます。入力された文字はコンソールにエコーバックされます。以下に示すコントロールキャラクタはファンクション内部で処理されるため、入力としては扱いません。
[CTRL]+[C] | システムリセット |
[CTRL]+[P] | プリンタへのエコー開始 |
[CTRL]+[N] | プリンタへのエコー停止 |
[CTRL]+[C]が入力されるとプログラムの実行を中断してMSX-DOSのコマンドレベルに戻ります。[CTRL]+[P]が入力されると、以降のコンソール出力はすべてプリンタにもエコーします。この状態は、[CTRL]+[N]を入力することによって解除されます。
02H
なし
Eレジスタで指定した文字を画面に表示します。この際、コンソール入力をチェックし、[CTRL]+[C]、[CTRL]+[P]、[CTRL]+[N]、[CTRL]+[S]の処理を行います。[CTRL]+[S]が入力されると、次に任意のキーを押すまでファンクション内部で入力待ちを行うので、プログラムの一時停止ができます。
03H
なし
A | 補助入力装置(AUXデバイス)から読み込んだ1文字 |
補助入力装置がセットされていないときは、EOF文字(1AH)を返します。コンソール入力は、ファンクション02Hと同様にチェックします。
04H
E | 補助出力装置(AUXデバイス)に出力する文字コード |
なし
補助出力装置がセットされていないときは何もしません。出力は捨てられます。コンソール入力は、ファンクション02Hと同様にチェックします。
05H
なし
文字コードをプリンタに出力します。コンソール入力は、ファンクション02Hと同様にチェックします。
06H
E | FFH | 入力 |
| FFH以外 | セットされた値を文字コードとみなしてコンソールに出力 |
■EレジスタがFFHだったとき(入力)
A | コンソール入力があるときはその文字コード |
| コンソールがないときは00H |
■EレジスタがFFH以外だったとき(出力)
入力のとき、エコーバック、コントロールキャラクタの処理は行いません。(入力文字として扱われる)。また、出力のとき、プリンタへのエコーバックは行いません。
07H
なし
エコーバック、コントロールキャラクタの処理は行いません。
このファンクションコールはCP/Mとの互換性はありません。
08H
なし
エコーバックは行いません。コントロールキャラクタはファンクション01Hと同様に処理します。
このファンクションコールはCP/Mとの互換性はありません。
09H
DE | コンソールに出力する文字列があるメモリの先頭アドレス |
なし
文字列の最後には、終端文字(ターミネータ)として「$」(24H)を置きます。最初に現れる「$」の直前までの文字列をコンソールに出力するので、「$」文字を出力することはできません。
コントロールキャラクタはファンクション02Hと同様にチェックします。
0AH
DE | 行バッファの先頭アドレス |
行バッファ+0 | 最大入力文字数(1〜255)(図3.22参照) |
行バッファ+1 | 実際に入力された文字数 |
行バッファ+2〜 | コンソールから入力された文字列 |
リターンキーの直前までをコンソールからの入力とみなします。最大入力文字数以上を入力することはできません。このファンクションコールによる文字列入力時には、テンプレートによる編集ができます。
このファンクションコールは、コントロールキャラクタをチェックします。
0BH
なし
A | FFH | コンソール入力がある |
| 00H | コンソール入力がない |
コンソール入力の状態を調べます。入力文字があるとときもその文字は取り出しません。ただし、コントロールキャラクタはファンクション02Hと同様にチェックします。入力文字は、ファンクション01Hか08Hで取り出すことができます。
0CH
なし
このファンクションコールは、CP/Mのバージョン番号を獲得するためのものです。MSX-DOSでは、必ず0022Hが戻ります。
0DH
なし
なし
変更されて、まだディスクに書き込まれていないセクタがあれば、それをディスクに書き込んだ後、デフォルトドライブをAドライブにセットし、DTAを0080Hにセットします。
0EH
E | デフォルトドライブ番号(A=0、B=1、・・・H=7) |
なし
デフォルトドライブを変更します、FCBなどのドライブ番号に「0」が指定されたときに有効です。接続されていないドライブが指定されたときには、変更しません。
0FH
DE | オープンされていないFCBの先頭アドレス |
FCBのカレントブロック | 読み出すブロック番号 |
■ | オープン成功のとき |
| A | 0 |
| | FCBの各フィールドが設定される |
■ | オープン失敗のとき |
| A | 0FFH |
FCBがファイル入出力のファンクションコールで使用できるようになります。レコードサイズ、カレントレコード、ランダムレコードの各フィールドは使用するファンクションに応じてオープンの後、ユーザープログラムで設定しなければなりません。
10H
現在のFCBの内容をディスク上の該当するディレクトリエリアに書き込むことによって、ファイルの更新に関する整合性を保ちます。ただし、ファイルの内容を変更していないときには、書き込みは行いません。クローズしたFCBはオープンされていないFCBとして再利用できます。また、オープンされたFCBとしてさらに入出力を続けることもできます。
11H
A | 00H | ファイルが見つかった |
| 0FFH | ファイルが見つからなかった |
| | ファイルが見つかったときは、DTAで指定される領域にドライブ番号を、それに続く32バイトにそのファイルのディスク上のディレクトリエントリをセットする。 |
ファイル名にはワイルドカード文字の「?」を使用することができます。例えば、ファイル名の名前部分に「????????」、拡張子部分に「MAC」を設定すると、「MAC」という拡張子を持つファイルのうち、最初にマッチしたファイルのディレクトリ情報を得ることができます。ファンクションコールレベルでは、ワイルドカード文字の「*」はサポートしていないので、適当な数の「?」に置き換えて下さい。一致するファイルすべてを検索したいときや、一致するファイルが1個だけかどうかを知りたいときには、ファンクション12Hを利用します。
DTA領域に設定されたデータはオープンされていないFCBとして使用できます。
12H
なし
A | 00H | ファイルが見つかった |
| FFH | ファイルが見つからなかった |
| | ファイルが見つかったときは、DTAで指定される領域にドライブ番号を、それに続く32バイトにそのファイルのディスク上のディレクトリエントリをセットする。 |
このファンクションコールは、ファンクション11Hのワイルドカード文字によるファイル名の指定と一致した複数のファイルを検索するときに使います。単独で使用することはできません。このファンクションコールを繰り返し使用して、ファンクション11Hによって一致した複数のファイルのディレクトリ情報を、1つずつ順番に獲得していくことができます。
DTA領域に設定されたデータはオープンされていないFCBとして使用できます。
13H
このファンクションコールでは、ファイル名にワイルドカード文字を指定して、複数のファイルを一度に削除することができます。
14H
DE | オープンされたFCBの先頭アドレス |
FCBのカレントレコード | 読み出すレコード番号 |
A | 00H | 読み出しが成功 |
| 01H | 読み出しが失敗 |
| 読み出しが成功したときは、DTA以降の128バイトに読み込んだレコードをセットします。 |
FCBのカレントブロックとカレントレコードは、読み出し後に次のレコードを指すように自動的に更新されます。したがって、連続して読み出すときは、カレントブロックとカレントレコードを再設定する必要はありません。
このファンクションコールが失敗するのは、ファイルの終わりに達したときです。また、読み出すレコードサイズは128バイト固定です。
15H
DE | オープンされたFCBの先頭アドレス |
FCBのカレントレコード | 書き込むレコード番号 |
DTA以降の128バイト | 書き込むデータ |
A | 00H | 書き込みが成功 |
| 01H | 書き込みが失敗 |
FCBのカレントブロックとカレントレコードは、書き込み後に次のレコードを指すように自動的に更新されます。したがって、連続して書き込むときには、カレントブロックとカレントレコードを再設定する必要はありません。
このファンクションコールが失敗するのは、ディスクの残り容量がなくなったときです。
16H
DE | オープンされていないFCBの先頭アドレス |
FCBのカレントブロック | 読み出すブロック番号 |
A | 00H | ファイルの作成が成功 |
| FFH | ファイルの作成が失敗 |
FCB中のレコードサイズ、カレントレコード、ランダムレコードの各フィールドは、このファンクションコールの実行後に必要に応じて設定しなければなりません。
このファンクションコールが失敗するのは、ファイル名が正しくセットされていないか、ディレクトリに空きがないときです。
17H
DE | オープンされていないFCBの先頭アドレス |
FCB+0 | 旧ファイル名 |
FCB+16 | 新ファイル名 |
A | 00H | ファイル名の変更が成功 |
| FFH | ファイル名の変更が失敗 |
新旧ファイル名に、ワイルドカード文字を使用できます。例えば、旧ファイル名に「????????REL」を、新ファイル名に「????????LIB」を指定すれば、「REL」という拡張子のファイルがすべて、「LIB」という拡張子のファイルに変更されます。
新ファイル名のドライブ番号は無視されます。
18H
なし
MSXには最大8台のディスクドライブが接続できます。「オンラインドライブ」とは、MSXに実際に接続されているドライブを示します。このファンクションコールを実行すると、各ドライブがオンラインであるかどうかを調べ、結果を表3.7のようにHLレジスタに入れて返します。それぞれのビットが1ならば対応するドライブはオンラインであり、0ならば接続されていないことを示します。MSX-DOSのときは、Hレジスタは常に「0」です。
表3.7 ログインベクトル
レジスタ | H | L |
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ドライブ | 常に、0 | H: | G: | F: | E: | D: | C: | B: | A: |
オンライン・オフライン | 各ビットが「1」ならばオンライン、「0」ならばオフライン |
19H
なし
A | デフォルトドライブ番号(A=0、B=1、・・・H=7) |
現在設定されているドライブ番号を獲得します。
1AH
なし
DTAアドレスは、システムリセット時に0080Hに初期化されますが、このファンクションコールによって、任意アドレスに設定し直すことができます。
1BH
A | 1クラスタあたりの論理セクタ数 |
| FFH | 指定ドライブがオフライン |
BC | セクタのサイズ(バイト単位) |
DE | クラスタの総数 |
HL | 未使用クラスタの総数 |
IX | DPBの先頭アドレス |
IY | FATバッファの先頭アドレス |
指定ドライブのディスクの情報を獲得します。ドライブ番号に「0」を指定すると、デフォルトドライブの指定になります。それ以外は、Aドライブなら「1」、Bドライブなら「2」、・・・を指定します。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
21H
DE | オープンされたFCBの先頭アドレス |
FCBのランダムレコード | 読み出すレコード番号 |
A | 00H | 読み出しが成功 |
| 01H | 読み出しが失敗 |
| 読み出しが成功したときは、DTA以降の128バイトに読み込んだレコードをセットします。 |
レコードの大きさは128バイト固定です。
22H
DE | オープンされたFCBの先頭アドレス |
FCBのランダムレコード | 書き込むレコード番号 |
DTA以降の128バイト | 書き込むデータ |
A | 00H | 書き込みが成功 |
| 01H | 書き込みが失敗 |
レコードの大きさは128バイト固定です。
23H
A | 00H | ファイルサイズの獲得が成功 |
| FFH | ファイルサイズの獲得が失敗 |
| 獲得が成功すれば、FCBのランダムレコードフィールドに指定されたファイルの128バイト単位のサイズをセットします。 |
ファイルのサイズは128バイト単位です。200バイトのファイルであれば「2」が、257バイトのファイルであれば「3」が設定されます。
24H
DE | オープンされたFCBの先頭アドレス |
FCBのカレントブロック | 目的のブロック |
FCBのカレントレコード | 目的のレコード |
ランダムレコードフィールドに、指定されたFCBのカレントブロックフィールドとカレントレコードフィールドから計算したカレントレコードポジションを設定します。
26H
DE | オープンされたFCBの先頭アドレス |
FCBのレコードサイズ | 書き込むレコードサイズ |
FCBのランダムレコード | 書き込みを開始するレコード |
HL | 書き込むレコード数 |
DTA以降のメモリ領域 | 書き込むデータ |
A | 00H | 書き込みが成功 |
| 01H | 書き込みが失敗 |
書き込みが終わると、ランダムレコードフィールドの値が自動的に更新されて、最後に書き込んだレコードの次のレコードを指します。1つのレコードの大きさはFCBのレコードサイズフィールドによって1バイトから65535バイトまで任意に設定できます。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
27H
DE | オープンされたFCBの先頭アドレス |
FCBのレコードサイズ | 読み出すレコードサイズ |
FCBのランダムレコード | 読み出しを開始するレコード |
HL | 読み出すレコード数 |
A | 00H | 読み出しが成功 |
| 01H | 読み出しが失敗 |
HL | 実際に読み込んだレコードの個数 |
データの読み込みが終わると、ランダムレコードフィールドの値が自動的に更新されます。このファンクションコール実行後、HLレジスタには実際に読み込んだレコードの総数が設定されます。つまり、指定した数のレコードを読み込み終わる前にファイルの終わりに達してしまったときには、それまでに読み込んだ実際のレコード数がHLレジスタに入ることになります。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
28H
DE | オープンされたFCBの先頭アドレス |
FCBのランダムレコード | 書き込むレコード番号 |
DTA以降の128バイト | 書き込むレコード |
A | 00H | 書き込みが成功 |
| 01H | 書き込みが失敗 |
レコードの大きさは128バイト固定です。
このファンクションコールでは、ファイルサイズより大きなレコード番号が指定されたとき、ファイルの終わりの次のレコードから指定されたレコードの直前までのレコードを「0」で埋めた後、指定されたレコードに書き込みます。「0」で埋める点を除けば、ファンクション22H(ランダムな書き込み)と同じです。
2AH
なし
HL | 年 | (1980〜2079) |
D | 月 | (1〜12) |
E | 日 | (1〜31) |
A | 曜日 | (0=日曜、1=月曜、・・・6=土曜) |
クロックICに設定されている日付のデータを獲得します。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
2BH
HL | 年 | (1980〜2079) |
D | 月 | (1〜12) |
E | 日 | (1〜31) |
A | 00H | 日付の設定が成功 |
| FFH | 日付の設定が失敗 |
クロックICに指定した日付を設定します。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
2CH
なし
クロックICに設定されている時刻のデータを獲得します。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
2DH
A | 00H | 時刻の設定が成功 |
| FFH | 時刻の設定が失敗 |
クロックICに時刻のデータを設定します。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
2EH
E | 00H | ベリファイフラグをリセット |
| 01H | ベリファイフラグをセット |
なし
ベリファイフラグをセットすると、以降のディスクに対する書き込みをベリファイ付きで行います。ベリファイとは、書き込んだあとでその内容をディスクから読み込み、書き込むべき内容と比較して等しいかどうかをチェックする機能です。
ベリファイ機能はオプションであり、ドライブによってはその機能がないものもあります。その場合、ベリファイフラグを設定しても意味はありません。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
2FH
DE | 読み出す論理セクタの番号(複数のときはその先頭の論理セクタ番号) |
H | 読み出す論理セクタの個数 |
L | 読み出すディスクのドライブ番号(A=0、B=1、・・・H=7) |
DTA以降の(論理セクタサイズ×論理セクタの個数)バイトに読み込んだ内容を設定
指定ドライブの指定論理セクタから指定された個数の論理セクタを読み出し、その内容をDTA以降のメモリに設定します。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。
30H
DE | 書き込む論理セクタの番号(複数のときはその先頭の論理セクタ番号) |
H | 書き込む論理セクタの個数 |
L | 書き込むディスクのドライブ番号(A=0、B=1、・・・H=7) |
DTA以降の(論理セクタサイズ×論理セクタの個数)バイトに書き込むデータを設定 |
なし
DTA以降に設定されたデータを指定ドライブの指定論理セクタへ、指定された論理セクタの個数だけ書き込みます。
このファンクションコールはMSX-DOS独自のもので、CP/Mとの互換性はありません。