2026-02-26

NFD形式ファイルの構造を出力するスクリプトを作成

Windows11上のT98-NEXTでWizardryをプレイするとNFD形式でフロッピーディスクイメージが作られます。これをNetBSD/i386上のxnp2で利用するにはFDI形式に変換しなくてはなりません。変換スクリプトを作成する前に、NFD形式について学ぶため、ファイル内の構造を出力するスクリプトを作ってみました。

 

以前なら、GoogleなどでWebを検索して、参考となるサイトを探していました。今でも同様なのですが、最近はGeminiと対話しながら、作成するようになりました。世間一般では、生成されたスクリプトを何も考えずに使うだけなのか、それとも生成されたものを参考にしながら自前で作るのか、どうしているのかはわかりません。私の場合には、Geminiが生成したスクリプトを参考にして、自分で作り上げるようにしています。

 

その結果、以下のようなスクリプトが出来上がりました。これを使ってWizardryで使用しているファイルを参照してみると、いろいろと勉強になります。 

 

#!/usr/bin/python3
import sys
import ctypes

# 基本的な型のエイリアス
BYTE  = ctypes.c_uint8
WORD  = ctypes.c_uint16
DWORD = ctypes.c_uint32

# セクタ情報
class NFD_SECT_ID(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("C",        BYTE),
        ("H",        BYTE),
        ("R",        BYTE),
        ("N",        BYTE),
        ("flMFM",    BYTE),
        ("flDDAM",   BYTE),
        ("byStatus", BYTE),
        ("byST0",    BYTE),
        ("byST1",    BYTE),
        ("byST2",    BYTE),
        ("byPDA",    BYTE),
        ("Reserve1", ctypes.c_char * 5),
    ]

# ヘッダ
class NFD_FILE_HEAD(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("szFileID",    ctypes.c_char * 15),
        ("Reserve1",    ctypes.c_char * 1),
        ("szComment",   ctypes.c_char * 0x100),
        ("dwHeadSize",  DWORD),
        ("flProtect",   BYTE),
        ("byHead",      BYTE),
        ("Reserve2",    ctypes.c_char * 10),
        ("si",          NFD_SECT_ID * (163 * 26)),
        ("Reserve3",    ctypes.c_char * 0x10),
    ]

if __name__ == "__main__":
    try:
        f = open(sys.argv[1], "br")
    except:
        print("usage: NFDdump <filename>")
        exit(1)

    header = NFD_FILE_HEAD()
    f.readinto(header)

    print(f"szFileID:{header.szFileID}")
    print(f"szComment:{header.szComment}")
    print(f"dwHeadSize:{header.dwHeadSize} (0x{header.dwHeadSize:X})")
    print(f"flProtect:{header.flProtect}")
    print(f"byHead:{header.byHead}")

    for i in range(len(header.si)):
        print(f"{i:4}:  ", end="")
        print(f"C:{header.si[i].C:02x} ", end="")
        print(f"H:{header.si[i].H:02x} ", end="")
        print(f"R:{header.si[i].R:02x} ", end="")
        print(f"N:{header.si[i].N:02x} ", end="")
        print(f"MFM:{header.si[i].flMFM} ", end="")
        print(f"DDAM:{header.si[i].flDDAM} ", end="")
        print(f"Status:{header.si[i].byStatus:02x} ", end="")
        print(f"ST0:{header.si[i].byST0:02x} ", end="")
        print(f"ST1:{header.si[i].byST1:02x} ", end="")
        print(f"ST2:{header.si[i].byST2:02x} ", end="")
        print(f"PDA:{header.si[i].byPDA:02x} ", end="")
        print(f"addr:{(header.dwHeadSize + i * 256):08x}")
#[EOF]
 

0 件のコメント:

コメントを投稿