Use new big endian marshaller on byte addressable images.

This commit is contained in:
2025-10-21 11:31:53 +01:00
parent 1a966d0c1c
commit 8c93002fdd
6 changed files with 109 additions and 106 deletions

View File

@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Attributes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -16,7 +17,7 @@ using Marshal = Aaru.Helpers.Marshal;
namespace Aaru.Images;
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class AtariLynx : IByteAddressableImage
public partial class AtariLynx : IByteAddressableImage
{
byte[] _data;
Stream _dataStream;
@@ -59,9 +60,9 @@ public class AtariLynx : IByteAddressableImage
if((stream.Length - 64) % 65536 != 0) return false;
stream.Position = 0;
byte[] magicBytes = new byte[4];
var magicBytes = new byte[4];
stream.EnsureRead(magicBytes, 0, 4);
uint magic = BitConverter.ToUInt32(magicBytes, 0);
var magic = BitConverter.ToUInt32(magicBytes, 0);
// "LYNX"
return magic == 0x584E594C;
@@ -78,13 +79,13 @@ public class AtariLynx : IByteAddressableImage
if((stream.Length - 64) % 65536 != 0) return ErrorNumber.InvalidArgument;
stream.Position = 0x0;
byte[] magicBytes = new byte[4];
var magicBytes = new byte[4];
stream.EnsureRead(magicBytes, 0, 4);
uint magic = BitConverter.ToUInt32(magicBytes, 0);
var magic = BitConverter.ToUInt32(magicBytes, 0);
if(magic != 0x584E594C) return ErrorNumber.InvalidArgument;
byte[] headerBytes = new byte[64];
var headerBytes = new byte[64];
stream.Position = 0;
stream.EnsureRead(headerBytes, 0, 64);
@@ -102,7 +103,7 @@ public class AtariLynx : IByteAddressableImage
MetadataMediaType = MetadataMediaType.LinearMedia
};
HandyHeader header = Marshal.ByteArrayToStructureBigEndian<HandyHeader>(headerBytes, 0, 64);
HandyHeader header = Marshal.ByteArrayToStructureBigEndianGenerated<HandyHeader>(headerBytes, 0, 64);
if(header.Version != 256) return ErrorNumber.NotSupported;
@@ -405,7 +406,7 @@ public class AtariLynx : IByteAddressableImage
return ErrorNumber.ReadOnly;
}
bool foundRom = false;
var foundRom = false;
// Sanitize
foreach(LinearMemoryDevice map in mappings.Devices)
@@ -516,9 +517,8 @@ public class AtariLynx : IByteAddressableImage
#region Nested type: HandyHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")]
struct HandyHeader
[SwapEndian]
partial struct HandyHeader
{
public uint Magic;
public short Bank0Length;

View File

@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Attributes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -16,7 +17,7 @@ using Marshal = Aaru.Helpers.Marshal;
namespace Aaru.Images;
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class GameBoy : IByteAddressableImage
public partial class GameBoy : IByteAddressableImage
{
byte[] _data;
Stream _dataStream;
@@ -59,9 +60,9 @@ public class GameBoy : IByteAddressableImage
if(stream.Length % 32768 != 0) return false;
stream.Position = 0x104;
byte[] magicBytes = new byte[8];
var magicBytes = new byte[8];
stream.EnsureRead(magicBytes, 0, 8);
ulong magic = BitConverter.ToUInt64(magicBytes, 0);
var magic = BitConverter.ToUInt64(magicBytes, 0);
return magic == 0x0B000DCC6666EDCE;
}
@@ -77,9 +78,9 @@ public class GameBoy : IByteAddressableImage
if(stream.Length % 512 != 0) return ErrorNumber.InvalidArgument;
stream.Position = 0x104;
byte[] magicBytes = new byte[8];
var magicBytes = new byte[8];
stream.EnsureRead(magicBytes, 0, 8);
ulong magic = BitConverter.ToUInt64(magicBytes, 0);
var magic = BitConverter.ToUInt64(magicBytes, 0);
if(magic != 0x0B000DCC6666EDCE) return ErrorNumber.InvalidArgument;
@@ -98,9 +99,9 @@ public class GameBoy : IByteAddressableImage
MetadataMediaType = MetadataMediaType.LinearMedia
};
Header header = Marshal.ByteArrayToStructureBigEndian<Header>(_data, 0x100, Marshal.SizeOf<Header>());
Header header = Marshal.ByteArrayToStructureBigEndianGenerated<Header>(_data, 0x100, Marshal.SizeOf<Header>());
byte[] name = new byte[(header.Name[^1] & 0x80) == 0x80 ? 15 : 16];
var name = new byte[(header.Name[^1] & 0x80) == 0x80 ? 15 : 16];
Array.Copy(header.Name, 0, name, 0, name.Length);
_imageInfo.MediaTitle = StringHandlers.CToString(name);
@@ -264,10 +265,10 @@ public class GameBoy : IByteAddressableImage
return ErrorNumber.NotOpened;
}
Header header = Marshal.ByteArrayToStructureBigEndian<Header>(_data, 0x100, Marshal.SizeOf<Header>());
Header header = Marshal.ByteArrayToStructureBigEndianGenerated<Header>(_data, 0x100, Marshal.SizeOf<Header>());
bool hasMapper = false;
bool hasSaveRam = false;
var hasMapper = false;
var hasSaveRam = false;
string mapperManufacturer = null;
string mapperName = null;
@@ -486,7 +487,7 @@ public class GameBoy : IByteAddressableImage
if(header.SramSize > 0) hasSaveRam = true;
int devices = 1;
var devices = 1;
if(hasSaveRam) devices++;
@@ -618,9 +619,9 @@ public class GameBoy : IByteAddressableImage
return ErrorNumber.ReadOnly;
}
bool foundRom = false;
bool foundSaveRam = false;
bool foundMapper = false;
var foundRom = false;
var foundSaveRam = false;
var foundMapper = false;
// Sanitize
foreach(LinearMemoryDevice map in mappings.Devices)
@@ -1030,8 +1031,8 @@ public class GameBoy : IByteAddressableImage
#region Nested type: Header
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")]
struct Header
[SwapEndian]
partial struct Header
{
/// <summary>Usually 0x00 (NOP)</summary>
public byte Opcode1;

View File

@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Attributes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -16,7 +17,7 @@ using Marshal = Aaru.Helpers.Marshal;
namespace Aaru.Images;
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class GameBoyAdvance : IByteAddressableImage
public partial class GameBoyAdvance : IByteAddressableImage
{
byte[] _data;
Stream _dataStream;
@@ -59,9 +60,9 @@ public class GameBoyAdvance : IByteAddressableImage
if(stream.Length % 32768 != 0) return false;
stream.Position = 4;
byte[] magicBytes = new byte[8];
var magicBytes = new byte[8];
stream.EnsureRead(magicBytes, 0, 8);
ulong magic = BitConverter.ToUInt64(magicBytes, 0);
var magic = BitConverter.ToUInt64(magicBytes, 0);
return magic == 0x21A29A6951AEFF24;
}
@@ -77,9 +78,9 @@ public class GameBoyAdvance : IByteAddressableImage
if(stream.Length % 512 != 0) return ErrorNumber.InvalidArgument;
stream.Position = 4;
byte[] magicBytes = new byte[8];
var magicBytes = new byte[8];
stream.EnsureRead(magicBytes, 0, 8);
ulong magic = BitConverter.ToUInt64(magicBytes, 0);
var magic = BitConverter.ToUInt64(magicBytes, 0);
if(magic != 0x21A29A6951AEFF24) return ErrorNumber.InvalidArgument;
@@ -97,7 +98,7 @@ public class GameBoyAdvance : IByteAddressableImage
MetadataMediaType = MetadataMediaType.LinearMedia
};
Header header = Marshal.ByteArrayToStructureBigEndian<Header>(_data, 0, Marshal.SizeOf<Header>());
Header header = Marshal.ByteArrayToStructureBigEndianGenerated<Header>(_data, 0, Marshal.SizeOf<Header>());
_imageInfo.MediaTitle = StringHandlers.CToString(header.Name);
@@ -353,8 +354,8 @@ public class GameBoyAdvance : IByteAddressableImage
return ErrorNumber.ReadOnly;
}
bool foundRom = false;
bool foundSaveRam = false;
var foundRom = false;
var foundSaveRam = false;
// Sanitize
foreach(LinearMemoryDevice map in mappings.Devices)
@@ -469,9 +470,8 @@ public class GameBoyAdvance : IByteAddressableImage
#region Nested type: Header
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")]
struct Header
[SwapEndian]
partial struct Header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] EntryPoint;

View File

@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Attributes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -16,7 +17,7 @@ using Marshal = Aaru.Helpers.Marshal;
namespace Aaru.Images;
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class MasterSystem : IByteAddressableImage
public partial class MasterSystem : IByteAddressableImage
{
byte[] _data;
Stream _dataStream;
@@ -61,9 +62,9 @@ public class MasterSystem : IByteAddressableImage
if(stream.Length % 8192 != 0) return false;
stream.Position = 0x7ff0;
byte[] magicBytes = new byte[8];
var magicBytes = new byte[8];
stream.EnsureRead(magicBytes, 0, 8);
ulong magic = BitConverter.ToUInt64(magicBytes, 0);
var magic = BitConverter.ToUInt64(magicBytes, 0);
if(magic == 0x4147455320524D54) return true;
@@ -95,9 +96,9 @@ public class MasterSystem : IByteAddressableImage
int headerPosition;
stream.Position = 0x7ff0;
byte[] magicBytes = new byte[8];
var magicBytes = new byte[8];
stream.EnsureRead(magicBytes, 0, 8);
ulong magic = BitConverter.ToUInt64(magicBytes, 0);
var magic = BitConverter.ToUInt64(magicBytes, 0);
if(magic != 0x0B000DCC6666EDCE)
headerPosition = 0x7ff0;
@@ -138,7 +139,8 @@ public class MasterSystem : IByteAddressableImage
MetadataMediaType = MetadataMediaType.LinearMedia
};
Header header = Marshal.ByteArrayToStructureBigEndian<Header>(_data, headerPosition, Marshal.SizeOf<Header>());
Header header =
Marshal.ByteArrayToStructureBigEndianGenerated<Header>(_data, headerPosition, Marshal.SizeOf<Header>());
var sb = new StringBuilder();
@@ -456,7 +458,7 @@ public class MasterSystem : IByteAddressableImage
return ErrorNumber.ReadOnly;
}
bool foundRom = false;
var foundRom = false;
// Sanitize
foreach(LinearMemoryDevice map in mappings.Devices)
@@ -567,9 +569,8 @@ public class MasterSystem : IByteAddressableImage
#region Nested type: Header
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
struct Header
[SwapEndian]
partial struct Header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Signature;

View File

@@ -38,6 +38,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Attributes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -51,7 +52,7 @@ namespace Aaru.Images;
/// <inheritdoc />
/// <summary>Implements support for Nintendo 64 cartridge dumps</summary>
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class Nintendo64 : IByteAddressableImage
public partial class Nintendo64 : IByteAddressableImage
{
byte[] _data;
Stream _dataStream;
@@ -100,9 +101,9 @@ public class Nintendo64 : IByteAddressableImage
if(stream.Length % 512 != 0) return false;
stream.Position = 0;
byte[] magicBytes = new byte[4];
var magicBytes = new byte[4];
stream.EnsureRead(magicBytes, 0, 4);
uint magic = BitConverter.ToUInt32(magicBytes, 0);
var magic = BitConverter.ToUInt32(magicBytes, 0);
return magic switch
{
@@ -129,9 +130,9 @@ public class Nintendo64 : IByteAddressableImage
if(stream.Length % 512 != 0) return ErrorNumber.InvalidArgument;
stream.Position = 0;
byte[] magicBytes = new byte[4];
var magicBytes = new byte[4];
stream.EnsureRead(magicBytes, 0, 4);
uint magic = BitConverter.ToUInt32(magicBytes, 0);
var magic = BitConverter.ToUInt32(magicBytes, 0);
switch(magic)
{
@@ -180,9 +181,9 @@ public class Nintendo64 : IByteAddressableImage
if(_littleEndian)
{
byte[] tmp = new byte[_data.Length];
var tmp = new byte[_data.Length];
for(int i = 0; i < _data.Length; i += 4)
for(var i = 0; i < _data.Length; i += 4)
{
tmp[i] = _data[i + 3];
tmp[i + 1] = _data[i + 2];
@@ -195,9 +196,9 @@ public class Nintendo64 : IByteAddressableImage
if(_interleaved)
{
byte[] tmp = new byte[_data.Length];
var tmp = new byte[_data.Length];
for(int i = 0; i < _data.Length; i += 2)
for(var i = 0; i < _data.Length; i += 2)
{
tmp[i] = _data[i + 1];
tmp[i + 1] = _data[i];
@@ -206,7 +207,7 @@ public class Nintendo64 : IByteAddressableImage
_data = tmp;
}
Header header = Marshal.ByteArrayToStructureBigEndian<Header>(_data, 0, Marshal.SizeOf<Header>());
Header header = Marshal.ByteArrayToStructureBigEndianGenerated<Header>(_data, 0, Marshal.SizeOf<Header>());
Encoding encoding;
try
@@ -305,7 +306,7 @@ public class Nintendo64 : IByteAddressableImage
LinearMemoryType saveType = LinearMemoryType.Unknown;
ulong saveLength = 0;
Header header = Marshal.ByteArrayToStructureBigEndian<Header>(_data, 0, Marshal.SizeOf<Header>());
Header header = Marshal.ByteArrayToStructureBigEndianGenerated<Header>(_data, 0, Marshal.SizeOf<Header>());
switch((char)header.CartridgeType)
{
@@ -676,8 +677,8 @@ public class Nintendo64 : IByteAddressableImage
return ErrorNumber.ReadOnly;
}
bool foundRom = false;
bool foundSaveRam = false;
var foundRom = false;
var foundSaveRam = false;
// Sanitize
foreach(LinearMemoryDevice map in mappings.Devices)
@@ -840,9 +841,9 @@ public class Nintendo64 : IByteAddressableImage
if(_interleaved)
{
byte[] tmp = new byte[_data.Length];
var tmp = new byte[_data.Length];
for(int i = 0; i < _data.Length; i += 2)
for(var i = 0; i < _data.Length; i += 2)
{
tmp[i] = _data[i + 1];
tmp[i + 1] = _data[i];
@@ -900,30 +901,30 @@ public class Nintendo64 : IByteAddressableImage
#region Nested type: Header
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
struct Header
[SwapEndian]
partial struct Header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public readonly byte[] Validation;
public readonly byte Compression;
public readonly byte Padding1;
public readonly uint ClockRate;
public readonly uint ProgramCounter;
public readonly uint ReleaseAddress;
public readonly uint Crc1;
public readonly uint Crc2;
public byte[] Validation;
public byte Compression;
public byte Padding1;
public uint ClockRate;
public uint ProgramCounter;
public uint ReleaseAddress;
public uint Crc1;
public uint Crc2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public readonly byte[] Padding2;
public byte[] Padding2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public readonly byte[] Name;
public byte[] Name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public readonly byte[] Padding3;
public byte[] Padding3;
/// <summary>'N' for cart, 'D' for 64DD, 'C' for expandable cart, 'E' for 64DD expansion, 'Z' for Aleck64</summary>
public readonly byte CartridgeType;
public byte CartridgeType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public readonly byte[] CartridgeId;
public readonly byte CountryCode;
public readonly byte Version;
public byte[] CartridgeId;
public byte CountryCode;
public byte Version;
}
#endregion

View File

@@ -38,6 +38,7 @@ using System.Runtime.InteropServices;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Attributes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
@@ -51,7 +52,7 @@ namespace Aaru.Images;
/// <inheritdoc />
/// <summary>Implements support for Sega Mega Drive, 32X, Genesis and Pico cartridge dumps</summary>
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class SegaMegaDrive : IByteAddressableImage
public partial class SegaMegaDrive : IByteAddressableImage
{
byte[] _data;
Stream _dataStream;
@@ -101,7 +102,7 @@ public class SegaMegaDrive : IByteAddressableImage
if(stream.Length % 512 != 0) return false;
byte[] buffer = new byte[4];
var buffer = new byte[4];
stream.Position = 256;
stream.EnsureRead(buffer, 0, 4);
@@ -142,7 +143,7 @@ public class SegaMegaDrive : IByteAddressableImage
if(stream.Length % 512 != 0) return ErrorNumber.InvalidArgument;
byte[] buffer = new byte[4];
var buffer = new byte[4];
stream.Position = 256;
stream.EnsureRead(buffer, 0, 4);
@@ -190,15 +191,15 @@ public class SegaMegaDrive : IByteAddressableImage
// Interleaves every 16KiB
if(_smd)
{
byte[] tmp = new byte[_data.Length];
byte[] bankIn = new byte[16384];
byte[] bankOut = new byte[16384];
var tmp = new byte[_data.Length];
var bankIn = new byte[16384];
var bankOut = new byte[16384];
for(int b = 0; b < _data.Length / 16384; b++)
for(var b = 0; b < _data.Length / 16384; b++)
{
Array.Copy(_data, b * 16384, bankIn, 0, 16384);
for(int i = 0; i < 8192; i++)
for(var i = 0; i < 8192; i++)
{
bankOut[i * 2 + 1] = bankIn[i];
bankOut[i * 2] = bankIn[i + 8192];
@@ -211,10 +212,10 @@ public class SegaMegaDrive : IByteAddressableImage
}
else if(_interleaved)
{
byte[] tmp = new byte[_data.Length];
int half = _data.Length / 2;
var tmp = new byte[_data.Length];
int half = _data.Length / 2;
for(int i = 0; i < half; i++)
for(var i = 0; i < half; i++)
{
tmp[i * 2] = _data[i];
tmp[i * 2 + 1] = _data[i + half];
@@ -224,7 +225,7 @@ public class SegaMegaDrive : IByteAddressableImage
}
SegaHeader header =
Marshal.ByteArrayToStructureBigEndian<SegaHeader>(_data, 0x100, Marshal.SizeOf<SegaHeader>());
Marshal.ByteArrayToStructureBigEndianGenerated<SegaHeader>(_data, 0x100, Marshal.SizeOf<SegaHeader>());
Encoding encoding;
@@ -404,10 +405,10 @@ public class SegaMegaDrive : IByteAddressableImage
if(_interleaved)
{
byte[] tmp = new byte[_data.Length];
int half = _data.Length / 2;
var tmp = new byte[_data.Length];
int half = _data.Length / 2;
for(int i = 0; i < half; i++)
for(var i = 0; i < half; i++)
{
tmp[i] = _data[i * 2];
tmp[i + half] = _data[i * 2 + 1];
@@ -432,15 +433,15 @@ public class SegaMegaDrive : IByteAddressableImage
_dataStream.Write(smdHeader, 0, smdHeader.Length);
byte[] tmp = new byte[_data.Length];
byte[] bankIn = new byte[16384];
byte[] bankOut = new byte[16384];
var tmp = new byte[_data.Length];
var bankIn = new byte[16384];
var bankOut = new byte[16384];
for(int b = 0; b < _data.Length / 16384; b++)
for(var b = 0; b < _data.Length / 16384; b++)
{
Array.Copy(_data, b * 16384, bankIn, 0, 16384);
for(int i = 0; i < 8192; i++)
for(var i = 0; i < 8192; i++)
{
bankOut[i] = bankIn[i * 2 + 1];
bankOut[i + 8192] = bankIn[i * 2];
@@ -539,7 +540,7 @@ public class SegaMegaDrive : IByteAddressableImage
}
SegaHeader header =
Marshal.ByteArrayToStructureBigEndian<SegaHeader>(_data, 0x100, Marshal.SizeOf<SegaHeader>());
Marshal.ByteArrayToStructureBigEndianGenerated<SegaHeader>(_data, 0x100, Marshal.SizeOf<SegaHeader>());
bool extraRam = header.ExtraRamPresent[0] == 0x52 && header.ExtraRamPresent[1] == 0x41;
@@ -732,8 +733,8 @@ public class SegaMegaDrive : IByteAddressableImage
return ErrorNumber.ReadOnly;
}
bool foundRom = false;
bool foundSaveRam = false;
var foundRom = false;
var foundSaveRam = false;
// Sanitize
foreach(LinearMemoryDevice map in mappings.Devices)
@@ -848,9 +849,8 @@ public class SegaMegaDrive : IByteAddressableImage
#region Nested type: SegaHeader
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Local")]
struct SegaHeader
[SwapEndian]
partial struct SegaHeader
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
public byte[] SystemType;