/***************************************************************************
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
}
}