示例#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;
            }

            DiabloDiskSector 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.Header[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.Label[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.Data[j] = _sectorData[i].Data;
            }
        }
示例#2
0
        public void Save(Stream imageStream)
        {
            for (int cylinder = 0; cylinder < _geometry.Cylinders; cylinder++)
            {
                for (int track = 0; track < _geometry.Tracks; track++)
                {
                    for (int sector = 0; sector < _geometry.Sectors; sector++)
                    {
                        byte[] header = new byte[4];        // 2 words
                        byte[] label  = new byte[16];       // 8 words
                        byte[] data   = new byte[512];      // 256 words

                        //
                        // Bitsavers images have an extra word in the header for some reason.
                        // We will follow this 'standard' when writing out.
                        // TODO: should support different formats ("correct" raw, Alto CopyDisk format, etc.)
                        //
                        byte[] dummy = new byte[2];
                        imageStream.Write(dummy, 0, 2);

                        DiabloDiskSector s = _sectors[cylinder, track, sector];

                        WriteWordBuffer(imageStream, s.Header);
                        WriteWordBuffer(imageStream, s.Label);
                        WriteWordBuffer(imageStream, s.Data);
                    }
                }
            }
        }
示例#3
0
 public DiabloPack(DiabloDiskType type)
 {
     _diskType = type;
     _packName = null;
     _geometry = new DiskGeometry(type == DiabloDiskType.Diablo31 ? 203 : 406, 2, 12);
     _sectors  = new DiabloDiskSector[_geometry.Cylinders, _geometry.Tracks, _geometry.Sectors];
 }
示例#4
0
        public void Load(Stream imageStream, string path, bool reverseByteOrder)
        {
            _packName = path;
            for (int cylinder = 0; cylinder < _geometry.Cylinders; cylinder++)
            {
                for (int track = 0; track < _geometry.Tracks; track++)
                {
                    for (int sector = 0; sector < _geometry.Sectors; sector++)
                    {
                        byte[] header = new byte[4];        // 2 words
                        byte[] label  = new byte[16];       // 8 words
                        byte[] data   = new byte[512];      // 256 words

                        //
                        // Bitsavers images have an extra word in the header for some reason.
                        // ignore it.
                        // TODO: should support different formats ("correct" raw, Alto CopyDisk format, etc.)
                        //
                        imageStream.Seek(2, SeekOrigin.Current);


                        if (imageStream.Read(header, 0, header.Length) != header.Length)
                        {
                            throw new InvalidOperationException("Short read while reading sector header.");
                        }

                        if (imageStream.Read(label, 0, label.Length) != label.Length)
                        {
                            throw new InvalidOperationException("Short read while reading sector label.");
                        }

                        if (imageStream.Read(data, 0, data.Length) != data.Length)
                        {
                            throw new InvalidOperationException("Short read while reading sector data.");
                        }

                        if (reverseByteOrder)
                        {
                            SwapBytes(header);
                            SwapBytes(label);
                            SwapBytes(data);
                        }

                        _sectors[cylinder, track, sector] = new DiabloDiskSector(header, label, data);
                    }
                }
            }

            if (imageStream.Position != imageStream.Length)
            {
                throw new InvalidOperationException("Extra data at end of image file.");
            }
        }
示例#5
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.
            //
            DiabloDiskSector 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.Header[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.Label[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.Data[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));
        }