Esempio n. 1
0
        /*
         * Read SECTOR_DATA CHUNK type
         */
        bool _load_sector_data_chunk(chunk_header chunkhdr, AtxTrack track, BinaryReader reader)
        {
            int data_size = (int)chunkhdr.length - chunk_header_bytecount;

            if (track.sector_count > 0 && track.sectors.Any() == false)
            {
                Console.WriteLine($"\tWARNING:: SECTOR_DATA chunk presented before SECTOR_LIST chunk");
            }
            else
            {
                int    actual_sectors  = 0;
                string missing_sectors = "";
                foreach (var s in track.sectors)
                {
                    if ((s.status & (byte)SectorStatus.MISSING_DATA) == 0)
                    {
                        actual_sectors++;
                    }
                    else
                    {
                        missing_sectors = "; missing sectors accounted for";
                    }
                }
                int calculated_bytes = actual_sectors * _sector_size;

                if (data_size != calculated_bytes)
                {
                    Console.WriteLine($"\tWARNING:: Chunk data size as given in header ({data_size:N0}) != expected size ({actual_sectors} * {_sector_size} = {calculated_bytes:N0}){missing_sectors}");
                }
            }

            Console.WriteLine($"\tReading {data_size:N0} bytes of track sector data");

            try
            {
                track.data = reader.ReadBytes(data_size);
            }
            catch
            {
                Console.WriteLine($"\tERROR:: Failed to read sector data");
                return(false);
            }

            /*
             * The start_data value in each sector header is an offset into the overall Track Record,
             * including headers and other chunks that preceed it, where that sector's actual data begins
             * in the data chunk.
             *
             * We record the number of bytes into the Track Record the data chunk begins so we
             * can adjust the start_data value later when we want to read the right section from this
             * array of bytes.
             */
            track.offset_to_data_start = track.record_bytes_read;
            // Keep a count of how many bytes we've read into the Track Record
            track.record_bytes_read += data_size;

            _sector_data_bytes += data_size;

            return(true);
        }
Esempio n. 2
0
        /*
         * Read EXTENDED_DATA CHUNK type
         */
        bool _load_extended_sector_chunk(chunk_header chunkhdr, AtxTrack track, BinaryReader reader)
        {
            if (chunkhdr.length != chunk_header_bytecount)
            {
                Console.WriteLine($"\tERROR:: Chunk length {chunkhdr.length} != expected ({chunk_header_bytecount})");
            }

            if (chunkhdr.sector_index >= track.sector_count)
            {
                Console.WriteLine("\tERROR:: Extended sector index > track sector count");
                return(false);
            }

            UInt16 xsize;

            switch ((ExtendedSize)chunkhdr.header_data)
            {
            case ExtendedSize.EXTENDEDSIZE_128:
                xsize = 128;
                break;

            case ExtendedSize.EXTENDEDSIZE_256:
                xsize = 256;
                break;

            case ExtendedSize.EXTENDEDSIZE_512:
                xsize = 512;
                break;

            case ExtendedSize.EXTENDEDSIZE_1024:
                xsize = 1024;
                break;

            default:
                Console.WriteLine($"\tERROR:: Invalid extended sector value {chunkhdr.header_data}");
                return(false);
            }

            track.sectors[chunkhdr.sector_index].extendedsize = xsize;

            int sector_number         = track.sectors[chunkhdr.sector_index].number;
            int overall_sector_number = track.track_number * _sectors_per_track + sector_number;

            Console.WriteLine($"\tExtended sector: index={chunkhdr.sector_index}, num={sector_number} ({overall_sector_number}, ${overall_sector_number:x3}), size={xsize}");

            return(true);
        }
Esempio n. 3
0
        /*
         * Read WEAK_SECTOR CHUNK type
         */
        bool _load_weak_sector_chunk(chunk_header chunkhdr, AtxTrack track, BinaryReader reader)
        {
            if (chunkhdr.length != chunk_header_bytecount)
            {
                Console.WriteLine($"\tERROR:: Chunk length {chunkhdr.length} != expected ({chunk_header_bytecount})");
            }
            if (chunkhdr.sector_index >= track.sector_count)
            {
                Console.WriteLine("\tERROR:: Weak sector index > track sector count");
                return(false);
            }

            track.sectors[chunkhdr.sector_index].weakoffset = chunkhdr.header_data;

            int sector_number         = track.sectors[chunkhdr.sector_index].number;
            int overall_sector_number = track.track_number * _sectors_per_track + sector_number;

            Console.WriteLine($"\tWeak sector: index={chunkhdr.sector_index}, num={sector_number} ({overall_sector_number}, ${overall_sector_number:x3}), offset={chunkhdr.header_data}");

            return(true);
        }
Esempio n. 4
0
 /*
  * Read UNKNOWN CHUNK type
  */
 bool _load_unknown_chunk(chunk_header chunkhdr, BinaryReader reader)
 {
     Console.WriteLine($"WARNING:: Unknown chunk type");
     return(true);
 }
Esempio n. 5
0
        /*
         * Read SECTOR_LIST CHUNK type
         */
        bool _load_sector_list_chunk(chunk_header chunkhdr, AtxTrack track, BinaryReader reader)
        {
            int expected = chunk_header_bytecount + track.sector_count * sector_header_bytecount;

            if (chunkhdr.length != expected)
            {
                Console.WriteLine($"\tWARNING:: Chunk length {chunkhdr.length} != expected ({expected})");
            }

            // Try to read sector data for sector_count sectors
            for (int i = 0; i < track.sector_count; i++)
            {
                AtxSector sect = new AtxSector();
                try
                {
                    sect.number     = reader.ReadByte();
                    sect.status     = reader.ReadByte();
                    sect.position   = reader.ReadUInt16();
                    sect.start_data = reader.ReadUInt32();

                    track.record_bytes_read += sector_header_bytecount;
                }
                catch
                {
                    Console.WriteLine($"\tERROR:: Failed to read sector list header for sector at index {i}");
                    return(false);
                }

                int    overall_sector_number = track.track_number * _sectors_per_track + sect.number;
                string overall = $"({overall_sector_number}, ${overall_sector_number:x3})";

                if (sect.status != 0)
                {
                    Console.Write($"\tSector index={i}, num={sect.number} {overall}, flags=");
                    if ((sect.status & (byte)SectorStatus.DELETED) != 0)
                    {
                        Console.Write("DELETED ");
                    }
                    if ((sect.status & (byte)SectorStatus.MISSING_DATA) != 0)
                    {
                        Console.Write("MISSING_DATA ");
                    }
                    if ((sect.status & (byte)SectorStatus.EXTENDED) != 0)
                    {
                        Console.Write("EXTENDED ");
                    }
                    if ((sect.status & (byte)SectorStatus.FDC_CRC_ERROR) != 0)
                    {
                        Console.Write("CRC_ERROR ");
                    }
                    if ((sect.status & (byte)SectorStatus.FDC_LOSTDATA_ERROR) != 0)
                    {
                        Console.Write("LOSTDATA_ERROR");
                    }
                    if ((sect.status & (byte)SectorStatus.FDC_DATAREQ_PENDING) != 0)
                    {
                        Console.Write("DATAREQ_PENDING");
                    }
                    Console.WriteLine();

                    if ((sect.status & ~(byte)(SectorStatus.DELETED | SectorStatus.MISSING_DATA |
                                               SectorStatus.EXTENDED | SectorStatus.FDC_CRC_ERROR |
                                               SectorStatus.FDC_DATAREQ_PENDING | SectorStatus.FDC_LOSTDATA_ERROR)) != 0)
                    {
                        Console.WriteLine($"\tWARNING:: Unknown sector status flag 0x{sect.status:X2}");
                    }
                }

                if (sect.number > _sectors_per_track)
                {
                    Console.WriteLine($"\tWARNING:: Sector index={i}, number={sect.number} > {_sectors_per_track}");
                }
                if (sect.number == 0)
                {
                    Console.WriteLine($"\tWARNING:: Sector index={i} has sector #0");
                }

                if (sect.position >= ANGULAR_UNIT_COUNT)
                {
                    Console.WriteLine($"\tWARNING:: Sector index={i}, num={sect.number} {overall}, angular position {sect.position} > {ANGULAR_UNIT_COUNT - 1}");
                }


                // See if this is a duplicate
                foreach (var s in track.sectors)
                {
                    if (s.number == sect.number)
                    {
                        Console.WriteLine($"\tDUPLICATE sector #{sect.number:D2} {overall}");
                        break;
                    }
                }

                // Add to the list
                track.sectors.Add(sect);
            }

            Console.WriteLine($"\tRead {track.sectors.Count} sector headers for track {track.track_number}");

            // Report on any missing sectors
            for (int i = 1; i <= _sectors_per_track; i++)
            {
                if (track.sectors.Find(x => x.number == i) == null)
                {
                    Console.WriteLine($"\tMISSING sector #{i}");
                }
            }

            return(true);
        }