예제 #1
0
파일: DMKImage.cs 프로젝트: wzydhek/EmuDisk
        public override void WriteSector(int track, int head, int sector, byte[] buffer)
        {
            int sectorLength = 0;
            int offset       = GetSectorOffset(track, head, sector, ref sectorLength);

            if (buffer.Length != sectorLength)
            {
                throw new IOException();
            }

            if (offset != 0 && sectorLength != 0)
            {
                byte[] crc = Crc16.ComputeChecksumBytes(0xE295, buffer);
                WriteBytes(offset, buffer);
                WriteByte(offset + buffer.Length, crc[1]);
                WriteByte(offset + buffer.Length + 1, crc[0]);
            }
        }
예제 #2
0
        /// <summary>
        /// Create DMK basic disk structure on disk image
        /// </summary>
        private void LowLevelFormat()
        {
            // Prepare blank sector data
            byte[] sectorData = new byte[this.PhysicalSectorSize];
            byte[] sectorCRC  = Crc16.ComputeChecksumBytes(0xe295, sectorData);

            for (int track = 0; track < this.PhysicalTracks; track++)
            {
                for (int head = 0; head < this.PhysicalHeads; head++)
                {
                    byte[] trackData = new byte[this.trackSize];

                    // First, create the IDAM table
                    byte[] idamtable = new byte[128];
                    for (int i = 0, sectorOffset = 0x80ab; i < this.PhysicalSectors; i++, sectorOffset += 338)
                    {
                        idamtable[i * 2]       = (byte)(sectorOffset & 0xff);
                        idamtable[(i * 2) + 1] = (byte)(sectorOffset >> 8);
                    }

                    Array.Copy(idamtable, 0, trackData, 0, idamtable.Length);

                    // Now lets make the track
                    Array.Copy(new byte[32].Initialize(0x4e), 0, trackData, idamtable.Length, 32);

                    // Lets create each sector
                    int interleavedSector = 1;
                    for (int sector = 1; sector < this.PhysicalSectors; sector++)
                    {
                        // Sector Preamble part
                        byte[] sectorPreamble = new byte[56].Initialize(0x4e);
                        Array.Copy(new byte[0x08], 0, sectorPreamble, 0, 0x08);
                        Array.Copy(new byte[0x03].Initialize(0xa1), 0, sectorPreamble, 0x08, 3);

                        byte[] sectorControl = new byte[] { 0xfe, (byte)track, (byte)head, (byte)sector, 0x01 };
                        Array.Copy(sectorControl, 0, sectorPreamble, 0x0b, 5);
                        byte[] sectorControlCRC = Crc16.ComputeChecksumBytes(0xcdb4, sectorControl);
                        sectorPreamble[0x10] = sectorControlCRC[1];
                        sectorPreamble[0x11] = sectorControlCRC[0];
                        Array.Copy(new byte[12], 0, sectorPreamble, 0x28, 12);
                        Array.Copy(new byte[3].Initialize(0xa1), 0, sectorPreamble, 0x34, 3);
                        sectorPreamble[0x37] = 0xfb;

                        // Sector Post-amble part
                        byte[] sectorPostamble = new byte[26].Initialize(0x4e);
                        sectorPostamble[0] = sectorCRC[1];
                        sectorPostamble[1] = sectorCRC[0];

                        // Write the parts to the track data
                        int trackOffset = idamtable.Length + ((interleavedSector - 1) * 338) + 32;
                        Array.Copy(sectorPreamble, 0, trackData, trackOffset, sectorPreamble.Length);
                        Array.Copy(sectorData, 0, trackData, trackOffset + 56, sectorData.Length);
                        Array.Copy(sectorPostamble, 0, trackData, trackOffset + 312, sectorPostamble.Length);

                        // Calculate next interleaved sector position
                        interleavedSector += this.Interleave;
                        if (interleavedSector > this.PhysicalSectors)
                        {
                            interleavedSector -= this.PhysicalSectors;
                        }

                        if (interleavedSector < this.Interleave)
                        {
                            interleavedSector++;
                        }
                    }

                    // Write out the track
                    this.WriteBytes(this.HeaderLength + (track * this.PhysicalHeads * this.trackSize) + (head * this.trackSize), trackData);
                }
            }
        }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Crc16CalculatorStream"/> class.
 /// </summary>
 /// <param name="stream">Base stream to perform operations on</param>
 /// <param name="length">Maximum number of stream bytes to process</param>
 /// <param name="leaveOpen">Leave the base stream open once operations are complete</param>
 /// <param name="crc16">Initial crc register value</param>
 public Crc16CalculatorStream(System.IO.Stream stream, long length, bool leaveOpen, Crc16 crc16)
     : this(leaveOpen, length, stream, crc16)
 {
     if (length < 0)
     {
         throw new ArgumentException("length");
     }
 }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Crc16CalculatorStream"/> class.
 /// </summary>
 /// <param name="leaveOpen">Leave the base stream open once operations are complete</param>
 /// <param name="length">Maximum number of stream bytes to process</param>
 /// <param name="stream">Base stream to perform operations on</param>
 /// <param name="crc16">Initial crc register value</param>
 private Crc16CalculatorStream(bool leaveOpen, long length, System.IO.Stream stream, Crc16 crc16)
     : base()
 {
     this.innerStream = stream;
     this.crc16       = crc16 ?? new Crc16();
     this.lengthLimit = length;
     this.leaveOpen   = leaveOpen;
 }
예제 #5
0
파일: DMKImage.cs 프로젝트: wzydhek/EmuDisk
        private int GetSectorOffset(int track, int head, int sector, ref int sectorsize)
        {
            int offset = 0;

            sectorsize = 0;

            int trackoffset = this.HeaderLength + (track * this.PhysicalHeads * this.trackLength) + (head * this.trackLength);
            int idamOffset  = 0;
            int i           = 0;

            byte[] idam = new byte[0];

            // Search for sector
            for (i = 0; i < DMK_TOK_LEN; i++)
            {
                idamOffset = ((this.ReadByte(trackoffset + (i * 2) + 1) << 8) + this.ReadByte(trackoffset + (i * 2))) & 0x3fff;
                if (idamOffset == 0)
                {
                    i = DMK_TOK_LEN;
                    break;
                }

                if ((idamOffset + DMK_IDAM_LENGTH) > trackLength)
                {
                    continue;
                }

                int idamCRC = (this.ReadByte(trackoffset + idamOffset + 5) << 8) + this.ReadByte(trackoffset + idamOffset + 6);
                idam = this.ReadBytes(trackoffset + idamOffset, DMK_IDAM_LENGTH - 2);
                int calcCRC = Crc16.ComputeChecksum(0xCDB4, idam);
                if (idamCRC == calcCRC)
                {
                    if (sector == idam[3] && track == idam[1] && head == idam[2])
                    {
                        break;
                    }
                }
            }

            if (i >= DMK_TOK_LEN)
            {
                throw new SectorNotFoundException();
            }

            int state = 0;
            int offs  = idamOffset + DMK_IDAM_LENGTH;

            for (i = 0; i < DMK_DATA_GAP; i++)
            {
                if ((i + offs) > trackLength)
                {
                    throw new SectorNotFoundException();
                }

                if (this.ReadByte(trackoffset + offs + i) == 0xA1)
                {
                    state++;
                }
                else if ((this.ReadByte(trackoffset + offs + i) == 0xFB) && state > 0)
                {
                    break;
                }
                else
                {
                    state = 0;
                }
            }

            if (i >= DMK_DATA_GAP)
            {
                throw new SectorNotFoundException();
            }

            offs += i + 1;
            int sec_len = 128 << idam[4];

            if ((offs + sec_len) > trackLength)
            {
                throw new SectorNotFoundException();
            }

            offset     = trackoffset + offs;
            sectorsize = sec_len;
            return(offset);
        }
예제 #6
0
파일: DMKImage.cs 프로젝트: wzydhek/EmuDisk
        public override void CreateDisk(string filename, int tracks, int heads, int sectors, int sectorsize, byte filldata)
        {
            if (this.baseStream != null)
            {
                this.baseStream.Close();
                this.baseStream = null;
            }

            this.filename = filename;

            try
            {
                this.baseStream    = File.Open(this.filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
                physicalTracks     = tracks;
                physicalHeads      = heads;
                physicalSectors    = sectors;
                physicalSectorSize = sectorsize;
                trackLength        = DMK_DEFAULT_TRACK_LENGTH;

                byte[] sectorData = new byte[this.PhysicalSectorSize].Initialize(filldata);
                byte[] sectorCRC  = Crc16.ComputeChecksumBytes(0xE295, sectorData);

                byte[] header = new byte[] { 0, (byte)this.PhysicalTracks, (byte)(this.trackLength & 0xff), (byte)(this.trackLength >> 8), (byte)(((this.PhysicalHeads > 1) ? 0 : 1) << 4), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                headerLength = header.Length;

                this.baseStream.Write(header, 0, HeaderLength);

                for (int t = 0; t < PhysicalTracks; t++)
                {
                    for (int h = 0; h < PhysicalHeads; h++)
                    {
                        byte[] trackData = new byte[trackLength].Initialize(0x4E);
                        for (int i = 0; i < 128; i++)
                        {
                            trackData[i] = 0;
                        }
                        int[] sPointers = new int[PhysicalSectors];

                        for (int s = 0, i = 0x80AB; s < PhysicalSectors; s++, i += 338)
                        {
                            sPointers[s]         = i;
                            trackData[2 * s]     = (byte)(i & 0xff);
                            trackData[2 * s + 1] = (byte)(i >> 8);
                        }

                        int SectorID = 1;

                        for (int s = 0; s < PhysicalSectors; s++)
                        {
                            int sectorOffset = (sPointers[SectorID - 1] & 0x3fff) - 11;
                            for (int i = 0; i < 8; i++)
                            {
                                trackData[sectorOffset++] = 0;
                            }
                            for (int i = 0; i < 3; i++)
                            {
                                trackData[sectorOffset++] = 0xA1;
                            }

                            byte[] sectorControl    = new byte[] { 0xFE, (byte)t, (byte)h, (byte)(s + 1), (byte)((PhysicalSectorSize / 128) >> 1) };
                            byte[] sectorControlCRC = Crc16.ComputeChecksumBytes(0xCDB4, sectorControl);
                            Array.Copy(sectorControl, 0, trackData, sectorOffset, 5);
                            sectorOffset += 5;
                            trackData[sectorOffset++] = sectorControlCRC[1];
                            trackData[sectorOffset++] = sectorControlCRC[0];

                            sectorOffset += 22;
                            for (int i = 0; i < 12; i++)
                            {
                                trackData[sectorOffset++] = 0;
                            }
                            for (int i = 0; i < 3; i++)
                            {
                                trackData[sectorOffset++] = 0xA1;
                            }
                            trackData[sectorOffset++] = 0xFB;

                            Array.Copy(sectorData, 0, trackData, sectorOffset, PhysicalSectorSize);
                            sectorOffset += PhysicalSectorSize;
                            trackData[sectorOffset++] = sectorCRC[1];
                            trackData[sectorOffset++] = sectorCRC[0];

                            if (s < PhysicalSectors - 1)
                            {
                                SectorID++;
                                SectorID += interleave;
                                if (SectorID > PhysicalSectors)
                                {
                                    SectorID -= PhysicalSectors;
                                }

                                while (trackData[sPointers[SectorID - 1] & 0x3FFF] == 0xFE)
                                {
                                    SectorID++;
                                }

                                if (SectorID > PhysicalSectors)
                                {
                                    throw new IOException();
                                }
                            }
                        }

                        this.baseStream.Write(trackData, 0, trackData.Length);
                    }
                }
            }
            catch (IOException)
            {
                MessageBox.Show(string.Format(MainForm.ResourceManager.GetString("DiskImageBase_FileOpenError", MainForm.CultureInfo), this.filename), MainForm.ResourceManager.GetString("DiskImageBase_FileOpenErrorCaption", MainForm.CultureInfo), MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.filename = string.Empty;
            }
        }