diff --git a/Aaru.Images/DiskCopy42/DiskCopy42.cs b/Aaru.Images/DiskCopy42/DiskCopy42.cs index febbb62dd..0b75a057c 100644 --- a/Aaru.Images/DiskCopy42/DiskCopy42.cs +++ b/Aaru.Images/DiskCopy42/DiskCopy42.cs @@ -43,6 +43,13 @@ namespace Aaru.Images; [SuppressMessage("ReSharper", "InconsistentNaming")] public sealed partial class DiskCopy42 : IWritableImage, IVerifiableImage { + enum TwiggyMode + { + None, + MacTwiggyReordered, + LisaTwiggyLogical + } + const string MODULE_NAME = "DiskCopy 4.2 plugin"; /// Bytes per tag, should be 12 uint bptag; @@ -55,7 +62,7 @@ public sealed partial class DiskCopy42 : IWritableImage, IVerifiableImage ImageInfo imageInfo; /// Start of tags in disk image, after data sectors uint tagOffset; - bool twiggy; + TwiggyMode twiggyMode; byte[] twiggyCache; byte[] twiggyCacheTags; FileStream writingStream; @@ -85,4 +92,4 @@ public sealed partial class DiskCopy42 : IWritableImage, IVerifiableImage }; ~DiskCopy42() => Close(); -} \ No newline at end of file +} diff --git a/Aaru.Images/DiskCopy42/Read.cs b/Aaru.Images/DiskCopy42/Read.cs index 7559a5d43..5ca8991b5 100644 --- a/Aaru.Images/DiskCopy42/Read.cs +++ b/Aaru.Images/DiskCopy42/Read.cs @@ -54,6 +54,7 @@ public sealed partial class DiskCopy42 public ErrorNumber Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); + twiggyMode = TwiggyMode.None; stream.Seek(0, SeekOrigin.Begin); var buffer = new byte[0x58]; var pString = new byte[64]; @@ -191,7 +192,6 @@ public sealed partial class DiskCopy42 twiggyCache = new byte[header.DataSize]; twiggyCacheTags = new byte[header.TagSize]; - twiggy = true; Stream dataStream = imageFilter.GetDataForkStream(); dataStream.Seek(dataOffset, SeekOrigin.Begin); @@ -208,6 +208,7 @@ public sealed partial class DiskCopy42 if(mfsMagic == 0xD2D7 && mfsAllBlocks == 422) { AaruLogging.Debug(MODULE_NAME, Localization.Macintosh_Twiggy_detected_reversing_disk_sides); + twiggyMode = TwiggyMode.MacTwiggyReordered; Array.Copy(data, header.DataSize / 2, twiggyCache, 0, header.DataSize / 2); Array.Copy(tags, header.TagSize / 2, twiggyCacheTags, 0, header.TagSize / 2); Array.Copy(data, 0, twiggyCache, header.DataSize / 2, header.DataSize / 2); @@ -215,42 +216,69 @@ public sealed partial class DiskCopy42 } else { - AaruLogging.Debug(MODULE_NAME, Localization.Lisa_Twiggy_detected_reversing_second_half_of_disk); + int[] sectorsPerTrack = + [ + 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, + 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15 + ]; + int[] trackOffsets = new int[sectorsPerTrack.Length]; + + for(int i = 1; i < trackOffsets.Length; i++) + trackOffsets[i] = trackOffsets[i - 1] + sectorsPerTrack[i - 1]; + + AaruLogging.Debug(MODULE_NAME, "Lisa Twiggy detected exposing logical sector order"); + twiggyMode = TwiggyMode.LisaTwiggyLogical; Array.Copy(data, 0, twiggyCache, 0, header.DataSize / 2); Array.Copy(tags, 0, twiggyCacheTags, 0, header.TagSize / 2); - var copiedSectors = 0; - var sectorsToCopy = 0; + int destinationSector = (int)(header.DataSize / 2 / 512); - for(var i = 0; i < 46; i++) + for(int i = sectorsPerTrack.Length - 1; i >= 24; i--) { - sectorsToCopy = i switch - { - >= 0 and <= 3 => 22, - <= 10 => 21, - <= 16 => 20, - <= 22 => 19, - <= 28 => 18, - <= 34 => 17, - <= 41 => 16, - <= 45 => 15 - }; - Array.Copy(data, - header.DataSize / 2 + copiedSectors * 512, + header.DataSize / 2 + trackOffsets[i] * 512, twiggyCache, - twiggyCache.Length - copiedSectors * 512 - sectorsToCopy * 512, - sectorsToCopy * 512); + destinationSector * 512, + sectorsPerTrack[i] * 512); Array.Copy(tags, - header.TagSize / 2 + copiedSectors * bptag, + header.TagSize / 2 + trackOffsets[i] * bptag, twiggyCacheTags, - twiggyCacheTags.Length - copiedSectors * bptag - sectorsToCopy * bptag, - sectorsToCopy * bptag); + destinationSector * bptag, + sectorsPerTrack[i] * bptag); - copiedSectors += sectorsToCopy; + destinationSector += sectorsPerTrack[i]; } + + for(int i = 22; i >= 0; i--) + { + Array.Copy(data, + header.DataSize / 2 + trackOffsets[i] * 512, + twiggyCache, + destinationSector * 512, + sectorsPerTrack[i] * 512); + + Array.Copy(tags, + header.TagSize / 2 + trackOffsets[i] * bptag, + twiggyCacheTags, + destinationSector * bptag, + sectorsPerTrack[i] * bptag); + + destinationSector += sectorsPerTrack[i]; + } + + Array.Copy(data, + header.DataSize / 2 + trackOffsets[23] * 512, + twiggyCache, + destinationSector * 512, + sectorsPerTrack[23] * 512); + + Array.Copy(tags, + header.TagSize / 2 + trackOffsets[23] * bptag, + twiggyCacheTags, + destinationSector * bptag, + sectorsPerTrack[23] * bptag); } } @@ -425,7 +453,7 @@ public sealed partial class DiskCopy42 buffer = new byte[length * imageInfo.SectorSize]; sectorStatus = Enumerable.Repeat(SectorStatus.Dumped, (int)length).ToArray(); - if(twiggy) + if(twiggyMode != TwiggyMode.None) { Array.Copy(twiggyCache, (int)sectorAddress * imageInfo.SectorSize, @@ -461,7 +489,7 @@ public sealed partial class DiskCopy42 buffer = new byte[length * bptag]; - if(twiggy) + if(twiggyMode != TwiggyMode.None) Array.Copy(twiggyCacheTags, (int)sectorAddress * bptag, buffer, 0, length * bptag); else { @@ -520,4 +548,4 @@ public sealed partial class DiskCopy42 } #endregion -} \ No newline at end of file +} diff --git a/Aaru.Images/DiskCopy42/Write.cs b/Aaru.Images/DiskCopy42/Write.cs index 58b8e3ae9..1e3cf67ee 100644 --- a/Aaru.Images/DiskCopy42/Write.cs +++ b/Aaru.Images/DiskCopy42/Write.cs @@ -82,7 +82,7 @@ public sealed partial class DiskCopy42 case MediaType.AppleFileWare: header.FmtByte = kSigmaFmtByteTwiggy; header.Format = kSigmaFormatTwiggy; - twiggy = true; + twiggyMode = TwiggyMode.LisaTwiggyLogical; // TODO ErrorMessage = Localization.Twiggy_write_support_not_yet_implemented; @@ -485,4 +485,4 @@ public sealed partial class DiskCopy42 public bool SetMetadata(Metadata metadata) => false; #endregion -} \ No newline at end of file +}