From 5968a367e84604e8ab011aa5bd8eae1a0fd79c7b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 14 Apr 2026 10:33:30 -0400 Subject: [PATCH] Add FDS image writing --- SabreTools.Wrappers/Atari7800Cart.Writing.cs | 4 +- SabreTools.Wrappers/AtariLynxCart.Writing.cs | 4 +- SabreTools.Wrappers/FDS.Extraction.cs | 35 ++---- SabreTools.Wrappers/FDS.Writing.cs | 107 +++++++++++++++++++ 4 files changed, 118 insertions(+), 32 deletions(-) create mode 100644 SabreTools.Wrappers/FDS.Writing.cs diff --git a/SabreTools.Wrappers/Atari7800Cart.Writing.cs b/SabreTools.Wrappers/Atari7800Cart.Writing.cs index 32673c96..05efb918 100644 --- a/SabreTools.Wrappers/Atari7800Cart.Writing.cs +++ b/SabreTools.Wrappers/Atari7800Cart.Writing.cs @@ -48,7 +48,7 @@ namespace SabreTools.Wrappers /// True if the writing was successful, false otherwise private bool WriteHeader(Stream stream, bool includeDebug) { - if (includeDebug) Console.WriteLine("Attempting to extract header data"); + if (includeDebug) Console.WriteLine("Attempting to write header data"); if (Header is null) { @@ -151,7 +151,7 @@ namespace SabreTools.Wrappers /// True if the writing was successful, false otherwise private bool WriteRom(Stream stream, bool includeDebug) { - if (includeDebug) Console.WriteLine("Attempting to extract ROM data"); + if (includeDebug) Console.WriteLine("Attempting to write ROM data"); // Try to write the data try diff --git a/SabreTools.Wrappers/AtariLynxCart.Writing.cs b/SabreTools.Wrappers/AtariLynxCart.Writing.cs index a09bfc76..82f7d474 100644 --- a/SabreTools.Wrappers/AtariLynxCart.Writing.cs +++ b/SabreTools.Wrappers/AtariLynxCart.Writing.cs @@ -48,7 +48,7 @@ namespace SabreTools.Wrappers /// True if the writing was successful, false otherwise private bool WriteHeader(Stream stream, bool includeDebug) { - if (includeDebug) Console.WriteLine("Attempting to extract header data"); + if (includeDebug) Console.WriteLine("Attempting to write header data"); if (Header is null) { @@ -109,7 +109,7 @@ namespace SabreTools.Wrappers /// True if the writing was successful, false otherwise private bool WriteRom(Stream stream, bool includeDebug) { - if (includeDebug) Console.WriteLine("Attempting to extract ROM data"); + if (includeDebug) Console.WriteLine("Attempting to write ROM data"); // Try to write the data try diff --git a/SabreTools.Wrappers/FDS.Extraction.cs b/SabreTools.Wrappers/FDS.Extraction.cs index 9979f5d6..74c6e972 100644 --- a/SabreTools.Wrappers/FDS.Extraction.cs +++ b/SabreTools.Wrappers/FDS.Extraction.cs @@ -1,12 +1,12 @@ using System; using System.IO; -using SabreTools.Numerics.Extensions; namespace SabreTools.Wrappers { public partial class FDS : IExtractable { /// + /// TODO: Convert to QD as well? public bool Extract(string outputDirectory, bool includeDebug) { // Get the base path @@ -27,23 +27,8 @@ namespace SabreTools.Wrappers // Try to write the data try { - // Open the output file for writing using var fs = File.Open(headerPath, FileMode.Create, FileAccess.Write, FileShare.None); - - // Bytes 0-3 - fs.Write(Header.IdentificationString); - fs.Flush(); - - // Byte 4 - fs.Write(Header.DiskSides); - fs.Flush(); - - // Byte 5-15 - fs.Write(Header.Padding); - fs.Flush(); - - // Header extracted - success = true; + success |= WriteHeader(fs, includeDebug); } catch (Exception ex) { @@ -51,23 +36,17 @@ namespace SabreTools.Wrappers } } - // Disk data - // TODO: Convert to QD format? + // ROM data if (Model.Data.Length > 0) { - string diskPath = $"{basePath}.unh"; - if (includeDebug) Console.WriteLine($"Attempting to extract disk data to {diskPath}"); + string romPath = $"{basePath}.bin"; + if (includeDebug) Console.WriteLine($"Attempting to extract ROM data to {romPath}"); // Try to write the data try { - // Open the output file for writing - using var fs = File.Open(diskPath, FileMode.Create, FileAccess.Write, FileShare.None); - fs.Write(Model.Data, 0, Model.Data.Length); - fs.Flush(); - - // PRG-ROM extracted - success = true; + using var fs = File.Open(romPath, FileMode.Create, FileAccess.Write, FileShare.None); + success |= WriteRom(fs, includeDebug); } catch (Exception ex) { diff --git a/SabreTools.Wrappers/FDS.Writing.cs b/SabreTools.Wrappers/FDS.Writing.cs new file mode 100644 index 00000000..8244b62c --- /dev/null +++ b/SabreTools.Wrappers/FDS.Writing.cs @@ -0,0 +1,107 @@ +using System; +using System.IO; +using SabreTools.Numerics.Extensions; + +namespace SabreTools.Wrappers +{ + public partial class FDS : IWritable + { + /// + public bool Write(string outputPath, bool includeDebug) + { + // Ensure an output path + if (string.IsNullOrEmpty(outputPath)) + { + string outputFilename = Filename is null + ? (Guid.NewGuid().ToString() + ".fds") + : (Filename + ".new"); + outputPath = Path.GetFullPath(outputFilename); + } + + // Check for invalid data + if (Header is null || Model.Data is null || Model.Data.Length == 0) + { + if (includeDebug) Console.WriteLine("Model was invalid, cannot write!"); + return false; + } + + // Open the output file for writing + using var fs = File.Open(outputPath, FileMode.Create, FileAccess.Write, FileShare.None); + + // Header data + if (!WriteHeader(fs, includeDebug)) + return false; + + // ROM data + if (!WriteRom(fs, includeDebug)) + return false; + + return true; + } + + /// + /// Write header data to the stream + /// + /// Stream to write to + /// True to include debug data, false otherwise + /// True if the writing was successful, false otherwise + private bool WriteHeader(Stream stream, bool includeDebug) + { + if (includeDebug) Console.WriteLine("Attempting to write header data"); + + if (Header is null) + { + if (includeDebug) Console.WriteLine("Header was invalid!"); + return false; + } + + // Try to write the data + try + { + // Bytes 0-3 + stream.Write(Header.IdentificationString); + stream.Flush(); + + // Byte 4 + stream.Write(Header.DiskSides); + stream.Flush(); + + // Byte 5-15 + stream.Write(Header.Padding); + stream.Flush(); + + // Header extracted + return true; + } + catch (Exception ex) + { + if (includeDebug) Console.Error.WriteLine(ex); + return false; + } + } + + /// + /// Write rom data to the stream + /// + /// Stream to write to + /// True to include debug data, false otherwise + /// True if the writing was successful, false otherwise + private bool WriteRom(Stream stream, bool includeDebug) + { + if (includeDebug) Console.WriteLine("Attempting to write ROM data"); + + // Try to write the data + try + { + stream.Write(Model.Data, 0, Model.Data.Length); + stream.Flush(); + return true; + } + catch (Exception ex) + { + if (includeDebug) Console.Error.WriteLine(ex); + return false; + } + } + } +}