diff --git a/ChangeLog b/ChangeLog index b5b47c3..fe88f1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-10-30 Natalia Portillo + + * SCSI/Modes.cs: + Implement decoding mode page 0Dh. + 2015-10-30 Natalia Portillo * SCSI/Modes.cs: diff --git a/SCSI/Modes.cs b/SCSI/Modes.cs index 72c84c2..d3b8489 100644 --- a/SCSI/Modes.cs +++ b/SCSI/Modes.cs @@ -3009,6 +3009,134 @@ namespace DiscImageChef.Decoders.SCSI return sb.ToString(); } #endregion Mode Page 0x0E: CD-ROM audio control parameters page + + #region Mode Page 0x0D: CD-ROM parameteres page + /// + /// CD-ROM parameteres page + /// Page code 0x0D + /// 8 bytes in SCSI-2 + /// + public struct ModePage_0D + { + /// + /// Parameters can be saved + /// + public bool PS; + /// + /// Time the drive shall remain in hold track state after seek or read + /// + public byte InactivityTimerMultiplier; + /// + /// Seconds per Minute + /// + public ushort SecondsPerMinute; + /// + /// Frames per Second + /// + public ushort FramesPerSecond; + } + + public static ModePage_0D? DecodeModePage_0D(byte[] pageResponse) + { + if (pageResponse == null) + return null; + + if ((pageResponse[0] & 0x3F) != 0x0D) + return null; + + if (pageResponse[1] + 2 != pageResponse.Length) + return null; + + if (pageResponse.Length < 8) + return null; + + ModePage_0D decoded = new ModePage_0D(); + + decoded.PS |= (pageResponse[0] & 0x80) == 0x80; + decoded.InactivityTimerMultiplier = (byte)(pageResponse[3] & 0xF); + decoded.SecondsPerMinute = (ushort)((pageResponse[4] << 8) + pageResponse[5]); + decoded.FramesPerSecond = (ushort)((pageResponse[6] << 8) + pageResponse[7]); + + return decoded; + } + + public static string PrettifyModePage_0D(byte[] pageResponse) + { + return PrettifyModePage_0D(DecodeModePage_0D(pageResponse)); + } + + public static string PrettifyModePage_0D(ModePage_0D? modePage) + { + if (!modePage.HasValue) + return null; + + ModePage_0D page = modePage.Value; + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("SCSI CD-ROM parameters page:"); + + if (page.PS) + sb.AppendLine("\tParameters can be saved"); + switch (page.InactivityTimerMultiplier) + { + case 0: + sb.AppendLine("Drive will remain in track hold state a vendor-specified time after a seek or read"); + break; + case 1: + sb.AppendLine("Drive will remain in track hold state 125 ms after a seek or read"); + break; + case 2: + sb.AppendLine("Drive will remain in track hold state 250 ms after a seek or read"); + break; + case 3: + sb.AppendLine("Drive will remain in track hold state 500 ms after a seek or read"); + break; + case 4: + sb.AppendLine("Drive will remain in track hold state 1 second after a seek or read"); + break; + case 5: + sb.AppendLine("Drive will remain in track hold state 2 seconds after a seek or read"); + break; + case 6: + sb.AppendLine("Drive will remain in track hold state 4 seconds after a seek or read"); + break; + case 7: + sb.AppendLine("Drive will remain in track hold state 8 seconds after a seek or read"); + break; + case 8: + sb.AppendLine("Drive will remain in track hold state 16 seconds after a seek or read"); + break; + case 9: + sb.AppendLine("Drive will remain in track hold state 32 seconds after a seek or read"); + break; + case 10: + sb.AppendLine("Drive will remain in track hold state 1 minute after a seek or read"); + break; + case 11: + sb.AppendLine("Drive will remain in track hold state 2 minutes after a seek or read"); + break; + case 12: + sb.AppendLine("Drive will remain in track hold state 4 minutes after a seek or read"); + break; + case 13: + sb.AppendLine("Drive will remain in track hold state 8 minutes after a seek or read"); + break; + case 14: + sb.AppendLine("Drive will remain in track hold state 16 minutes after a seek or read"); + break; + case 15: + sb.AppendLine("Drive will remain in track hold state 32 minutes after a seek or read"); + break; + } + + if (page.SecondsPerMinute > 0) + sb.AppendFormat("Each minute has {0} seconds", page.SecondsPerMinute).AppendLine(); + if (page.FramesPerSecond > 0) + sb.AppendFormat("Each second has {0} frames", page.FramesPerSecond).AppendLine(); + + return sb.ToString(); + } + #endregion Mode Page 0x0D: CD-ROM parameteres page } }