Image: 続: 富士通FMシリーズの特異なブートセクタ

注意:長文です。

前の記事→ 富士通FMシリーズの特異なブートセクタ (IPL) - Diary on wind

私がこの記事を書いたとき、1つの大きな見落としと2つの大誤解に気付いていなかった。見落としというのは、

  1. FMRフォーマットのフロッピーディスクはPC-98で読めるのか?

という疑問。誤解とは、

  1. BPB (BIOS parameter block) はディスク上に記録される、ディスクの内部構造を表すデータである。(これは必ずしも間違いではないが、本来はMS-DOS内部に持っているデータを指す。)
  2. MS-DOSの標準的なフォーマットでは、先頭セクターにジャンプ命令やBPBを配置してから起動用プログラム(ブートコード)を配置する必要がある。

という表面的な認識を深く掘り下げないまま、思考ベースに据えてしまったこと。知ったかぶりと浅はかな考えで記事を書いた結果、有識者に恥をさらしたことになった。何ともみっともないことだ。とはいえ、これを機にいろいろ調べてみた結果、面白いことが分かってきた。

この記事の要約(結論を知りたい人のために)

  1. FMRフォーマットのディスクはPC-98で普通に読み書きできる。
  2. PC/AT互換機において、FMRフォーマットはPC-98の1.23MBフォーマットとほぼ同等の扱いとなる。ただし、Windows 98では先頭の’IPLx’署名がJMP命令で上書きされる。
  3. MS-DOSではブートセクタにBPBがなくてもFATさえ正しく記録されていれば読み書きできた。しかし、WindowsではBPBが正しく記録されていることがFATを認識するための必須条件になった。
  4. 富士通がMS-DOS標準のフォーマットを無視したというのは語弊がある。初期のMS-DOSではディスクフォーマットの構造は厳格に規定されたものではなく、後年に今の形が標準になった。
  5. MS-DOSやWindowsに関する様々な制限や仕様によって、FMRのブートセクタが独特の構造を取っていたことは世間で大きな問題にはならなかった。

前回の話を整理する。通常、PC/AT互換機やNEC PC-98でフォーマットされたフロッピーディスクは、最初のセクターがMS-DOSの起動ファイルを読み込むためのプログラムが記録されたブートセクターとなっており、その第1バイトから第3バイトには同じセクター内の起動用コードへジャンプする命令が記録されている。ところが、FMRやFM TOWNSではこの部分に”IPLx”(xは1から5の数字で、対応する機種によって分けている)という文字列がASCIIコードで記録されており、BIOSはこの署名を確認して直接起動用コードへジャンプする。これは、同じFMRシリーズの中でも機種によってアーキテクチャーに違いがあり、その起動用コードが誤った機種で実行されないようにする狙いがあると考えられた。このディスクフォーマットを以下「FMRフォーマット」として述べる。

FMRフォーマットのフロッピーディスクはPC-98で読める

※以下、PC-98での記述については実機で調べたわけではなく、エミュレーター (Anex98, T98-Next)上での調査なので、実際と異なる可能性がある。

当時の日本においてPCといえばPC-98のことを指す。いくら富士通がメインフレーム市場で善戦していたと言っても、ある会社内のパソコンを全て富士通で統一している所なんてそう多くない。PC-98と同居しているところは少なからずあっただろう。そして、日本の標準機であるPC-98とフロッピーディスクでデータを交換できないとなれば、この問題はとっくに炎上してもおかしくない。しかし、実際はそうなっていないどころか、ほとんど問題と見られていない節がある。そしてよく調べてみると、これは単にFMRユーザーの規模が限定的だったというわけではなく、そうなって当然の成り行きがあった。

結論から言えば、PC-98においてFMRフォーマットのフロッピーディスクは読める。と言うより、ブートセクターの先頭バイトはジャンプ命令や”IPLx”でなくても問題ない。それどころか、BPBがなくても、さらにブートセクターの中身がまっさらでも、FATさえ正しければ読める。

実はこれはPC/AT互換機のMS-DOSについてもほぼ同じことを言えるのだが、それについては後述する。

BPBは必ずしもフロッピーディスク上に記録する必要がなかった

最初はそんなまさかと思った。MS-DOSがフロッピーディスクを認識する上でBPB (BIOS Parameter Block) の記録は必要だと思っていた。しかし、MS-DOSに関する古い技術書を掘り起こして読んでいくうちに、まずBPBに対する自分の認識に誤りがあることに気が付いた。

BPBとは、MS-DOSにおいてIO.SYSやデバイスドライバが持っている、セクタ長やFATの数などのディスクの仕様を記録したテーブルのことである。MS-DOSはこのBPBを元に各ドライブ (A:, B:, C:, …) ごとにDPB (Device Parameter Block) を生成する。MS-DOSにおいてドライブの仕様を決めるBPBはIO.SYS内部で生成されるものであり、IO.SYSの開発はPCベンダーに任されているので、BPBの生成過程というのはMS-DOSというOSで一様に決まっているものではない。要するに、BPBをディスクから読み取るものがあれば、予め「決め打ち」の値を用意しているものがあってもおかしくはない。

さらに、私の中での常識を覆す衝撃的な事実が分かった。1986年まで日本におけるマイクロソフト製品の代理店であったアスキーが出版していたアスキー出版局(編)『標準MS-DOSハンドブック』(1984年)によれば、ブートセクタ(予約領域)は「なくてもよい」というのだ。

Image: MS-DOSで扱うディスクの領域

1984年というとMS-DOS関連の文献としては最初期のものだ。出所がアスキーであることから、この曖昧な仕様が実際に当時の米マイクロソフト社がメーカーに伝えていたものだった可能性は否定できない。もしそうなら、富士通がブートセクタをいかに扱おうとこの構造さえ保っていれば、その時点においては「MS-DOSの仕様内」に収まっていたことになる。

また、BPBが必須ではなかったという事実はNEC公式のMS-DOSに関する技術解説書によっても裏付けられることになった。以下、日本電気(株)『MS-DOS 3.3C プログラマーズリファレンスマニュアル Vol.1』(1990年) p.327より。

(異なるメディアのタイプを区別する)最善の方法は、ブートセクタに完全なメディアディスクリプタテーブルを書き、それをメディアの識別に使用することです。NON FAT IDビットをセットしないドライバを持つシステムの将来のMS-DOSのバージョンに対する互換性を保証するために、FORMATのプロセス中にFAT IDバイトを書き込むことも必要です。

今後、さまざまなディスクフォーマットをサポートするための柔軟性を高めるためには、特定の種類のメディアについてのBPBに関する情報を、ブートセクタに保存しておくことが望ましいと言えます。このようなブートセクタのフォーマットを、次に示します(引用者注:ブートセクタの構造を説明する図が続く。)

これはデバイスドライバの開発者向けに書かれている文章だが、この前後はマイクロソフトが書いた英文を翻訳しているのか、分かりにくい文章になっている。私の解釈で述べると、古いMS-DOS (V2.0より前) ではFATの先頭に書かれたFAT IDからディスクの諸元を特定していたが、FAT IDで判別する方法は将来のディスクフォーマットに柔軟に対応できないので、今後はブートセクタにBPBを配置してその情報を利用することが望ましい。ただ、FAT IDを利用する古いドライバをサポートするためにFAT IDも書いておくと良い、ということ。

この2つの記述を総合すると、ディスク先頭のジャンプ命令から始まるブートセクタの構造というのは元々MS-DOS標準の仕様として存在したのではなく、後から推奨仕様として加えられたものだったというように読み取れる。ところが、マイクロソフトがgithubに公開しているMS-DOS 2.0のソースコードに含まれる文書 (MS-DOS/DEVDRIV.DOC) を読むと、この時点で既にBPBやJMP命令を含めたブートセクタの構造が標準として提案されていたことが分かる。実際、NECのMS-DOS 2.11でフォーマットしたディスクはこの構造に準じている。

フロッピーディスクのブートセクターがフォーマットの判定にどう扱われるか

MS-DOSでは次のようにして判定することを推奨している。以下、日本電気(株)『MS-DOS 3.3C プログラマーズリファレンスマニュアル Vol.1』(1990年) p.328より。

NOT FAT IDフォーマットドライバによるメディア判定には、次のプロシージャが適当です。

  1. ドライブのブートセクタを、DWORD転送アドレスによって指定される1セクタのスクラッチスペースに読み込みます。
  2. ブートセクタの最初のバイトが、E9HまたはEBH(3バイトNEARまたは2バイトSHORT JUMPの最初のバイト)か、あるいはEBH(後にNOPが続く2バイトJUMPの最初のバイト)のいずれかであることを判定します。もしそうならば、BPBはオフセットを基点として置かれます。それに対するポインタを返します。
  3. ブートセクタにBPBテーブルがない場合には、それはMS-DOSのV2.0以前でフォーマットされたディスクであり、おそらくFAT IDバイトを用いてメディアを判定します。

フロッピーディスクのブートセクタに様々な改変を施して、実際にMS-DOS上でアクセスできるか確かめてみた。OSごとにDIRコマンドでファイル一覧を表示できるか、また、CHKDSKコマンドによるディスクの正常性チェックが正しく完了するか確認した。PC-98のMS-DOSはFAT IDしか見ていないことが分かったため省略する(以下のテストは全部通ると思われる)。フロッピーディスクのフォーマットは3.5インチ720KB (2DD) を使用した。これは、1.44MB (2HD)だとMS-DOSやWindowsのドライバが決め打ちで認識してしまう可能性があり、正しい実験結果が得られないとの懸念から。

  1. 正しいFAT ID + ブートセクタ0埋め
  2. 正しいFAT ID + ブートセクタのうちBPB以外0埋め
  3. 正しいFAT ID + 正しいBPB + 先頭に’IPL1’
  4. 正しいFAT ID + 正しいBPB + 先頭に’ipl1’
  5. 正しいFAT ID + 間違ったBPB
  6. 正しいFAT ID + 間違ったBPB + 先頭に’IPL1’
  7. 正しいFAT ID + 間違ったBPB + 先頭に’ipl1’
1 2 3 4 5 6 7 テスト環境
O O o o O o o NEC MS-DOS 3.3C (T98-NEXT上) DIR
O O o o E O E 沖電気 MS-DOS 3.21 (DOSVAXJ3上) DIR
O O o o E O E 沖電気 MS-DOS 3.21 (DOSVAXJ3上) CHKDSK
O O o o E O E IBM DOS J5.0/V DIR
O O o o E O E IBM DOS J5.0/V CHKDSK
O O O O E O E Windows 98 (PC/AT互換機) MS-DOSモード DIR
O O O O E O E Windows 98 (PC/AT互換機) MS-DOSモード CHKDSK
x X X X E E E Windows 98 (PC/AT互換機) MS-DOSプロンプト DIR
x X X X E E E Windows 98 (PC/AT互換機) MS-DOSプロンプト CHKDSK
x X O X E E X Windows XP DIR
x X O X E E X Windows XP CHKDSK
x X O X E E X Windows 10 20H2 DIR
x X X X E X X Windows 10 20H2 CHKDSK

上記の表の小文字部分については未実施だが、他のテストから結果を予想できるので省略している。「間違ったBPB」は3.5インチ1.44MBフォーマットと同一のパラメータで偽装しており、Eはフォーマットを誤認していることを示す。

この実験結果から分かったことが2つある。まず、MS-DOSはブートセクタ先頭にジャンプ命令があるか、セクタサイズの指定が一定の基準(128の倍数など)を満たしているか、などのBPBの妥当性を簡易的に検証し、問題なければこれをフォーマットとして認識する。BPBの部分に想定と異なるデータが置かれている場合は、FAT IDからフォーマットの判別を試みる。ところがWindowsの場合、BPBの検証に失敗するとその時点でFATフォーマットではないと判断する。Windows 98の場合、MS-DOSモードでは従来の生DOSと同じ結果になるが、Windows上ではこれと異なる結果が出る。

もう一つはFMRフォーマットに関わることである。Windows XPとWindows 10では、テスト3ではディスク内のデータにアクセスでき、テスト6では偽装BPBを受け入れてフォーマットを誤認している。これはつまり、先頭がジャンプ命令でなく’IPL1’となっていても有効なBPBとして認識していることを示す。ところが、MS-DOSではテスト6でフォーマットを正常に認識している。つまり’IPL1’によってBPBは存在しないものとして扱われ、代替手段としてFAT IDからフォーマットを判別していることになる。そしてテスト7でフォーマットを誤認しているということは、’ipl1’で始めるブートセクタのBPBを受け入れたことになる。すなわち、Windowsでは’IPL1’が受け入れられ、MS-DOSでは’ipl1’が受け入れられたことになる。これは前回の記事でのMS-DOS 3.21 OAKとWindows NT 4.0のソースコードに存在した不一致部分と辻褄が合う。

例外として、PC-98のMS-DOSは先に述べたように、フロッピーディスクについてはFAT IDのみでフォーマットを判定している。BPBはFORMATコマンドでのフォーマット時に記録されているものの、使用されているわけではない。

次の実験はMS-DOSやWindowsが’I’(49h)と’i’(69h)のどちらかを受け入れるか、先の実験を反証するものである。

  1. 間違ったFAT ID + 正しいBPB
  2. 間違ったFAT ID + 正しいBPB + 先頭に’IPL1’
  3. 間違ったFAT ID + 正しいBPB + 先頭に’ipl1’
1 2 3 テスト環境
O X O 沖電気 MS-DOS 3.21 (DOSVAXJ3上) DIR
X X X 沖電気 MS-DOS 3.21 (DOSVAXJ3上) CHKDSK
O X O IBM DOS J5.0/V DIR
N X N IBM DOS J5.0/V CHKDSK
O X O Windows 98 (PC/AT互換機) MS-DOSモード DIR
N X N Windows 98 (PC/AT互換機) MS-DOSモード CHKDSK
O X X Windows 98 (PC/AT互換機) MS-DOSプロンプト DIR
N X X Windows 98 (PC/AT互換機) MS-DOSプロンプト CHKDSK
O O X Windows XP DIR
N N X Windows XP CHKDSK
O O X Windows 10 20H2 DIR
X X X Windows 10 20H2 CHKDSK

上記の表のNについては、CHKDSKコマンドを実行すると「これはおそらく MS-DOS のディスクではありません。続けますか (Y/N)?」という確認メッセージが出るものの、情報は正しく表示されているようである。前の記事でも述べたように、なぜMS-DOSのOAKで’i’(69h)を許容していたのか謎である。

FMRフォーマットのフロッピーディスクはPC/AT互換機で読める

ここまでの実験は全てPC/AT互換機が標準でサポートしている3 12 インチ 720KB フォーマットを基準としている。FMRフォーマットは私が調べた限りでは、PC-98とブートセクタ以外は同じ仕様を持つものと考えている。PC-98で使われている 1.23MB フォーマットをPC/AT互換機で扱うのは容易ではない。

まず3 12 インチ フロッピーディスクの場合、PC-98のフロッピーディスクドライブでは360rpmの回転速度と500kbpsのデータレートで記録しているが、PC/AT互換機で一般に使われるドライブでは回転速度が300rpm固定となっており、その記録密度に対応できるデータレートが存在しない。よってPC/AT互換機のドライブではPC-98でフォーマットされたディスクを読み取ることが物理的に不可能となっており、日本市場でPC/AT互換機を展開するメーカーは特別な対応を迫られた。

5 14 インチ フロッピーディスクの場合、PC/AT互換機で一般に使われる5 14 フロッピーディスクドライブはPC-98と同じ360rpmで駆動しているため、物理的には相互に読み書きできる。しかし、PC/AT互換機のMS-DOSでこれを読もうとするとエラーを出して終了してしまう。技術的な詳細は私にも理解しがたいが、PC/AT互換機のMS-DOSが用意するセクタバッファが512バイト/セクタを前提としていることに起因するらしい。PC/AT互換機で使用されるディスクは全て512バイト/セクタであるため問題にならないが、PC-98の標準的なフォーマットは1024バイト/セクタとなっている。MS-DOSが用意するセクタバッファより大きいセクタサイズのDPBは追加することができないため、エラーで終了してしまう。という解釈で合っているのか?情報の確度は保証しない。

当初、PC/AT互換機を使用していた少数のマニアの間では、PC-98でデータを交換する時は640KB (2DD) フォーマットまたは1.2MB (2HC) フォーマットを使用することが常識となっていた。どちらも512バイト/セクタであるため、PC/AT互換機のMS-DOSで読み書きすることができた。1.2MBフォーマットについてはPC-98標準のフォーマットではないが、MS-DOSでは非公式に対応していた。しかし、フォーマットの異なるディスクを使い分けたり、ファイルを移し替えたりというのは、煩わしかったことだろう。

そのうち、PC/AT互換機のDOSでPC-98の標準フォーマットをそのまま読み書きできるようにするフリーソフトが登場した。「JAPAN2HD」はその一つで、デバイスドライバーからMS-DOSに対しては512バイト/セクタのBPBを通知しておき、デバイスドライバー内部で512バイト×2セクタのデータを1024バイト×1セクタに相互変換して読み書きを行った。

次の実験は、5 14 インチ 2HDフロッピーディスクを1.23MBフォーマット (1024バイト/セクタ) でフォーマットし、PC/AT互換機でアクセスできるか確認したものである。なお、私はPC98の実機を所有していないため、PC/AT互換機の生DOS上で「FDU」というフリーソフトを使って物理フォーマットしたディスクを使用した。

Image: MS-DOSで扱うディスクの領域

  1. PC98標準1.23MBフォーマットのディスク
  2. PC98標準1.23MBフォーマットのディスク + 先頭に’IPL1’(⇒FMRフォーマットと同等?)
1 2 テスト環境
X X IBM DOS J5.0/V DIR
O O IBM DOS J5.0/V + JAPAN2HD.SYS DIR
x X Windows 98 (PC/AT互換機) MS-DOSモード DIR
O O Windows 98 (PC/AT互換機) MS-DOSプロンプト DIR

なんと、JAPAN2HDを使用した場合はPC/AT互換機のDOS上でFMRフォーマットのディスクを読み書きすることができた。Windows 98の場合、MS-DOSモードは生DOSと同じ環境であるためJAPAN2HDのような助けがないと読み書きできないと予想されるが、Windows上ではそのまま読み書きすることができた。ただ一つ問題があって、Windows上で一度でもフロッピーディスクにアクセスすると、ブートセクタ先頭の’IPL’がジャンプ命令で上書きされてしまう。このディスクをFMRに持ち帰って起動用に使うには、上書きされた部分を修正し直す必要がある(あるいは前もってディスクのライトプロテクトを設定する)。

マイクロソフト版のMS-DOS 6.2/VでFMRフォーマットのディスクが読めないというのは、1024FD.EXE特有の問題だった可能性がある。所持していないので、詳細を調べることはできていない。

実際の所、FMRフォーマットの非互換性は問題にならなかったと予想

以上と当時の時代背景を考えると、FMRフォーマットのブートセクタがそれほど大きな問題にならなかった理由は以下のように考えられる。

PC-98では読み書き可能

MS-DOS全盛期、日本において家庭でも企業でも最も普及していたPC-98では、FMRフォーマットのディスクを読み書きできたため、当然問題にはならなかった。

PC/AT互換機の生DOSではPC-98フォーマット同様の扱い

DOS時代にPC/AT互換機を使用していたユーザーは少数派である。FMRとPC/AT互換機を両方使用していたユーザーとなると、さらに限定的だったと考えられる。

2HDのFMRフォーマットはブートセクタの構造を除けばPC-98の1.23MBフォーマットと同等であり、どちらもPC/AT互換機のMS-DOSやDOS/Vでは通常は読み取ることができない。これを読み書きするためのドライバはフリーからPCメーカー添付のものまで様々登場したが、多くはPC-98のことしか想定していなかっただろうから、どれだけのドライバがFMRフォーマットを読めたか不明。読めなかったドライバの一例が1024FD.EXEだったという事しか分かっていない。

生DOSでは’I’ (49h) から始まるブートセクタが無効なBPBとして扱われたとしても、FAT IDからフォーマットを判別することができたため、それさえ正しければ640KBや720KBフォーマットの2DDディスクはそのまま読み書きできたことになる。よって、2DDディスクであればそのままデータを交換できる。これも表面的な状況はPC-98と同じ。

PC/AT互換機のWindows 9xでは読み書き可

PC/AT互換機のWindows 98ではFMRフォーマットのディスクをPC-98フォーマットと同様に扱うことができたが、先頭のIPLが破壊される問題があった。これについてはFM TOWNSユーザーを中心に、ネット上でもいくつかの指摘が散見される。

もっとも、FMRユーザーの中心は企業ユーザーと思われ、スタンドアロン使用に適したWindows 98よりもネットワーク利用に適したWindows NTへの移行が多かったと考えられる。ブートセクタが破壊されたところでデータ交換に支障はなく、この問題で迷惑を被ったのは、MS-DOSやFDベースのゲームソフトのディスクをイメージ化しようというFM TOWNSユーザーくらいだったのだろう。よって、Windows 9xでFMRのブートセクタ (IPL)が破壊されることによる影響はかなり小さく、大きな問題にならなかった。

Windows NTでは富士通が対応に動いた

MS-DOSでは有効なBPBがなくてもFAT IDによってフォーマットが正しく認識されていた。しかし、Windows NTでFATフォーマットとして認識されるためには、有効なBPBが記録されていることが必須条件となった。これはJMP命令をASCIIコードに置き換えていたFMRフォーマットでは互換性の問題を引き起こすことになる。富士通はWindows NTをFMRへ移植するにあたって、ソースコードにFMRフォーマットへ対応するための改変を加えた。この改変は米マイクロソフト本家のソースコードにもフィードバックされ、今のWindows 10でもFMRフォーマットのディスクが読める状態となった。

最後に

こうして自分の間違いに気づけたのは、「PC-98では読めなかったのか?」という疑問の声と、エゴサや下調べで参考にした数々の意見のおかげです。調査の原動力になったのはこの記事がきっかけでした。

PC-9801 用 MS-DOS のフロッピーディスク認識って… - DOS | OS/2 memo

内容的には深くないし、MS-DOSではBPBが必須であるという誤った情報が入っているのだけど、きっかけを与えてくれたことはありがたいです。

参考文献

  • アスキー出版局(編)『標準MS-DOSハンドブック』, アスキー, 1984年.
  • 『MS-DOS 3.3C プログラマーズリファレンスマニュアル Vol.1』, 日本電気, 1990年.
  • 幸田, 敏記『MS-DOSデータブック ―MSDOS.SYSの仕組みと解析フローチャート―』, 3版, ラジオ技術社, 1988年8月.
  • Paterson, Tim, “An Inside Look at MS-DOS”, Byte Magazine, Vol.8 No.6, 1983, pp.230-252.
  • FM TOWNS実機救済用ブートローダープロジェクト - YSFLIGHT.COM http://ysflight.in.coocan.jp/FM/towns/bootloader/j.html
  • DOS mysteries - Page 4 http://www.vcfed.org/forum/showthread.php?73257-DOS-mysteries/page4

※コメント欄が表示されない場合はdisqusについてJavascriptが有効であることを確認して下さい.