Add A78 cart writing

This commit is contained in:
Matt Nadareski
2026-04-14 10:13:05 -04:00
parent f26c5bfebc
commit b51879bbec
2 changed files with 170 additions and 86 deletions

View File

@@ -1,7 +1,5 @@
using System;
using System.IO;
using SabreTools.Data.Models.Atari7800;
using SabreTools.Numerics.Extensions;
namespace SabreTools.Wrappers
{
@@ -28,85 +26,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);
// Byte 0
fs.Write(Header.HeaderVersion);
fs.Flush();
// Bytes 1-16
fs.Write(Header.MagicText);
fs.Flush();
// Bytes 17-48
fs.Write(Header.CartTitle);
fs.Flush();
// Bytes 49-52
fs.Write(Header.RomSizeWithoutHeader);
fs.Flush();
// Bytes 53-54
fs.Write((ushort)Header.CartType);
fs.Flush();
// Bytes 55-56
fs.Write((byte)Header.Controller1Type);
fs.Write((byte)Header.Controller2Type);
fs.Flush();
// Byte 57
fs.Write((byte)Header.TVType);
fs.Flush();
// Byte 58
fs.Write((byte)Header.SaveDevice);
fs.Flush();
// Bytes 59-62
fs.Write(Header.Reserved);
fs.Flush();
// Byte 63
fs.Write((byte)Header.SlotPassthroughDevice);
fs.Flush();
if (HeaderVersion >= 4)
{
// Byte 64
fs.Write((byte)Header.Mapper);
fs.Flush();
// Byte 65
fs.Write((byte)Header.MapperOptions);
fs.Flush();
// Byte 66-67
fs.Write((ushort)Header.AudioDevice);
fs.Flush();
// Byte 68-69
fs.Write((ushort)Header.Interrupt);
fs.Flush();
// Bytes 70-99
fs.Write(Header.Padding);
fs.Flush();
}
else
{
// Bytes 64-99
fs.Write(Header.Padding);
fs.Flush();
}
// Bytes 100-127
fs.Write(Header.EndMagicText);
fs.Flush();
// Header extracted
success = true;
success |= WriteHeader(fs, includeDebug);
}
catch (Exception ex)
{
@@ -123,13 +44,8 @@ namespace SabreTools.Wrappers
// Try to write the data
try
{
// Open the output file for writing
using var fs = File.Open(romPath, FileMode.Create, FileAccess.Write, FileShare.None);
fs.Write(Model.Data, 0, Model.Data.Length);
fs.Flush();
// ROM extracted
success = true;
success |= WriteRom(fs, includeDebug);
}
catch (Exception ex)
{

View File

@@ -0,0 +1,168 @@
using System;
using System.IO;
using SabreTools.Data.Models.Atari7800;
using SabreTools.Numerics.Extensions;
namespace SabreTools.Wrappers
{
public partial class Atari7800Cart : IWritable
{
/// <inheritdoc/>
public bool Write(string outputDirectory, bool includeDebug)
{
// Get the base path
string outputFilename = Filename is null
? Guid.NewGuid().ToString()
: Path.GetFileName(Filename);
outputFilename += ".a78";
string outputPath = Path.Combine(outputDirectory, 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;
}
/// <summary>
/// Write header data to the stream
/// </summary>
/// <param name="stream">Stream to write to</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>True if the writing was successful, false otherwise</returns>
private bool WriteHeader(Stream stream, bool includeDebug)
{
if (includeDebug) Console.WriteLine("Attempting to extract header data");
if (Header is null)
{
if (includeDebug) Console.WriteLine("Header was invalid!");
return false;
}
// Try to write the data
try
{
// Byte 0
stream.Write(Header.HeaderVersion);
stream.Flush();
// Bytes 1-16
stream.Write(Header.MagicText);
stream.Flush();
// Bytes 17-48
stream.Write(Header.CartTitle);
stream.Flush();
// Bytes 49-52
stream.Write(Header.RomSizeWithoutHeader);
stream.Flush();
// Bytes 53-54
stream.Write((ushort)Header.CartType);
stream.Flush();
// Bytes 55-56
stream.Write((byte)Header.Controller1Type);
stream.Write((byte)Header.Controller2Type);
stream.Flush();
// Byte 57
stream.Write((byte)Header.TVType);
stream.Flush();
// Byte 58
stream.Write((byte)Header.SaveDevice);
stream.Flush();
// Bytes 59-62
stream.Write(Header.Reserved);
stream.Flush();
// Byte 63
stream.Write((byte)Header.SlotPassthroughDevice);
stream.Flush();
if (HeaderVersion >= 4)
{
// Byte 64
stream.Write((byte)Header.Mapper);
stream.Flush();
// Byte 65
stream.Write((byte)Header.MapperOptions);
stream.Flush();
// Byte 66-67
stream.Write((ushort)Header.AudioDevice);
stream.Flush();
// Byte 68-69
stream.Write((ushort)Header.Interrupt);
stream.Flush();
// Bytes 70-99
stream.Write(Header.Padding);
stream.Flush();
}
else
{
// Bytes 64-99
stream.Write(Header.Padding);
stream.Flush();
}
// Bytes 100-127
stream.Write(Header.EndMagicText);
stream.Flush();
// Header extracted
return true;
}
catch (Exception ex)
{
if (includeDebug) Console.Error.WriteLine(ex);
return false;
}
}
/// <summary>
/// Write rom data to the stream
/// </summary>
/// <param name="stream">Stream to write to</param>
/// <param name="includeDebug">True to include debug data, false otherwise</param>
/// <returns>True if the writing was successful, false otherwise</returns>
private bool WriteRom(Stream stream, bool includeDebug)
{
if (includeDebug) Console.WriteLine("Attempting to extract 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;
}
}
}
}