Zum Inhalt

CD-Imagedateien konvertieren

📅 Erstellt: 10.08.2026 🔄 Aktualisiert: 11.08.2026

Linux

ISO aus Dateien und Ordnern

Hierfür wird genisoimage benutzt. Das kann zum Beispiel aus den Paketquellen von Arch Linux installiert werden.
Die Befehlszeile lautet wie folgt:
genisoimage -iso-level 1 -V "MEINE_CD" -o dos_spiel.iso /pfad/zu/deinem/quellordner

Erklärung der wichtigsten Optionen:
- -iso-level 1: Begrenzt die Dateinamen streng auf das 8.3-Format (max. 8 Zeichen Name, 3 Zeichen Endung) und erlaubt nur ein Verzeichnis-Level ohne komplexe Erweiterungen.
- -V "MEINE_CD": Setzt den Volume-Namen (Datenträgerbezeichnung) der CD (maximal 32 Zeichen, idealerweise ebenfalls kurz und in Großbuchstaben gehalten).
- -o dos_spiel.iso: Der Name und Pfad der fertigen ISO-Datei, die am Ende herauskommt.
- /pfad/zu/deinem/quellordner: Der Ordner auf deinem Linux-System, in dem die DOS-Dateien liegen.

Ich habe mal was zusammengestellt, bewusst auch mal mit lowercase .zip, mal sehen was passiert:
1c76c80b37e5b28ddf3c6d4e6ec0760d.png

ISO dann mal erstellt mit:
genisoimage -iso-level 1 -V "DOS_ISO" -o ~/dos_games.iso /mnt/ToshibaHDD/Temp/dosiso

Das funktioniert soweit gut, auch Lowercase wurde zu Uppercase :-)
Screenshots folgen

.bin/.cue aus GOG-Dateien

Oder allgemein aus .bin/.cue mit anhänglichen, ggf. komprimierten Audiodateien .wav/.ogg/.mp3 etc.

Hierfür habe ich zusammen mit Gemini ein Python Skript entwickelt. Die Technik dahinter ist die Audiotracks in 16-Bit 44 kHz RAW-Dateien zu decodieren (mit FFMPEG) und in "Mode1 / 2352" auf .bin zu "brennen".
Die GOG Dateien werden mit ihrer Endung .ins/.gog äquivalent zu .bin/.cue interpretiert, sind im Grunde das gleiche nur mit anderer Extension.

Datei-/Ordnerstruktur am Beispiel der Alone in the Dark 3 GOG Version:
c9ceb92990fa4bbd03f0133926e33af6.png

Skript: -> conv_gog_bincue_mode1.py

import os
import subprocess
import sys
import glob

# 1. .ins Datei im Ordner suchen
ins_files = glob.glob("*.ins")
if not ins_files:
    print("Fehler: Keine .ins-Datei im aktuellen Verzeichnis gefunden!")
    sys.exit(1)

ins_file = ins_files[0]
print(f"Gefundene Installations-Datei: {ins_file}")

# 2. Spielnamen abfragen
game_name = input("Bitte gib den Namen für die Spieldateien ein (z.B. AloneInTheDark3): ").strip()
if not game_name:
    game_name = os.path.splitext(ins_file)[0]

output_bin = f"{game_name}.bin"
output_cue = f"{game_name}.cue"

# 3. .ins Datei parsen, um Audiotracks und die gog-Datei zu finden
data_file = None
audio_tracks = []
current_file = None

with open(ins_file, "r", encoding="utf-8", errors="ignore") as f:
    for line in f:
        line_str = line.strip()
        if line_str.startswith("FILE"):
            parts = line_str.split('"')
            if len(parts) >= 2:
                current_file = parts[1]
        elif "TRACK" in line_str and "AUDIO" in line_str:
            parts = line_str.split()
            track_num = int(parts[1])
            audio_tracks.append((track_num, current_file))
        elif "TRACK" in line_str and ("MODE1" in line_str or "MODE2" in line_str):
            parts = line_str.split()
            track_num = int(parts[1])
            data_file = current_file

if not data_file or not os.path.exists(data_file):
    gog_files = glob.glob("*.gog")
    if gog_files:
        data_file = gog_files[0]
    else:
        print("Fehler: Konnte die Datendatei (.gog) nicht finden!")
        sys.exit(1)

# PICO-GUS FIX: Wir erzwingen MODE1/2352, da PicoGUS kein Mode 2 / XA unterstützt!
data_mode = "MODE1/2352"

print(f"\nStarte Konvertierung für PicoGUS:")
print(f" -> Datendatei: {data_file} (Erzwungener Modus: {data_mode})")
print(f" -> Audio-Tracks: {len(audio_tracks)} gefunden\n")

total_sectors = 0
tracks = []

# Track 1: Daten schreiben
data_size = os.path.getsize(data_file)
data_sectors = data_size // 2352
tracks.append((1, data_mode, 0, data_sectors))
total_sectors += data_sectors

with open(output_bin, "wb") as outfile:
    with open(data_file, "rb") as infile:
        outfile.write(infile.read())

# Audio-Tracks verarbeiten
for track_num, ogg_path in audio_tracks:
    ogg_path_clean = ogg_path.replace("\\", "/")
    if not os.path.exists(ogg_path_clean):
        print(f"Warnung: Audio-Datei {ogg_path_clean} nicht gefunden, überspringe...")
        continue

    raw_name = f"temp_track{track_num:02d}.raw"
    print(f"Konvertiere Track {track_num:02d} ({ogg_path_clean})...")

    subprocess.run([
        "ffmpeg", "-y", "-i", ogg_path_clean,
        "-f", "s16le", "-acodec", "pcm_s16le", "-ar", "44100", "-ac", "2",
        raw_name
    ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    if os.path.exists(raw_name):
        raw_sectors = os.path.getsize(raw_name) // 2352
        tracks.append((track_num, "AUDIO", total_sectors, raw_sectors))

        with open(output_bin, "ab") as outfile:
            with open(raw_name, "rb") as infile:
                outfile.write(infile.read())

        total_sectors += raw_sectors
        os.remove(raw_name)

def sectors_to_msf(sectors):
    frames = sectors % 75
    total_seconds = sectors // 75
    seconds = total_seconds % 60
    minutes = total_seconds // 60
    return f"{minutes:02d}:{seconds:02d}:{frames:02d}"

# .cue Datei mit MODE1/2352 für die PicoGUS generieren
with open(output_cue, "w", encoding="utf-8") as cuefile:
    cuefile.write(f'FILE "{output_bin}" BINARY\n')
    for track_num, track_type, start_sector, _ in tracks:
        msf = sectors_to_msf(start_sector)
        cuefile.write(f"  TRACK {track_num:02d} {track_type}\n")
        cuefile.write(f"    INDEX 01 {msf}\n")

print("\n------------------------------------------")
print(f"Erfolg! PicoGUS-kompatible Dateien erstellt:")
print(f" -> {output_bin}")
print(f" -> {output_cue}")

.bin/.cue oder .iso aus .mds/.mdf Dateien

Um alle Szenarien komplett abzudecken werden die Tools cdrdao, toc2cue, mdf2iso und der cdemu-client benötigt. Diese sind z.B. mit Arch Linux als Pakete verfügbar.
Falls das Image eine CD abbilden soll, die auch Audiotracks enthält geht man über den cdemu-client, man mountet das Image und erstellt mit cdrdao vom emulierten Laufwerk ein neues Imagefile .bin/.toc. .toc wiederum ist dann umwandelbar in .cue mit toc2cue.

Theoretisch geht es am einfachsten mit reinen Daten-CD-Images:
mdf2iso Image.mdf
ACHTUNG! PicoGUS mag dieses Format aber offenbar nicht. Daher werde ich den unten gezeigten Weg nehmen.

Für Daten- & Audio-CD-Images .mds/.mdf - ungetestet - theoretisch:
cdemu load 0 Image.mds
cdrdao read-cd --read-raw --datafile Image.bin --device /dev/sr0 Image.toc
toc2cue Image.toc Image.cue

Dies funktioniert auch für reine Daten-CDs und ist meiner Meinung nach die sicher(st)e Methode!

.img/.sub/.ccd Format

Bedeutung der einzelnen Dateien (Quelle: Gemini):

  • .img: Dies ist die eigentliche Imagedatei. Sie enthält alle Sektoren im rohen 2352-Byte-Format und ist damit funktional identisch mit einer .bin-Datei.

  • .ccd: Eine textbasierte Steuerungsdatei (im INI-Format), die den Aufbau der CD, die Positionen der Tracks und den Modus beschreibt – im Grunde das Äquivalent zu einer .cue-Datei.

  • .sub: Enthält Subchannel-Daten (Subcodes für Kopierschutze oder CD-Text). Das wird von der PicoGUS und klassischen DOS-CD-Treibern nicht benötigt und kann schlicht ignoriert werden.

Die Image-Datei .img wird zu .bin umgenannt:
mv Image.img Image.bin

Mit dem Tool ccd2cue wird ein .cue erzeugt:
ccd2cue Image.ccd Image.cue

.sub wird ignoriert und nicht benötigt. Wird sich in Praxistests zeigen, ob das stimmt :-)

.nrg Format

Hierfür nutzt man das Tool nrg2iso und/oder nrg2cue.
nrg2cue für Windows und als Linux .c Source: nrg2cue.zip

Reine Daten-CD-Images mit der Befehlszeile:
nrg2iso Image.nrg Image.iso

Daten- & Audio-CD-Images:
nrg2cue Image.nrg Image.cue Image.bin