// /*************************************************************************** // The Disc Image Chef // ---------------------------------------------------------------------------- // // Filename : Definitions.cs // Author(s) : Natalia Portillo // // Component : CP/M filesystem plugin. // // --[ Description ] ---------------------------------------------------------- // // Handles definitions of known CP/M disks. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2018 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.Reflection; using System.Xml; using System.Xml.Serialization; namespace DiscImageChef.Filesystems.CPM { partial class CPM { /// /// Loads all the known CP/M disk definitions from an XML stored as an embedded resource. /// /// The definitions. bool LoadDefinitions() { try { XmlReader defsReader = XmlReader.Create(Assembly.GetExecutingAssembly() .GetManifestResourceStream("DiscImageChef.Filesystems.CPM.cpmdefs.xml") ?? throw new InvalidOperationException()); XmlSerializer defsSerializer = new XmlSerializer(typeof(CpmDefinitions)); definitions = (CpmDefinitions)defsSerializer.Deserialize(defsReader); // Patch definitions foreach(CpmDefinition def in definitions.definitions) { if(def.side1 == null) { def.side1 = new Side {sideId = 0, sectorIds = new int[def.sectorsPerTrack]}; for(int i = 0; i < def.sectorsPerTrack; i++) def.side1.sectorIds[i] = i + 1; } if(def.sides != 2 || def.side2 != null) continue; { def.side2 = new Side {sideId = 1, sectorIds = new int[def.sectorsPerTrack]}; for(int i = 0; i < def.sectorsPerTrack; i++) def.side2.sectorIds[i] = i + 1; } } return true; } catch { return false; } } } /// /// CP/M disk definitions /// class CpmDefinitions { /// /// Timestamp of creation of the CP/M disk definitions list /// public DateTime creation; /// /// List of all CP/M disk definitions /// public List definitions; } /// /// CP/M disk definition /// class CpmDefinition { /// /// Maps the first 16 allocation blocks for reservation, high byte /// public int al0; /// /// Maps the first 16 allocation blocks for reservation, low byte /// public int al1; /// /// Controller bitrate /// public string bitrate; /// /// Block mask for /// public int blm; /// /// Left shifts needed to translate allocation block number to lba /// public int bsh; /// /// Physical bytes per sector /// public int bytesPerSector; /// /// Comment and description /// public string comment; /// /// If true, all bytes written on disk are negated /// public bool complement; /// /// Total cylinders /// public int cylinders; /// /// Total number of available directory entries /// public int drm; /// /// Total number of 128 byte records on disk /// public int dsm; /// /// Encoding, "FM", "MFM", "GCR" /// public string encoding; /// /// Absolutely unknown? /// public bool evenOdd; /// /// Extent mask /// public int exm; /// /// Disk definition label /// public string label; /// /// Tracks at the beginning of disk reserved for BIOS/BDOS /// public int ofs; /// /// Cylinder/side ordering. SIDES = change side after each track, CYLINDERS = change side after whole side, EAGLE and /// COLUMBIA unknown /// public string order; /// /// Physical sectors per side /// public int sectorsPerTrack; /// /// Description of controller's side 0 (usually, upper side) /// public Side side1; /// /// Description of controller's side 1 (usually, lower side) /// public Side side2; /// /// Total sides /// public int sides; /// /// Physical sector interleaving /// public int skew; /// /// Sectors at the beginning of disk reserved for BIOS/BDOS /// public int sofs; } /// /// Side descriptions /// class Side { /// /// Software interleaving mask, [1,3,0,2] means CP/M LBA 0 is physical sector 1, LBA 1 = 3, so on /// public int[] sectorIds; /// /// Side ID as found in each sector address mark /// public int sideId; } }