/// <summary> /// Commits modified sector data back to the emulated disk. /// Intended to be called at the end of the sector / beginning of the next. /// </summary> private void CommitSector() { if (_pack == null) { return; } DiskSector sector = _pack.GetSector(_cylinder, _head, _sector); // Header (2 words data, 1 word cksum) for (int i = HeaderOffset + 1, j = 1; i < HeaderOffset + 3; i++, j--) { // actual data to be loaded from disk / cksum calculated sector.WriteHeader(j, _sectorData[i].Data); } // Label (8 words data, 1 word cksum) for (int i = LabelOffset + 1, j = 7; i < LabelOffset + 9; i++, j--) { // actual data to be loaded from disk / cksum calculated sector.WriteLabel(j, _sectorData[i].Data); } // sector data (256 words data, 1 word cksum) for (int i = DataOffset + 1, j = 255; i < DataOffset + 257; i++, j--) { // actual data to be loaded from disk / cksum calculated sector.WriteData(j, _sectorData[i].Data); } // // Commit it back to the pack. // _pack.CommitSector(sector); }
// // Sector management. We load in an entire track's worth of sectors at a time. // When the head or cylinder changes, UpdateTrackCache must be called. // private void UpdateTrackCache() { if (_pack != null) { if (_trackCache == null) { // // First time through, initialize the cache. // _trackCache = new DiskSector[_pack.Geometry.Sectors]; } else { // // Commit the sectors back to disk before loading in the new ones. // for (int i = 0; i < _trackCache.Length; i++) { _pack.CommitSector(_trackCache[i]); } } // // Load the new sectors for this track. // for (int i = 0; i < _trackCache.Length; i++) { _trackCache[i] = _pack.GetSector(_cylinder, _head, i); } } }
public void CommitSector(DiskSector sector) { // // Update the in-memory sector reference to point to this (possibly new) sector object. // if (sector.Modified) { _sectors[sector.Cylinder, sector.Head, sector.Sector] = sector; } }
private InMemoryDiskPack(DiskGeometry geometry, string path, bool load) { _packName = path; _geometry = geometry; _sectors = new DiskSector[_geometry.Cylinders, _geometry.Heads, _geometry.Sectors]; if (load) { // // Attempt to load in the specified image file. // using (FileStream imageStream = new FileStream(_packName, FileMode.Open, FileAccess.Read)) { try { for (int cylinder = 0; cylinder < _geometry.Cylinders; cylinder++) { for (int head = 0; head < _geometry.Heads; head++) { for (int sector = 0; sector < _geometry.Sectors; sector++) { _sectors[cylinder, head, sector] = new DiskSector(_geometry.SectorGeometry, imageStream, cylinder, head, sector); } } } if (imageStream.Position != imageStream.Length) { throw new InvalidOperationException("Extra data at end of image file."); } } finally { imageStream.Close(); } } } else { // // Just initialize a new, empty disk. // for (int cylinder = 0; cylinder < _geometry.Cylinders; cylinder++) { for (int head = 0; head < _geometry.Heads; head++) { for (int sector = 0; sector < _geometry.Sectors; sector++) { _sectors[cylinder, head, sector] = new DiskSector(_geometry.SectorGeometry, cylinder, head, sector); } } } } }
public void CommitSector(DiskSector sector) { if (sector.Modified) { // // Commit this data back to disk. // Seek to the appropriate position and flush. // _diskStream.Position = GetOffsetForSector(sector.Cylinder, sector.Head, sector.Sector); sector.WriteToStream(_diskStream); } }
private void LoadSector() { if (_pack == null) { return; } // // Pull data off disk and pack it into our faked-up sector. // Note that this data is packed in in REVERSE ORDER because that's // how it gets written out and it's how the Alto expects it to be read back in. // DiskSector sector = _pack.GetSector(_cylinder, _head, _sector); // Header (2 words data, 1 word cksum) for (int i = HeaderOffset + 1, j = 1; i < HeaderOffset + 3; i++, j--) { // actual data to be loaded from disk / cksum calculated _sectorData[i] = new DataCell(sector.ReadHeader(j), CellType.Data); } ushort checksum = CalculateChecksum(_sectorData, HeaderOffset + 1, 2); _sectorData[HeaderOffset + 3].Data = checksum; Log.Write(LogType.Verbose, LogComponent.DiskController, "Header checksum for C/H/S {0}/{1}/{2} is {3}", _cylinder, _head, _sector, Conversion.ToOctal(checksum)); // Label (8 words data, 1 word cksum) for (int i = LabelOffset + 1, j = 7; i < LabelOffset + 9; i++, j--) { // actual data to be loaded from disk / cksum calculated _sectorData[i] = new DataCell(sector.ReadLabel(j), CellType.Data); } checksum = CalculateChecksum(_sectorData, LabelOffset + 1, 8); _sectorData[LabelOffset + 9].Data = checksum; Log.Write(LogType.Verbose, LogComponent.DiskController, "Label checksum for C/H/S {0}/{1}/{2} is {3}", _cylinder, _head, _sector, Conversion.ToOctal(checksum)); // sector data (256 words data, 1 word cksum) for (int i = DataOffset + 1, j = 255; i < DataOffset + 257; i++, j--) { // actual data to be loaded from disk / cksum calculated _sectorData[i] = new DataCell(sector.ReadData(j), CellType.Data); } checksum = CalculateChecksum(_sectorData, DataOffset + 1, 256); _sectorData[DataOffset + 257].Data = checksum; Log.Write(LogType.Verbose, LogComponent.DiskController, "Data checksum for C/H/S {0}/{1}/{2} is {3}", _cylinder, _head, _sector, Conversion.ToOctal(checksum)); }