CD-Imagedateien konvertieren
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:

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:

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