MSX Datapack wiki化計画

7章 プログラム開発の諸注意の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
{{include unfinished_page}}

,{t},{BSIZE:1 0|SIZE:100%}
,{BSIZE:0}←[[6章 内部ルーチン]]                                                               ,{BSIZE:0|RIGHT}[[3部 MSX-DOS]]                                                                   →

!!7.1 BIOS

!7.1.1 BIOS
 アプリケーションプログラムが入出力を行う時には、必ずBIOSを使って下さい。BIOSを使う目的は、ハードウェアとソフトウェアを分離し、ハードウェアを変更してもソフトウェアをそのまま使えるようにすることです。
 BIOSはROMの0000H番地から始まるジャンプテーブルを通して呼び出されます。ジャンプテーブルの飛び先、つまりBIOSの内容はハードウェアの変更や機能の拡張のために変更されますので、アプリケーションプログラムがそこを直接に(ジャンプテーブルを通さずに)参照してはいけません。MSX2の拡張ROMにも、同様のジャンプテーブルがあり、拡張機能の呼び出しに使われます。

!7.1.2 拡張BIOSコールの方法
 MSXでは、新たに追加されたデバイスの持つドライバールーチン(拡張BIOS)をアプリケーションソフトウェアから使用できます。その方法はデバイスによって異なりますので、詳細については各デバイスの仕様書をご覧下さい。
 以下では、RS-232Cを例にとって、拡張BIOSコールの手順を説明します。
+8000H番地以上に拡張BIOSのエントリーアドレスを入れるためのワークエリア(64バイト)をとる。
+HLレジスタに、1.で取ったワークエリアの先頭アドレスを入れる。
+Bレジスタに、1.で取ったワークエリアが存在するRAMのスロットアドレスを入れる。RAMのスロットアドレスについては、「7.3.5 RAMのあるスロット」参照。
+Dレジスタにデバイス番号、Eレジスタに拡張BIOSのファンクション番号(0)を入れる。
+【EXPBIO(0FFCAH)】をコールする。
+その結果、1.で取ったワークエリアに、以下の順番でデータが入ってくる。
{{svg 図2.33.svg}}
'''図2.33 RETURN情報の形式'''

 ジャンプテーブルのスロットアドレスとは、拡張BIOSを持ったROMの存在するスロットアドレスを、ジャンプテーブルの先頭アドレスとは拡張BIOSへのジャンプテーブルのアドレス(EXBTBL)を指します。例えば、RS-232Cの場合、ポートをOPENする場合には、EXBTBL+6バイトをインタースロットコールします。拡張BIOSの詳細は、各デバイスの拡張BIOSコール仕様書をご覧下さい。
 拡張BIOSコールを指定するデバイスには、RS-232C、MSX-MODEM、MSX-AUDIO、MSX-JEなどがあります。

!7.1.3 拡張BIOSのワークエリア
 拡張BIOSを使うときには、スロットが切り換えられてもCPUがRAMを参照できるように、スタックをC000H番地よりも上位に置いて下さい。
 同様の理由で、RS-232CなどのFCBは8000H番地よりも上位に置いて下さい。
!!7.2 I/Oポート

!7.2.1 I/Oポート
 MSXでは互換性と拡張性を維持するために、ハードウェアについては基本的な使用を決めるにとどめ、ハードウェアの違いをソフトウェアによって吸収するように定めています。したがって、市販を目的としたソフトウェアでは、その内容を問わず決してI/Oポートを直接アクセスしないで下さい。I/Oポートを直接アクセスするプログラムは各システムでの互換性を確実に失ってしまいます。ただし、VDPに関してはこの限りではありません。
 MSXでは互換性と拡張性を維持するために、ハードウェアについては基本的な仕様を決めるにとどめ、ハードウェアの違いをソフトウェアによって吸収するように定めています。したがって、市販を目的としたソフトウェアでは、その内容を問わず決してI/Oポートを直接アクセスしないで下さい。I/Oポートを直接アクセスするプログラムは各システムでの互換性を確実に失ってしまいます。ただし、VDPに関してはこの限りではありません。

!7.2.2 ユーザー定義用I/Oポート
 I/Oの00H〜3FHはユーザー用に解放されています。専用システムの構築などの目的で、ハードウェアを接続するときは、ここに割り当てて下さい。
 40H〜7FHは周辺機器用にリザーブされています。市販を目的としたハードウェアはなるべくメモリマップドI/O方式で本体と接続して下さい。スピード等の問題で、どうしてもI/Oポートに接続することを希望する場合は、あらかじめ株式会社アスキー MSX推進部(連絡先は巻末を参照)までご連絡下さい。当社でI/Oの割り当て調整を行います。
!!7.3 スロット

!7.3.1 拡張スロット
 過去に、
+拡張スロットに差し込まれた場合
+RAMが拡張スロットにある場合
などに、動作しないソフトウェアがいくつかありました。MSX2の多くの機種では本体内部で拡張スロットを使っていますので、拡張スロットでの動作不良は致命的な問題になります。ソフトウェアを発売するまえに、そのソフトウェアが拡張スロットに入れられた場合と、RAMが拡張スロットにある場合について、必ず動作試験を行って下さい。
 特に、FFFFH番地には拡張スロットレジスタが置かれていますので、そこをRAMのつもりで参照してはいけません。拡張スロットで暴走するソフトウェアの多くが、
 LD     SP,0
を行っていました。このようなソフトウェアを作らないようにご注意下さい。

!7.3.2 プログラムのスロットアドレス
 プログラムが1ページと2ページ(4000H番地からBFFFH番地)までの32KバイトのROMに入っている場合には、1ページのROMのINITルーチン(データブックのスロット管理メカニズム参照)が呼び出された時に、2ページがそのROMの続きではなく、別のスロットになっています。1ページのROMの内部で自分がいるスロットのスロットアドレスを調べ、2ページをそのスロットに切り換える必要があります。
 添付のフロッピーディスクにサンプルプログラムが入っています。ファイル名は「WHEREAMI.MAC」です。
 他のプログラムから参照されるような場合にも、同じ方法で求めた自分のスロットアドレスを使用して下さい。
{{svg 図2.34.svg}}
'''図2.34 INITルーチン呼び出し時のスロット状況例'''

!7.3.3 BASICのROMのスロットアドレス
 従来は、「BASICのROMは基本スロットの0、または基本スロットの0を拡張した0-0に置く。」という仕様がありました。しかし、本体外にV9938とROMを増設してMSX2の機能を持たせる場合には、BASICのROMが他のスロットにあります。また、MSX2の拡張ROMが入っているスロットは、機種によって異なります。
 ゆえに、下記のシステムワークエリアの内容を参照して、BASICのROMのスロットアドレスを調べて下さい。
 DOSからBIOSを呼ぶ場合にこの方法を使えます(「[5部 スロットとカートリッジ]」参照)。
'''表2.22 BASICのROMのスロットアドレス'''
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0}
,アドレス,ラベル,内容
,{c},{BSIZE:0},{BSIZE:0},{BSIZE:0}
,FCC1H,EXPTBL,MAIN-ROMのスロットアドレス
,FAF8H,EXBRSA,SUB-ROMのスロットアドレス

,{SIZE:100|CENTER}注意
BASIC 1.0では、EXBRSAの内容は00Hです。

!7.3.4 スロット切り替え時の注意
 インタースロットコールを行うと、IX、IYおよび裏レジスタの内容が破壊され、リターン時に割り込みが禁止されています。
{{svg 図2.35.svg}}
'''図2.35 インタースロットコール時の割り込み'''

 Z80の特性により、MSX2でもごく希なケースとして、DI状態でリターンすることがあります。割り込み状態がEIの必要があるプログラムでは、インタースロットコール直後にEIすることをおすすめします。

!7.3.5 RAMのあるスロット
 フロッピーディスクドライブを実装しているシステムでは、各ページのRAMのあるスロットを以下のワークエリアに保存しています。フロッピーディスクドライブが実装されたMSXで、RAMの実装されたスロットアドレスを知りたい場合には、必ずこのワークエリアを参照して下さい。
 例えば、ページ1のRAMをデータエリアとして使用するためにすろっとを切り換えるといった場合に、このワークエリアの値を参照します。
 例えば、ページ1のRAMをデータエリアとして使用するためにスロットを切り換えるといった場合に、このワークエリアの値を参照します。
'''表2.23 RAMのスロットアドレスを保存したワークエリア'''
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 0|SIZE:120},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:200}
,RAMのスロット,ラベル,アドレス
,{c},{BSIZE:0},{BSIZE:0},{BSIZE:0}
,ページ0,RAMAD0,0F341H
,ページ1,RAMAD1,0F342H
,ページ2,RAMAD2,0F343H
,ページ3,RAMAD3,0F344H

各ビットは以下の意味を持ちます。
{{svg 図2.36.svg}}
'''図2.36 RAMD0〜3のビットの意味'''

 フロッピーディスクドライブを実装しないシステムの場合は、RAMのあるスロットを自分で捜さなければなりません。添付のフロッピーディスクに、「RAMSRCH.MAC」というなまえのサンプルプログラムが入っています。
 フロッピーディスクドライブを実装しないシステムの場合は、RAMのあるスロットを自分で捜さなければなりません。添付のフロッピーディスクに、「RAMSRCH.MAC」という名前のサンプルプログラムが入っています。
 このプログラムはBASICプログラムからDEFUSR命令で呼ばれるようになっています。フロッピーディスクドライブを実装した機種では、上記のワークエリア【RAMAD0(0F341H)】〜【RAMAD3(0F344H)】を参照し、このサンプルプログラムによるRAMサーチは行わないで下さい。さもなければ、システムに矛盾をきたし、暴走の原因となる場合があります。

!!7.4 ワークエリア
!7.4.1 BASICのワークエリア
 メインRAMのF380H番地からFFFEH番地までは、BIOSとBASICインタープリタのワークエリアですから、不用意に使わないで下さい。ワークエリア内の使われていない場所は、将来の機能拡張の為に予約されています。
 メインRAMのF380H番地からFFFEH番地までは、BIOSとBASICインタープリタのワークエリアですから、不用意に使わないで下さい。ワークエリア内の使われていない場所は、将来の機能拡張のために予約されています。

!7.4.2 ユーザーエリア
 BASIC、Disk BASICの環境で、ユーザーの使用できるRAMエリアは8000H番地〜0FC4AHと0FC4BHの内容が示すアドレスです。0FC4AHのラベル名はHIMEMです。
 MSX-DOSでは、CP/Mと同じく、100H番地〜6、7H番地の内容が示すアドレスまでがTPAとなります。
 アプリケーションプログラムは必ずHIMEM(DOSの場合は6、7H番地)を確かめて、最悪の場合でも暴走しないように対処する必要があります。対処の方法としては、
+ワークエリアをリロケータブルにする。
+ワークエリアをBOTTOMから確保する。
+ドライブの数を減らすように指示してから停止する。
などがあります。

!7.4.3 RAMとスタックポインタの初期化
 電源投入時のRAMの内容は不定で、システムのワークエリア以外の領域は初期化されません。自分のワークエリアを初期化することは、アプリケーションプログラムの責任です。
 RAMの内容が00Hであることを期待しているために、特定の本体との組み合わせでしか動かないソフトウェアがあり、問題になっています。
 また、ROMカートリッジのINITルーチンが呼ばれた時のスタックポインタの値は不定で、ディスクインターフェイスが先に初期化されたような場合にはそうでない場合よりもスタックポインタの値が小さくなっています。このため、スタックポインタを初期化しないプログラムが暴走するという問題が起きました。INITルーチンで起動し、そのまま走り続けるプログラムは必ずスタックポインタを初期化して下さい。

!7.4.4 デバイスドライバなどのワークエリア
 デバイスドライバやBASICから呼ばれるサブルーチンのように、他のプログラムと同様にメモリに存在するプログラムは、ワークエリアの確保に特に注意を要します。
 カートリッジのINITルーチンがHIMEM(またはBOTTOM)を書き換え、古いHIMEMと新しいHIMEMの間を自分のワークエリアとして予約します。そのワークエリアのアドレスをSLTWRKというスロット別に割り当てられた2バイトの領域に記録します。
{{svg 図2.37.svg}}
'''図2.37 デバイスドライバのワークエリア'''

!7.4.5 フック
 例えば、RS-232Cカートリッジが割り込み処理のためにフックを書き替えたとします。次のカートリッジが同じフックを書き替えると、RS-232Cカートリッジは割り込みフックを使えなくなります。
 このような事を防ぐためにフックを書き替える場合には、以前のフックの内容(例では、RS-232Cカートリッジの割り込み処理ルーチンへのインタースロットコール命令)を記憶します。そして、自分がフックで呼ばれたら以前のフックの内容を呼び出し、そのフックを使おうとしているカートリッジに制御が渡るようにして下さい。
{{svg 図2.38.svg}}
'''図2.38 フック'''

!!7.5 VDP
!7.5.1 VDPのI/Oアドレス
 MAIN ROMの6番地と7番地にはVDPのリードアドレスとライトアドレスが書き込まれています。I/Oポートを使ってVDPを直接アクセスする場合は、ROMの内容からI/Oポートのアドレスを調べ、そのI/Oアドレスをアクセスして下さい。TMS9918を使っている機種(MSX1)ではVDPが98H番地に置かれていましたので、その番地を直接参照しても実害はありませんのでしたが、V9938を外付けしてMSX2に拡張したハードウェア(MSX2アダプター)の場合にはVDPのアドレスが変わりますので、必ず以上の事を守って下さい。
'''表2.24 VDPのI/Oアドレス'''
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 0|SIZE:200},{BSIZE:1 0|SIZE:300}
,VDPのポート,I/Oアドレス
,{c},{BSIZE:0},{BSIZE:0}
,データリード    ,MAIN-ROMの6番地の内容
,データライト    ,MAIN-ROMの7番地の内容
,ステータスリード,データリードアドレス+1
,コマンドライト  ,データライトアドレス+1
,パレットライト  ,データリードアドレス+2
,インダイレクトアクセス,データライトアドレス+3

!7.5.2 レジスタの保存
 VDPのいくつかのレジスタは書き込み専用であり、直接には現在のレジスタのに亜用を知ることができません。そこで、システムワークエリアの【RG0SAV(0F3DFH)】から【RG7SAV(0F3E6H)】と【RG8SAV(0F3E7H)】から【RG23SA(0FFF6H)】(RG8SAV以降はV9938仕様機種のみ)に、レジスタの内容を保存してあります。BIOSを通さずにVDPのレジスタを書き替える場合には、これらのワークエリアの内容も書き換えて下さい。特に、機械語プログラムからBASICやDOSに制御が戻った時にレジスタの内容とワークエリアの内容が異なると、画面表示が正しく行われません。
 VDPのいくつかのレジスタは書き込み専用であり、直接には現在のレジスタの内容を知る事ができません。そこで、システムワークエリアの【RG0SAV(0F3DFH)】から【RG7SAV(0F3E6H)】と【RG8SAV(0F3E7H)】から【RG23SA(0FFF6H)】(RG8SAV以降はV9938使用機種のみ)に、レジスタの内容を保存してあります。BIOSを通さずにVDPのレジスタを書き替える場合には、これらのワークエリアの内容も書き替えて下さい。特に、機械語プログラムからBASICやDOSに制御が戻った時にレジスタの内容とワークエリアの内容が異なると、画面表示が正しく行われません。
 また、VDPのレジスタの一部のビットを書き替える場合には、ワークエリアからレジスタの内容を読んで、必要に応じてビットを変え、そのデータをレジスタとワークエリアの両方に書き込んで下さい。

!7.5.3 VRAMの初期化
 アプリケーションプログラムが動き始める時のVRAMの内容は不定です。アプリケーションプログラムは、必ずVRAMを初期化して下さい。
 VRAMを初期化していないために、ハードウェアの特性でVRAMの内容が0になっている機種でのみ画面が正しく表示されるというソフトウェアがありました。

!7.5.4 VRAMの容量
 FAFCH番地のビット2とビット1の内容で、VRAMの容量が判ります。
{{svg 図2.39.svg}}
'''図2.39 【MODE(0FAFCH)】のビット'''
!!7.6 キー入力
!7.6.1 キー入力の方法
 BIOSによるキー入力に2つの方法があります。目的に応じて使い分けて下さい。特に、ヨーロッパ用などの異なる種類のキーボードに対応するソフトウェアを作る場合には注意が必要です。
+SNSMATルーチンを使って、リアルタイムにキーの物理的な状態を得ます。
+CHSNSとCHGETを使い、バッファリングされた文字コードを得ます。また、KILBUFルーチンでキーバッファの内容を捨てることができます。この方法では、VDPによるタイマ割り込み時にキースキャンが行われますので、割り込みが許可されている必要があります。

!7.6.2 キークリック
 システムワークエリアの【CLIKSW(0F3DBH)】という1バイトの内容が0でなければキー入力時にクリック音が発生し、0であればクリック音が発生しません。
!!7.7 プリンタ
!7.7.1 MSX用でないプリンタへの対応
 【NTMSXP(0F416H)】というワークエリアの内容が0でなければ、MSX用でないプリンタのためにBIOSが文字を変換します。その場合、ひらがながカタカナに変換され(日本語版のみ)、グラフィック文字が空白に変換されます。
!7.7.2 RAWモード印字
 【RAWPRT(0F418H)】の内容が0でなければ、RAWモード印字となり、タブ(09H)の空白への変換と前項の文字の変換が行われません。ビットイメージプリントを行うときには、必ずRAWモードを設定して下さい。
 【RAWPRT(0F418H)】の内容が0でなければ、RAWモード印字となり、タブ(09H)の空白への変換と前項の文字の変換が行われません。ビットイメージプリントを行う時には、必ずRAWモードを設定して下さい。
 だたし、RAWモード印字はBIOSのOUTDO(0018H/MAIN)を使用しているプログラムのみ有効で、LPTOUT(00A5H/MAIN)では無効です。したがって、BASICのPRINT命令などではRAWモード印字されますが、MSX-DOSのプリンタ出力(ファンクションコール05H)などでは何も起こりません。
 MSX2+やMSX-DOS2の漢字BASICでプリンタにエスケープシーケンスなどを送る場合も、RAWモード印字にして下さい。
!!7.8 BASICの種類
!7.8.1 BASICのバージョン番号
 アプリケーションプログラムがBASICのバージョン番号を知るためには、以下の方法を使います。

 MAIN ROMの2DH番地にBASICのバージョン番号が入っています。MSX BASIC1.0では2DH番地の内容が00H、MSX BASIC 2.0では01H、MSX BASIC 3.0では02Hです。

!7.8.2 インターナショナルMSX
 MSXは世界各国で使われており、その種類は主なもので10を越えています。下記の項目が、国によって大きく異なります。
+キーボード配列
+文字セット
+PRINT USINGの書式
+タイマ割り込み周波数
IDバイトというROM内の情報を読むと本体の種類が分かり、各国のMSXに対応できます。
{{svg 図2.40.svg}}
'''図2.40 IDバイトの内容'''

'''表2.25 国別のMSX仕様'''
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 1 1 0|SIZE:100},{BSIZE:1 0 1 1|SIZE:100},{BSIZE:1 0 1 1|SIZE:100},{BSIZE:1 0 1 1|SIZE:100},{BSIZE:1 0 1 1|SIZE:130},{BSIZE:1 0 1 1|SIZE:120},{BSIZE:1 0 1 1|SIZE:120}
,国名{ROWS:2},TVセット{ROWS:2},日付{{br}}フォーマット{ROWS:2},初期画面{{br}}モード{ROWS:2},PRINT USING{COLS:3|CENTER}
,    ,        ,                 ,               ,文字列の長さ指定,文字の置き換え,通貨シンボル
,{c},{BSIZE:0 1 0 0},{BSIZE:0 0 0 1},{BSIZE:0 0 0 1},{BSIZE:0 0 0 1},{BSIZE:0 0 0 1},{BSIZE:0 0 0 1},{BSIZE:0 0 0 1}
,日本               ,NTSC(60Hz) ,年/月/日,SCREEN 1,%,@,\(エン)
,イギリス           ,PAL(50Hz)  ,日/月/年,SCREEN 0,%,&,£(ポンド)
,インター{{br}}ナショナル,PAL(50Hz)  ,月/日/年,SCREEN 0,%,&,$(ドル)
,アメリカ           ,NTSC(60Hz) ,月/日/年,SCREEN 0,%,&,$(ドル)
,フランス           ,SECAM(50Hz),日/月/年,SCREEN 0,%,&,$(ドル)
,ドイツ             ,PAL(50Hz)  ,日/月/年,SCREEN 0,%,&,$(ドル)
,ソビエト           ,NTSC(60Hz) ,月/日/年,SCREEN 0,%,&,$(ドル)
,スペイン           ,PAL(50Hz)  ,月/日/年,SCREEN 0,%,&,$(ドル)

!!7.9 ディスク
 フロッピーディスクが使用するワークエリアの情報は、原則的には公開していません。この章で公開しているアドレスと使用法以外の目的で、ワークエリアを参照したり、書き換えたりすると動作は保証できませんので、十分ご注意下さい。また、この章で紹介しているワークエリア以外は、将来のバージョンアップの際に、アドレスや使用法が変わる可能性があります。

!7.9.1 ディスクを使わない方法
 リセット(または電源投入)してからビープ音が鳴るまでシフトキーを押していると、ディスクインターフェイスが無視され、ROM BASICが起動します。ディスク内蔵機でディスクとワークエリアが衝突するソフトウェアを動かす婆には、この方法を使って下さい。
 リセット(または電源投入)してからビープ音が鳴るまでシフトキーを押していると、ディスクインターフェイスが無視され、ROM BASICが起動します。ディスク内蔵機でディスクとワークエリアが衝突するソフトウェアを動かす場合には、この方法を使って下さい。
 同様に、コントロールキーを押していると、2ドライブシミュレーション機能(1ドライブでソフト的に2ドライブをシミュレートする機能)が無効になり、ディスクワークエリアが少し小さくなります。
 アプリケーションプログラムから見てドライブが2台接続されているシステムで、それが2ドライブシミュレーション機能なのか、それとも物理的にディスクが接続されているかを知ることはできません。また、ソフトウェアから2ドライブシミュレーション機能を無効にすることも不可能です。

!7.9.2 ドライブの有無と数を知る方法
 【H.PHYDIO(0FFA7H)】というフックの内容を読んで下さい。そこにRET命令が書かれていれば、ディスクは接続されていません。RETでなければ、ディスクが接続されています。
 ディスクが存在する場合は、DOSのシステムコール(BDOSコール)の18H(ログインベクトルの獲得)を使用して下さい。DOSのシステムコールはDisk BASICからも利用できます。詳しくは「第3部 4章 システムコール」をご覧下さい。

!7.9.3 エラー処理
 MSX-DOSには、ディスク入出力のエラーを検知して適切な回復手続きを行う機能が用意されています。

'''1.MSX-DOSの標準エラー処理手順'''
 システムコールのディスク入出力でエラーが発生すると、エラー処理ルーチンが呼ばれます。標準処理手順では、エラーメッセージと「Abort Retry Ignore?」というプロンプトが表示されて、キー入力を待ちます。ここで、A、R、Iを入力しますが、これらはそれぞれ以下のような意味があります。

,{t},{BSIZE:0}
,{c},{BSIZE:0|SIZE:80},{BSIZE:0}
,A,"システムのウォームブートが起こり、DOSのコマンド入力状態になります。"
,R,"処理を再び試みます。"
,I,"システムコールをキャンセルして、アプリケーションには正常終了を返します。"
{{svg 図2.41.svg}}
'''図2.41 MSX-DOSの標準エラー処理手順'''

'''2.Disk BASICの標準エラー処理'''
 Disk BASICの環境でディスクエラーが起こった時には、エラーメッセージを表示して、BASICの入力待ち状態になります。

'''3.アプリケーションプログラムがエラーを処理する方法'''
 【DISKVE(0F323H)】は、ディスクエラー処理ルーチンへのポインタへのポインタ(エラー処理ルーチンの開始アドレスを記憶してあるアドレス)です。そこを書き替える事により、エラー発生時にアプリケーションプログラム内のエラー処理ルーチンを呼び出すことができます。
図2.41の*1は、エラー処理ルーチンの入り口を示します。ここで、

 Aレジスタにはエラーを起こしたドライブの番号(A=0、B=1...H=7)
 Cレジスタにはエラーの種類

が入っています。Cレジスタの各ビットの意味は以下の通りです。例えば、書き込み時に、「NOT READY」エラーが起こると、Cレジスタの内容は03Hになります。

'''表2.26 エラーの種類'''
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 0|SIZE:120},{BSIZE:1 0}
,bit0(LSB),エラー時の状態
,{c},{BSIZE:0},{BSIZE:0}
,0,読み込み時
,1,書き込み時

(MSB)
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0|SIZE:80},{BSIZE:1 0}
,bit7,bit6,bit5,bit4,bit3,bit2,bit1,エラーの種類
,{c},{BSIZE:0},{BSIZE:0},{BSIZE:0},{BSIZE:0},{BSIZE:0},{BSIZE:0},{BSIZE:0},{BSIZE:0}
,1,0,0,0,0,0,0,bad FAT
,0,0,0,0,0,0,0,write protect
,0,0,0,0,0,0,1,not ready
,0,0,0,0,0,1,0,CRC error
,0,0,0,0,0,1,1,seek error
,0,0,0,0,1,0,0,record not found
,0,0,0,0,1,0,1,write fault
,0,0,0,0,1,1,0,other error

 図2.41の*2は、エラー処理ルーチンの出口を示します。ここからDOSの標準エラー処理に戻る場合には、Cレジスターの内容で処理を指定し、リターンします。ここで、AF、B、DE、HLレジスターには何が入っていても構いません。
,{t},{BSIZE:2 0}
,{c},{BSIZE:1 0|SIZE:120},{BSIZE:1 0}
,bit0(LSB),エラー時の状態
,Cレジスタ,事後処理
,{c},{BSIZE:0},{BSIZE:0}
,2,abort(処理を中断)
,1,retry(入出力を再度試みる)
,0,ignore(エラーを無視して先へ進む)

 以下の場合には、エラー処理ルーチンは必ず2(abort)または1(retry)を返すようにしてください。さもなければ、ディスクが壊れる可能性があります。
 以下の場合には、エラー処理ルーチンは必ず2(abort)または1(retry)を返すようにしてください。さもなければ、ディスクが壊れることがあります。
+エラーコードのビット7が1(bad FAT)だった場合
+エラーコードが1010(Unsupported media type)だった場合
 Disk BASICの環境下では、エラーが発生したときには、Disk ROMがイネーブルされており、スロット切り替えは行われません。したがって、ページ1にあるディスクエラー処理ルーチンは制御を受け取ることができません。しかし、MSX-DOSの環境では、ページ1のRAMがイネーブルされてから、コントロールが渡ってきます。
 DOSから返って来るエラーは「directory entry not found」や「no more free sectors to write」のようなロジカルエラーです。そして、ディスクエラーハンドラが返すのはハードウェアのエラーです。この2つは異なります。
 DOSから返ってくるエラーは「directory entry not found」や「no more free sectors to write」のようなロジカルエラーです。そして、ディスクエラーハンドラが返すのはハードウェアのエラーです。この2つは異なります。
 MSX-DOS上で動作するアプリケーションプログラムが特別なエラー処理を行いたい場合は、下記のようにします。
+DISKVEの内容をセーブする。
+DISKVEにエラー処理ルーチンへのポインタへのポインタを設定する。
+01H番地と02H番地の内容をセーブする。
+1.、3.でセーブした値をRESTOREするルーチンへのエントリを01H番地、02H番地に書く。1.、3.の値をRESTOREするルーチンとは、以下を実行するもの。
**DISKVEを元の値に戻す
**01H番地と02H番地を元の値に戻す
**0H番地へジャンプする
+システムコールの実行前に、スタックポインタを保存する。
+システムコールを行う。
+エラー処理ルーチンが呼び出されたら、スタックポインタを元に戻し、適当な処理を続ける。
 前述の【DISKVE】の内容は、システムのコールドスタート時、およびDOSとBASICの切り換え時に初期化されます。このため、あるプログラムが【DISKVE】の内容を書き換えたまま終了し、DOSのコマンドや次のプログラムがエラーを起こすと暴走します。
 故に、DISKVEを書き替えたプログラムはそのままコマンドレベルに戻らずに、01H番地と02H番地の内容(WOOM BOOT)を書き替えて、[CTRL]+[C]でプログラムが止まらないようにして下さい。

!7.9.4 BDOSコール
 MSX Disk BASICの環境下でも、DOSファンクションコールが可能です。F37DHがDisk BASICのばあいでのファンクションコールエントリで、MSX-DOSの場合の5番地コールに相当する機能を提供します。詳しくは「第3部4章 システムコール」を参照して下さい。
 MSX Disk BASICの環境下でも、DOSファンクションコールが可能です。F37DHがDisk BASICの場合でのファンクションコールエントリで、MSX-DOSの場合の5番地コールに相当する機能を提供します。詳しくは「第3部4章 システムコール」を参照して下さい。
!7.9.5 FDC
 MSXではFDCの種類や割り当てられるアドレスは定められていません。したがって、いかなる理由があろうとも、アプリケーションプログラムは直接FDCをアクセスしてはいけません。ディスクのアクセスには必ずファンクションコール(BDOSコール)を使用してください。
!7.9.6 DISK ROMが入っているスロットを知る方法
 ワークエリアのFB21HからFB28Hまでのドライブテーブルという領域に、ディスクインターフェイスに関する情報が記録されています。書くカートリッジに2バイトが割り当てられており、その内容は以下のようになっています。カートリッジが3個以下であればあいているテーブルに00Hが入ります。
 ワークエリアのFB21HからFB28Hまでのドライブテーブルという領域に、ディスクインターフェイスに関する情報が記録されています。各カートリッジに2バイトが割り当てられており、その内容は以下のようになっています。カートリッジが3個以下であれば空いているテーブルに00Hが入ります。
{{svg 図2.42.svg}}
'''図2.42 DISK ROMの情報'''
!7.9.7 FDDのモーターを止める方法
 以下の方法で、アプリケーションプログラムがFDDのモーターを止めることができます。ただし、ディスクドライブによっては、モーターOFFのエントリを持っていないものがあるので、そのエントリがあるかどうかを事前にチェックしてください。また、ディスクドライブによっては、何もしないでリターンするものもあります。
 なお、このルーチンはアスキーから発売しているハードディスクインターフェイスで実行すると、シャットダウン(ハードディスクのヘッドを安全地帯へ待避させること)の効果があります。ユーザープログラムがシャットダウンを行うときは、ユーザープログラムから、@_SHUTDOWNをコールして下さい。

'''リスト2.15 FDDのモーターOFF'''
 ;
 ;      moter off Subroutine
 ;      motor off Subroutine
 ;
        .z80
        entry               @_SHUTDOWN
 ;
 rdslt           equ      000ch
 calslt          equ      001ch
 motor_off_entry equ      4029h
 master_slot     equ      0f348h
 ;
 @_SHUTDOWN:
        ld       a,(master_slot)        ; moter off entry present?
        ld       a,(master_slot)        ; motor off entry present?
        ld       hl,motor_off_entry
        call     rdslt
        and      a
        ret      z                      ; no, no way....
        ld       iy,(master_slot-1)     ; we have it! call it now
        ld       ix,motor_off_entry
        jp       calslt
 ;
 ; 注意
 ;      マスターカートリッジの'motore_off_entry'はシステムにつながっている
 ;      マスターカートリッジの'motor_off_entry'はシステムにつながっている
 ;      すべてのディスクドライブを調べ、モーターを止めます。
 ;      しかし、旧版のマスターカートリッジはモーターを止めることができません。
 ;      この場合は、モーターを止める手だてはありません。
 ;      たとえ、マスターカートリッジがその機能を持っていても、
 ;      スレーブカートリッジがその機能を持っていなければ、
 ;      スレーブカートリッジが管理するディスクドライブのモーターは止まりません。
 ;
        end

Cコンパイラからは、_shutdown();でコールできます。
Cコンパイラのテストプログラムです。
 #include <stdio.h>
 VOID _shutdown();
 main()
 {
      _shutdown();
 }
!7.9.8 マスターカートリッジのスロットアドレス
 ディスク機能の大部分を受け持つディスクカートリッジは、「マスターカートリッジ」と呼びます。マスターカートリッジのスロットアドレスは、【MASTER_SLOT(0F348H)】に保存されています。
!7.9.9 ディスク交換
 2ドライブシミュレーション機能が働いているときは、別のドライブにアクセスすると、
 Insert disk for drive x:
 and strike a key when ready
というメッセージが表示されます。そのため、グラフィックを使ったアプリケーションソフトウェアでは不都合が生じます。
 アプリケーションソフトウェアが、自分でディスクの交換メッセージを出すためには、【H.PROMPT(0F24FH,3)】がコールされたときは、Aレジスタにドライブ名(A、B・・・)がキャラクタで入っています。また、スタックトップが標準プロンプトルーチンへのリターンアドレスで、スタックトップ+2がシステムへのリターンアドレスになっています。したがって、標準プロンプトルーチンをバイパスするためには、リターンする前にスタックを1レベル捨てなければなりません。なお、レジスタを保存する必要はありません。
 アプリケーションソフトウェアが、自分でディスクの交換メッセージを出すためには、【H.PROMPT(0F24FH,3)】をアプリケーションプログラム側のディスク交換ルーチンへのジャンプ命令に書き換えます。
 【H.PROMPT(0F24FH,3)】がコールされたときは、Aレジスタにドライブ名(A、B・・・)がキャラクタで入っています。また、スタックトップが標準プロンプトルーチンへのリターンアドレスで、スタックトップ+2がシステムへのリターンアドレスになっています。したがって、標準プロンプトルーチンをバイパスするためには、リターンする前にスタックを1レベル捨てなければなりません。なお、レジスタを保存する必要はありません。

,{SIZE:100|CENTER}注意
交換ルーチンはページ1には置けません。
交換ルーチンからは、アプリケーションプログラムにジャンプしてはいけません。かならずリターンして下さい。
!!7.10 便利な機能
!7.10.1 エスケープシーケンス
 MSXには別表のようなエスケープシーケンス機能があります。この機能はBASICのPRINT文、BIOSおよびBDOSコールのコンソール出力で利用できます。シーケンスの機能は、DEC製VT52ターミナルおよびヒースきっと製H19ターミナルのサブセットになっています。
 MSXには別表のようなエスケープシーケンス機能があります。この機能はBASICのPRINT文、BIOSおよびBDOSコールのコンソール出力で利用できます。シーケンスの機能は、DEC製VT52ターミナルおよびヒースキット製H19ターミナルのサブセットになっています。
!7.10.2 BASICに戻る方法
 BASIC ROMのスロットをイネーブルした後、MAIN ROMの409BH番地へジャンプして下さい。BASICのワークエリアが壊されていなければ、BASICのコマンド入力状態になり、OK(MSX2でプロンプトの設定を行っていればその文字列)が表示されます。ジャンプするときのレジスタやスタックの内容は一切無視されます。
 また、内部ルーチンのNEWSTT(「4.4 BASICの内部ルーチン」参照)で次の命令を実行しても、BASICに戻ることができます。
{{svg 図2.43.svg}}
'''図2.43 ウォームスタートのためのNEWSTTの設定''' 
!7.10.3 オートスタート
 単純なゲームカートリッジ等では、ROMのヘッダのINITの場所にプログラムの実行開始アドレスを書くことでそのプログラムを実行できます。しかし、この方法を使うと他のカートリッジの初期設定が行われないため、ディスク等を使えなくなります。
 ROMカートリッジのソフトウェアでディスクを使う場合は、カートリッジのINITルーチン実行時に、起動させたいプログラムへのインタースロットコール命令を【H.STKE(0FEDAH)】というフックに書き、リターン命令でシステムへ戻って下さい。すると、全てのカートリッジの初期設定が終わり、ディスクがあればDisk BASICの環境が整ってから、そのフックがコールされ、目的のプログラムを起動できます。
 この方法は、ディスクがない場合でも有効です。

,{t},{BSIZE:1 0|SIZE:100%}
,{BSIZE:0}←[[6章 内部ルーチン]]                                                               ,{BSIZE:0|RIGHT}[[3部 MSX-DOS]]                                                                   →