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

View File

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

View File

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

View File

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

View File

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

View File

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