/// <summary> /// Create a new, empty track with the specified format, sector size and sector count. /// </summary> /// <param name="format"></param> /// <param name="cylinder"></param> /// <param name="head"></param> /// <param name="sectorCount"></param> /// <param name="sectorSize"></param> public Track(Format format, int cylinder, int head, int sectorCount, int sectorSize) { _format = format; _cylinder = cylinder; _head = head; _sectorCount = sectorCount; _sectorSize = sectorSize; _sectors = new FloppySector[_sectorCount]; for (int i = 0; i < _sectorCount; i++) { _sectors[i] = new FloppySector(_sectorSize, _format); } }
/// <summary> /// Create a new track loaded from the given stream. The stream is expected to be positioned /// at the beginning of an IMD sector definition. /// </summary> /// <param name="s"></param> public Track(Stream s) { bool bCylMap = false; bool bHeadMap = false; _format = (Format)s.ReadByte(); _cylinder = s.ReadByte(); _head = s.ReadByte(); _sectorCount = s.ReadByte(); int sectorSizeIndex = s.ReadByte(); // Basic sanity check of values if (_format > Format.MFM250 || _cylinder > 77 || (_head & 0x3f) > 1 || sectorSizeIndex > _sectorSizes.Length - 1) { throw new InvalidOperationException("Invalid header data for track."); } _sectorSize = _sectorSizes[sectorSizeIndex]; bCylMap = (_head & 0x80) != 0; bHeadMap = (_head & 0x40) != 0; // Head is just the first bit. _head = (byte)(_head & 0x1); // // Read sector numbering // _sectorOrdering = new List <int>(_sectorCount); for (int i = 0; i < _sectorCount; i++) { _sectorOrdering.Add(s.ReadByte()); } // // At this time, cyl and head maps are not supported. // It's not expected any Star disk would use such a format. // if (bCylMap | bHeadMap) { throw new NotImplementedException("IMD Cylinder and Head maps not supported."); } // // Read the sector data in. // _sectors = new FloppySector[_sectorCount]; for (int i = 0; i < _sectorCount; i++) { SectorRecordType type = (SectorRecordType)s.ReadByte(); byte compressedData; switch (type) { case SectorRecordType.Unavailable: // Nothing, sectors left null. break; case SectorRecordType.Normal: case SectorRecordType.NormalDeleted: case SectorRecordType.NormalError: case SectorRecordType.DeletedError: _sectors[_sectorOrdering[i] - 1] = new FloppySector(_sectorSize, _format, s); break; case SectorRecordType.Compressed: case SectorRecordType.CompressedDeleted: case SectorRecordType.CompressedError: case SectorRecordType.CompressedDeletedError: compressedData = (byte)s.ReadByte(); // Fill sector with compressed data _sectors[_sectorOrdering[i] - 1] = new FloppySector(_sectorSize, _format, compressedData); break; default: throw new InvalidOperationException(String.Format("Unexpected IMD sector data type {0}", type)); } } }