Exemple #1
0
        private List <SectorDescriptor> GetSectorDescriptorCache()
        {
            var sds = new List <SectorDescriptor>();

            for (int SectorIndex = 0; SectorIndex < HEADER_LENGTH && Header[SectorIndex] > 0; SectorIndex++)
            {
                bool density      = Header[SectorIndex] >= DOUBLE_DENSITY_MASK;
                int  byteMultiple = density ? 1 : 2;
                int  offset       = (Header[SectorIndex] & OFFSET_MASK) - HEADER_LENGTH_BYTES;
                if (data[offset] != Floppy.IDAM)
                {
                    continue;
                }

                byte trackNum  = data[offset + 1 * byteMultiple];
                bool sideOne   = data[offset + 2 * byteMultiple] > 0;
                byte sectorNum = data[offset + 3 * byteMultiple];

                byte dam       = 0x00;
                int  dataStart = 0x00;
                bool deleted   = false;
                for (int i = offset + 7 * byteMultiple; i < offset + (7 + (density ? 43 : 30)) * byteMultiple; i += byteMultiple)
                {
                    if (FloppyController.IsDAM(data[i], out deleted))
                    {
                        dam       = data[i];
                        dataStart = i + byteMultiple;
                        break;
                    }
                }

                var  sizeCode   = data[offset + 4 * byteMultiple];
                var  dataLength = Floppy.GetDataLengthFromCode(sizeCode);
                var  sectorData = new byte[dataLength];
                bool crcError;
                bool inUse;
                if (dam == 0x00)
                {
                    crcError = true;
                    inUse    = false;
                }
                else
                {
                    inUse = !deleted;
                    ushort actualCrc = Lib.Crc(density ? Floppy.CRC_RESET_A1_A1_A1 : Floppy.CRC_RESET, dam);
                    for (int i = 0; i < dataLength; i++)
                    {
                        sectorData[i] = data[dataStart + i * byteMultiple];
                        actualCrc     = Lib.Crc(actualCrc, sectorData[i]);
                    }
                    ushort recordedCrc = Lib.CombineBytes(data[dataStart + (dataLength + 1) * byteMultiple], data[dataStart + dataLength * byteMultiple]);
                    crcError = actualCrc != recordedCrc;
                }
                sds.Add(new SectorDescriptor(trackNum,
                                             sectorNum,
                                             sideOne,
                                             density,
                                             dam,
                                             sectorData,
                                             inUse,
                                             crcError));
            }
            return(sds.OrderBy(s => s.SectorNumber).ToList());
        }
Exemple #2
0
        private void SeekAddressData(byte ByteRead, OpStatus NextStatus, bool Check)
        {
            damBytesChecked++;
            switch (opStatus)
            {
            case OpStatus.SeekingIDAM:
                if (IndexesFound >= 5)
                {
                    SeekError = true;
                    opStatus  = OpStatus.NMI;
                }
                else
                {
                    switch (ByteRead)
                    {
                    case Floppy.IDAM:
                        if (track?.HasIdamAt(TrackDataIndex, DoubleDensitySelected) ?? false)
                        {
                            readAddressIndex = 0;
                            ResetCRC();
                            crc      = Lib.Crc(crc, ByteRead);
                            opStatus = OpStatus.ReadingAddressData;
                        }
                        idamBytesFound = 0;
                        break;

                    default:
                        idamBytesFound = 0;
                        break;
                    }
                }
                break;

            case OpStatus.ReadingAddressData:
                readAddressData[readAddressIndex] = ByteRead;
                if (readAddressIndex == ADDRESS_DATA_CRC_HIGH_BYTE - 1)
                {
                    // save the value before the first crc on the sector comes in
                    crcCalc = crc;
                }
                else if (readAddressIndex >= ADDRESS_DATA_CRC_LOW_BYTE)
                {
                    damBytesChecked = 0;

                    crcHigh  = readAddressData[ADDRESS_DATA_CRC_HIGH_BYTE];
                    crcLow   = readAddressData[ADDRESS_DATA_CRC_LOW_BYTE];
                    CrcError = crcCalc != Lib.CombineBytes(crcLow, crcHigh);

                    var match = (TrackRegister == readAddressData[ADDRESS_DATA_TRACK_REGISTER_BYTE] &&
                                 (!command.SideSelectVerify || (command.SideOneExpected == (readAddressData[ADDRESS_DATA_SIDE_ONE_BYTE] != 0))) &&
                                 (SectorRegister == readAddressData[ADDRESS_DATA_SECTOR_REGISTER_BYTE]));

                    if (Check && !match)
                    {
                        opStatus = OpStatus.SeekingIDAM;
                    }
                    else
                    {
                        sectorLength = Floppy.GetDataLengthFromCode(readAddressData[ADDRESS_DATA_SECTOR_SIZE_BYTE]);

                        if (CrcError)
                        {
                            opStatus = OpStatus.SeekingIDAM;
                        }
                        else
                        {
                            opStatus = NextStatus;
                        }
                    }
                }
                readAddressIndex++;
                break;

            default:
                throw new Exception();
            }
        }
Exemple #3
0
        private ushort[] RebuildHeader()
        {
            var header = new ushort[HEADER_LENGTH];

            int headerCursor = 0;

            int end = data.Length - 10;
            int i   = 4;

            while (i < end)
            {
                bool density = GetDensity(i);

                if (data[i] == Floppy.IDAM)
                {
                    // is it a real IDAM? Check preceding bytes
                    if (density)
                    {
                        if (data[i - 1] != 0xA1 || data[i - 2] != 0xA1 || data[i - 3] != 0xA1)
                        {
                            i++;
                            continue;
                        }
                    }
                    else
                    {
                        if (data[i - 2] != 0x00)
                        {
                            i += 2;
                            continue;
                        }
                    }

                    // commit without checking address crc, since could be intentional error
                    header[headerCursor++] = (ushort)(i + HEADER_LENGTH_BYTES + (density ? DOUBLE_DENSITY_MASK : 0));

                    // now skip forward past the sector contents
                    // advance to length
                    if (density)
                    {
                        i += 4;
                    }
                    else
                    {
                        i += 8;
                    }
                    i += Floppy.GetDataLengthFromCode(data[i]) * (density ? 1 : 2);
                    i += 20 * (density ? 1 : 2); // filler minimum
                }
                else
                {
                    if (density)
                    {
                        i++;
                    }
                    else
                    {
                        i += 2;
                    }
                }
            }
            this.header = header;
            return(this.header);
        }