/*************************************************************************** The Disc Image Chef ---------------------------------------------------------------------------- Filename : BD.cs Version : 1.0 Author(s) : Natalia Portillo Component : Decoders. Revision : $Revision$ Last change by : $Author$ Date : $Date$ --[ Description ] ---------------------------------------------------------- Decodes DVD structures. --[ License ] -------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ---------------------------------------------------------------------------- Copyright (C) 2011-2014 Claunia.com ****************************************************************************/ //$Id$ using System; using System.Runtime.InteropServices; namespace DiscImageChef.Decoders { // Information from: // National Semiconductor PC87332VLJ datasheet // SMsC FDC37C78 datasheet // Intel 82078 datasheet // Intel 82077AA datasheet // Toshiba TC8566AF datasheet // Fujitsu MB8876A datasheet // Inside Macintosh, Volume II, ISBN 0-201-17732-3 // ECMA-147 // ECMA-100 public static class Floppy { #region Public enumerations /// /// In-sector code for sector size /// public enum IBMSectorSizeCode : byte { /// /// 128 bytes/sector /// EighthKilo = 0, /// /// 256 bytes/sector /// QuarterKilo = 1, /// /// 512 bytes/sector /// HalfKilo = 2, /// /// 1024 bytes/sector /// Kilo = 3, /// /// 2048 bytes/sector /// TwiceKilo = 4, /// /// 4096 bytes/sector /// FriceKilo = 5, /// /// 8192 bytes/sector /// TwiceFriceKilo = 6, /// /// 16384 bytes/sector /// FricelyFriceKilo = 7 } public enum IBMIdType : byte { IndexMark = 0xFC, AddressMark = 0xFE, DataMark = 0xFB, DeletedDataMark = 0xF8 } public enum AppleEncodedFormat : byte { /// /// Disk is an Apple II 3.5" disk /// AppleII = 0x96, /// /// Disk is an Apple Lisa 3.5" disk /// Lisa = 0x97, /// /// Disk is an Apple Macintosh single-sided 3.5" disk /// MacSingleSide = 0x9A, /// /// Disk is an Apple Macintosh double-sided 3.5" disk /// MacDoubleSide = 0xD9 } #endregion Public enumerations #region Public structures #region IBM System 3740 floppy /// /// Track format for IBM System 3740 floppy /// public struct IBMFMTrack { /// /// Start of track /// public IBMFMTrackPreamble trackStart; /// /// Track sectors /// public IBMFMSector[] sectors; /// /// Undefined size /// public byte[] gap; } /// /// Start of IBM PC FM floppy track /// public struct IBMFMTrackPreamble { /// /// Gap from index pulse, 80 bytes set to 0xFF /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public byte[] gap; /// /// 6 bytes set to 0x00 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] zero; /// /// Set to /// public IBMIdType type; /// /// Gap until first sector, 26 bytes to 0xFF /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)] public byte[] gap1; } /// /// Raw demodulated format for IBM System 3740 floppies /// public struct IBMFMSector { /// /// Sector address mark /// public IBMFMSectorAddressMark addressMark; /// /// 11 bytes set to 0xFF /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] innerGap; /// /// Sector data block /// public IBMFMSectorAddressMark dataBlock; /// /// Variable bytes set to 0xFF /// public byte[] outerGap; } /// /// Sector address mark for IBM System 3740 floppies, contains sync word /// public struct IBMFMSectorAddressMark { /// /// 6 bytes set to 0 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] zero; /// /// Set to /// public IBMIdType type; /// /// Track number /// public byte track; /// /// Side number /// public byte side; /// /// Sector number /// public byte sector; /// /// /// public IBMSectorSizeCode sectorSize; /// /// CRC16 from to end of /// public UInt16 crc; } /// /// Sector data block for IBM System 3740 floppies /// public struct IBMFMSectorDataBlock { /// /// 12 bytes set to 0 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] zero; /// /// Set to or to /// public IBMIdType type; /// /// User data /// public byte[] data; /// /// CRC16 from to end of /// public UInt16 crc; } #endregion IBM System 3740 floppy #region IBM System 34 floppy /// /// Track format for IBM System 34 floppy /// Used by IBM PC, Apple Macintosh (high-density only), and a lot others /// public struct IBMMFMTrack { /// /// Start of track /// public IBMMFMTrackPreamble trackStart; /// /// Track sectors /// public IBMMFMSector[] sectors; /// /// Undefined size /// public byte[] gap; } /// /// Start of IBM PC MFM floppy track /// Used by IBM PC, Apple Macintosh (high-density only), and a lot others /// public struct IBMMFMTrackPreamble { /// /// Gap from index pulse, 80 bytes set to 0x4E /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] gap; /// /// 12 bytes set to 0x00 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] zero; /// /// 3 bytes set to 0xC2 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] ctwo; /// /// Set to /// public IBMIdType type; /// /// Gap until first sector, 50 bytes to 0x4E /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] public byte[] gap1; } /// /// Raw demodulated format for IBM System 34 floppies /// public struct IBMMFMSector { /// /// Sector address mark /// public IBMMFMSectorAddressMark addressMark; /// /// 22 bytes set to 0x4E, set to 0x22 on Commodore 1581 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 22)] public byte[] innerGap; /// /// Sector data block /// public IBMMFMSectorAddressMark dataBlock; /// /// Variable bytes set to 0x4E, ECMA defines 54 /// public byte[] outerGap; } /// /// Sector address mark for IBM System 34 floppies, contains sync word /// public struct IBMMFMSectorAddressMark { /// /// 12 bytes set to 0 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] zero; /// /// 3 bytes set to 0xA1 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] aone; /// /// Set to /// public IBMIdType type; /// /// Track number /// public byte track; /// /// Side number /// public byte side; /// /// Sector number /// public byte sector; /// /// /// public IBMSectorSizeCode sectorSize; /// /// CRC16 from to end of /// public UInt16 crc; } /// /// Sector data block for IBM System 34 floppies /// public struct IBMMFMSectorDataBlock { /// /// 12 bytes set to 0 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] zero; /// /// 3 bytes set to 0xA1 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] aone; /// /// Set to or to /// public IBMIdType type; /// /// User data /// public byte[] data; /// /// CRC16 from to end of /// public UInt16 crc; } #endregion IBM System 34 floppy #region Perpendicular MFM floppy /// /// Perpendicular floppy track /// public struct PerpendicularFloppyTrack { /// /// Start of track /// public IBMMFMTrackPreamble trackStart; /// /// Track sectors /// public PerpendicularFloppySector[] sectors; /// /// Undefined size /// public byte[] gap; } /// /// Raw demodulated format for perpendicular floppies /// public struct PerpendicularFloppySector { /// /// Sector address mark /// public IBMMFMSectorAddressMark addressMark; /// /// 41 bytes set to 0x4E /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 41)] public byte[] innerGap; /// /// Sector data block /// public IBMMFMSectorDataBlock dataBlock; /// /// Variable-sized inter-sector gap, ECMA defines 83 bytes /// public byte[] outerGap; } #endregion Perpendicular MFM floppy #region ISO floppy /// /// ISO floppy track, also used by Atari ST and others /// public struct ISOFloppyTrack { /// /// Start of track, 32 bytes set to 0x4E /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] innerGap; /// /// Track sectors /// public IBMMFMSector[] sectors; /// /// Undefined size /// public byte[] gap; } #endregion ISO floppy #region Apple ][ GCR floppy /// /// GCR-encoded Apple ][ GCR floppy track /// public struct AppleOldGCRRawSectorRawTrack { /// /// Track preamble, set to self-sync 0xFF, between 40 and 95 bytes /// public byte[] gap; public AppleOldGCRRawSector[] sectors; } /// /// GCR-encoded Apple ][ GCR floppy sector /// public struct AppleOldGCRRawSector { /// /// Address field /// public AppleOldGCRRawAddressField addressField; /// /// Track preamble, set to self-sync 0xFF, between 5 and 10 bytes /// public byte[] innerGap; /// /// Data field /// public AppleOldGCRRawDataField dataField; /// /// Track preamble, set to self-sync 0xFF, between 14 and 24 bytes /// public byte[] gap; } /// /// GCR-encoded Apple ][ GCR floppy sector address field /// public struct AppleOldGCRRawAddressField { /// /// Always 0xD5, 0xAA, 0x96 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] prologue; /// /// Volume number encoded as: /// volume[0] = (decodedVolume >> 1) | 0xAA /// volume[1] = decodedVolume | 0xAA /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] volume; /// /// Track number encoded as: /// track[0] = (decodedTrack >> 1) | 0xAA /// track[1] = decodedTrack | 0xAA /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] track; /// /// Sector number encoded as: /// sector[0] = (decodedSector >> 1) | 0xAA /// sector[1] = decodedSector | 0xAA /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] sector; /// /// decodedChecksum = decodedVolume ^ decodedTrack ^ decodedSector /// checksum[0] = (decodedChecksum >> 1) | 0xAA /// checksum[1] = decodedChecksum | 0xAA /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] checksum; /// /// Always 0xDE, 0xAA, 0xEB /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] epilogue; } /// /// GCR-encoded Apple ][ GCR floppy sector data field /// public struct AppleOldGCRRawDataField { /// /// Always 0xD5, 0xAA, 0xAD /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] prologue; /// /// Encoded data bytes. /// 410 bytes for 5to3 (aka DOS 3.2) format /// 342 bytes for 6to2 (aka DOS 3.3) format /// public byte[] data; public byte checksum; /// /// Always 0xDE, 0xAA, 0xEB /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] epilogue; } #endregion Apple ][ GCR floppy #region Apple Sony GCR floppy /// /// GCR-encoded Apple Sony GCR floppy track /// public struct AppleSonyGCRRawSectorRawTrack { /// /// Track preamble, set to self-sync 0xFF, 36 bytes /// public byte[] gap; public AppleOldGCRRawSector[] sectors; } /// /// GCR-encoded Apple Sony GCR floppy sector /// public struct AppleSonyGCRRawSector { /// /// Address field /// public AppleSonyGCRRawAddressField addressField; /// /// Track preamble, set to self-sync 0xFF, 6 bytes /// public byte[] innerGap; /// /// Data field /// public AppleSonyGCRRawDataField dataField; /// /// Track preamble, set to self-sync 0xFF, unknown size /// public byte[] gap; } /// /// GCR-encoded Apple Sony GCR floppy sector address field /// public struct AppleSonyGCRRawAddressField { /// /// Always 0xD5, 0xAA, 0x96 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] prologue; /// /// Encoded (decodedTrack & 0x3F) /// public byte track; /// /// Encoded sector number /// public byte sector; /// /// Encoded side number /// public byte side; /// /// Disk format /// public AppleEncodedFormat format; /// /// Checksum /// public byte checksum; /// /// Always 0xDE, 0xAA /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] epilogue; } /// /// GCR-encoded Apple ][ GCR floppy sector data field /// public struct AppleSonyGCRRawDataField { /// /// Always 0xD5, 0xAA, 0xAD /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] prologue; /// /// Spare, usually /// public byte spare; /// /// Encoded data bytes. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 698)] public byte[] data; /// /// Checksum /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] checksum; /// /// Always 0xDE, 0xAA /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] epilogue; } #endregion Apple Sony GCR floppy #region Commodore GCR decoded /// /// Decoded Commodore GCR sector header /// public struct CommodoreSectorHeader { /// /// Always 0x08 /// public byte id; /// /// XOR of following fields /// public byte checksum; /// /// Sector number /// public byte sector; /// /// Track number /// public byte track; /// /// Format ID, unknown meaning /// public UInt16 format; /// /// Filled with 0x0F /// public UInt16 fill; } /// /// Decoded Commodore GCR sector data /// public struct CommodoreSectorData { /// /// Always 0x07 /// public byte id; /// /// User data /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte data; /// /// XOR of /// public byte checksum; /// /// Filled with 0x0F /// public UInt16 fill; } #endregion Commodore GCR decoded #region Commodore Amiga public struct CommodoreAmigaSector { /// /// Set to 0x00 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] zero; /// /// Set to 0xA1 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] sync; /// /// Set to 0xFF /// public byte amiga; /// /// Track number /// public byte track; /// /// Sector number /// public byte sector; /// /// Remaining sectors til end of writing /// public byte remaining; /// /// OS dependent tag /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] label; /// /// Checksum from to /// public UInt32 headerChecksum; /// /// Checksum from /// public UInt32 dataChecksum; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] data; } #endregion Commodore Amiga #endregion Public structures } }