﻿======================================================================
  SFORM16 (SFORM-2 0.07互換方式)  簡易マニュアル
  MEGA-SCSI 用 FAT16 マルチパーティション・フォーマッタ (Windows版)
======================================================================

----------------------------------------------------------------------
1. 概要
----------------------------------------------------------------------
MSX-DOS2 / MEGA-SCSI で使用する SD カードを、SFORM-2 0.07互換方式の
FAT16 マルチパーティション構成でフォーマットするプログラムです。

  - Sector0 がパーティション0(FAT16)兼 MBR になります。
  - 2個以上のパーティションを作る場合、各パーティションのクラスタ2に
    MEGASCSI.TBL を作成します。
  - パーティション容量は 512MiB / 1GiB / 2GiB から選択します。
  - パーティションの合計は最大 2GiB です。
　- SFORM-2 0.07互換方式と表現していますが、実際にはSFORM-2 0.09aの
    似非ASPIフォーマットでは無い方のフォーマット形式となります。

----------------------------------------------------------------------
2. 動作環境・ファイル構成
----------------------------------------------------------------------
  OS     : Windows 10 / 11
  Python : 3.7 以降 (標準ライブラリのみ使用。追加インストール不要)
  権限   : 管理者 (物理ディスクへの書き込みに必要)

  sform16_007.py         本体 (計画・書き込みデータ生成・解析)
  write_physical_007.py  Windows 物理ディスクアクセス部
  README.TXT             本書

  ※ 2つの .py ファイルは同じフォルダに置いてください。

----------------------------------------------------------------------
3. 対象メディア
----------------------------------------------------------------------
  物理容量が次の範囲のメディアのみ対象です。範囲外の場合は中止します。

    32MiB < 物理容量 <= 32GiB

  32MiB    = 33,554,432 byte
  32GiB    = 34,359,738,368 byte
  (市販の "32GB" SDHC カードは通常この範囲に収まります)

----------------------------------------------------------------------
4. 基本的な使い方
----------------------------------------------------------------------
コマンドプロンプトを「管理者として実行」で開き、プログラムのある
フォルダへ移動してから実行します。

(1) ディスク番号を確認する

      python sform16_007.py --list

    表示例:
      No  容量                         バス   リムーバブル  モデル / ドライブ
       0  512,110,190,592 byte (...)   NVMe   いいえ        ...  C:\  ★システム
       2  31,914,983,424 byte (...)    USB    はい          Generic SD  E:\

    容量・モデル・ドライブ文字から、対象の SD カードの番号を確認して
    ください。★システム の付いたディスクは選択できません。

(2) 作成されるパーティションを確認する (書き込みなし)

      python sform16_007.py --disk 2 --size 512M --dry-run

(3) フォーマットする

      python sform16_007.py --disk 2 --size 512M

    計画が表示された後、確認のためディスク番号の入力を求められます。
    正しい番号を入力すると書き込みを開始します。それ以外を入力すると
    中止します。

(4) 結果を確認する (任意)

      python sform16_007.py --disk 2 --inspect

    最後に「解析結果: 問題なし」と表示されれば正常です。

----------------------------------------------------------------------
5. パーティションの作成規則
----------------------------------------------------------------------
  --size で指定した容量 Y (512M / 1G / 2G) で先頭から順に切り出します。

  1) 使用可能容量 = min(物理容量, 2GiB)
  2) 残り容量 >= Y なら、容量 Y のパーティションを1個作成
  3) 残り容量 <  Y なら、残り全部を1個のパーティションにする
  4) 残り容量が 32MiB 以下になったら、それ以上作成しない

  作成例:
    物理容量           --size 512M          --size 1G     --size 2G
    ----------------   ------------------   -----------   -----------
    2GiB 以上          512MiB x 4           1GiB x 2      2GiB x 1
    1GB (10^9 byte)    512MiB + 441.67MiB   953.67MiB x1  953.67MiB x1
    544MiB             512MiB x 1           544MiB x 1    544MiB x 1
    40MiB              40MiB x 1            40MiB x 1     40MiB x 1

  ※ 2GiB 以上のメディアでは、2GiB 以降の領域は使用しません。

----------------------------------------------------------------------
6. クラスタサイズ
----------------------------------------------------------------------
  FAT16 のクラスタ数上限 (65,524) に収まる最小のクラスタサイズを
  パーティションごとに自動選択します。

    パーティション容量    クラスタサイズ   sectors/cluster
    ------------------    --------------   ---------------
    〜 約512MiB           8KB              16
    〜 約1GiB             16KB             32
    〜 約2GiB             32KB             64

  ※ 2GiB を指定した場合、FAT16 の上限に合わせて実際のパーティションは
     4,194,081 セクタ (2GiB より 223 セクタ = 約111KiB 小さい) に
     なります。

----------------------------------------------------------------------
7. オプション一覧
----------------------------------------------------------------------
  [対象の指定] (いずれか1つが必須)
    --list               物理ディスクの一覧を表示する
    --disk N             物理ディスク N (\\.\PhysicalDriveN) を対象にする
    --image PATH         イメージファイルを対象にする (試験用)

  [基本]
    --size {512M,1G,2G}  1パーティションの容量 (フォーマット時は必須)
                         512MiB, 1GiB, 2GiB のような表記も可
    --dry-run            計画を表示するだけで書き込まない
    --inspect            既存のフォーマット構造を解析して表示する
    --yes                確認入力を省略する (注意して使用)

  [イメージファイル]
    --image-size SIZE    イメージファイルを新規作成する容量
                         例: 1GB (10^9), 4GiB, 560MiB, 31914983424 (byte)
                         既存ファイルは上書きされます。

  [詳細設定]
    --cluster {auto,16,32,64}
                         sectors/cluster を固定する (既定: auto)
    --no-protect-tbl     MEGASCSI.TBL のクラスタ2を FAT 上で未使用の
                         ままにする (0.07互換仕様書どおりの動作)
    --tbl-end {device,used}
                         MEGASCSI.TBL 終端レコードの開始値
                           device : デバイス総容量 (既定)
                           used   : 最終パーティションの末尾
    --no-clear-tail      デバイス末尾 (旧GPTバックアップ領域) を消去しない
    --no-verify          書き込み後のベリファイを省略する
    --oem NAME           ブートセクタの OEM 名 (8文字まで。既定 SFRM16)
    --serial HEX         ボリュームシリアルの基準値 (16進)
    --max-partitions N   パーティション数の上限 (既定 16)
    --force              リムーバブル/USB/SD 以外のディスクも許可する
                         (内蔵ディスクを誤って消す危険があります)

----------------------------------------------------------------------
8. 書き込まれる内容
----------------------------------------------------------------------
  各パーティションに以下を書き込みます。データ領域は消去しません
  (クイックフォーマット相当)。

    ブートセクタ      BPB、ブートプログラム、MBRエントリ1/2
    FAT #1, #2        先頭 F0 FF FF FF (+ FF FF: TBL保護時)、残りゼロ
    ルートディレクトリ  先頭に MEGASCSI.TBL のエントリ、残りゼロ
    クラスタ2          MEGASCSI.TBL の実データ (全パーティション同一)

  各値の作り方:
    ボリュームシリアル (0x27-0x2A)
        基準値 + パーティション番号。基準値は --serial の値、
        指定が無ければ実行時刻 (Unix時間)。
    ディスクシグネチャ (0x1B8-0x1BB)
        乱数 4byte。Sector0 のみ。他のパーティションはゼロ。

  パーティションが1個だけの場合:
    MEGASCSI.TBL は作成しません。ルートディレクトリは空になり、
    クラスタ2の先頭セクタはゼロで消去します (旧TBLの残骸対策)。

----------------------------------------------------------------------
9. 注意事項
----------------------------------------------------------------------
  - 対象ディスクの内容はすべて失われます。ディスク番号は必ず
    --list と --dry-run で確認してから実行してください。

  - 書き込み前に、対象ディスク上のボリュームをロック・アンマウント
    します。エクスプローラ等でカード内のファイルやフォルダを
    開いているとロックに失敗するので、閉じてから実行してください。

  - MEGASCSI.TBL の保護 (既定で有効)
    0.07互換仕様書では、MEGASCSI.TBL のあるクラスタ2は FAT 上で
    「未使用」のままです。この状態では Windows や MSX でファイルを
    書き込んだときに TBL が上書きされる恐れがあります。このため
    本プログラムでは既定で FAT 上を「使用中」にしています。
    仕様書どおりにしたい場合のみ --no-protect-tbl を付けてください。

  - 約8GiB を超えるカードの場合
    MEGASCSI.TBL の開始値フィールドは 3byte のため、デバイス総容量を
    格納できません。終端レコードの開始値を 0xFFFFFF に丸め、注意を
    表示します (--tbl-end used で最終パーティション末尾にできます)。

  - Windows から見える状態
    フォーマット後、Windows が各パーティションにドライブ文字を
    割り当てる場合があります。「フォーマットしますか?」と聞かれても
    フォーマットしないでください (MEGA-SCSI 用の構造が失われます)。

  - CP-004.COM にはパーティション番号の対応がずれる既知のバグが
    あります。CP.COM (パッチ無し版) の使用を推奨します。

----------------------------------------------------------------------
10. イメージファイルでの試験
----------------------------------------------------------------------
  SD カードを使わずに動作を確認できます (管理者権限不要)。

    python sform16_007.py --image test.img --image-size 1GB --size 512M
    python sform16_007.py --image test.img --inspect

  イメージは Win32 Disk Imager 等でカードに書き込むこともできますが、
  2GiB を超える部分も含めた物理容量分のファイルになる点に注意して
  ください。

----------------------------------------------------------------------
11. 終了コード
----------------------------------------------------------------------
    0    正常終了
    1    エラー、または確認入力で中止
    2    --inspect で問題を検出
    130  Ctrl+C で中断

----------------------------------------------------------------------
12. トラブルシューティング
----------------------------------------------------------------------
  「管理者として実行してください」
      コマンドプロンプトを右クリック →「管理者として実行」で開く。

  「ボリューム X: をロックできません」「書込が拒否されました」
      Windows やほかのプログラム(エクスプローラ、自動再生、ウイルス
      対策ソフト等)がカード上のボリュームを使用中です。以前 SFORM16 で
      複数パーティションを作成したカードに再実行した場合に起きやすく
      なります。
      本プログラムはロックを約5秒間再試行し、それでも失敗した場合は
      強制アンマウントしてから再度ロックを試みます。それでも失敗した
      ときは、次の手順で対処してください(画面にも同じ案内が出ます)。

        1. SD Association 公式の SD Card Formatter でカードを
           フォーマットする
             https://www.sdcard.org/downloads/formatter/
           (クイックフォーマットで可。ドライブの選択に注意)
        2. カードを一度抜き差しする
        3. 本プログラムを再実行する

      ロックの段階で失敗した場合、カードには何も書き込まれていません。
      書き込み途中で失敗した場合は構造が不完全なので、必ず上記手順で
      初期化してから再実行してください。

  「リムーバブル/USB/SD デバイスではありません」
      内蔵カードリーダー等で種別が正しく報告されない場合に表示される。
      --list で対象が間違いないことを確認したうえで --force を付ける。

  「32GiB を超えています」「32MiB 以下のため対象外です」
      対象外のメディアです (3章参照)。

  「メディアが挿入されていません」
      カードリーダーにカードが入っているか確認する。

  「書込禁止(ライトプロテクト)状態です」
  「最初のセクタに書き込めませんでした。ライトプロテクトされている
    可能性があります」
      SD カード側面のスイッチが LOCK 側になっています。書込可能側へ
      動かしてから差し直し、再実行してください。microSD 変換アダプタ
      の場合はアダプタ側のスイッチを確認してください。
      カードリーダーによってはライトプロテクトを「I/O デバイス エラー
      (エラー 1117)」として報告するため、後者のメッセージになります。
      いずれの場合もカードには何も書き込まれていません。

  「ベリファイ失敗」
      カードの不良、書き込み禁止スイッチ、リーダーの不調が考えられる。
      別のカード/リーダーで試す。

======================================================================
