Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        //
        // 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);
                }
            }
        }
Ejemplo n.º 3
0
 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;
     }
 }
Ejemplo n.º 4
0
        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);
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
 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);
     }
 }
Ejemplo n.º 6
0
        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));
        }