Пример #1
0
        public static CHSVolume Load(String source, Byte[] data)
        {
            if (!IsValid(data))
            {
                return(null);
            }
            Int32 z1 = 21, z2 = 19, z3 = 18, z4 = 17;
            Int32 nt = 35;

            if ((data.Length == 196608) || (data.Length == 197376))
            {
                nt = 40;
            }
            else if ((data.Length == 205312) || (data.Length == 206114))
            {
                nt = 42;
            }
            else if ((data.Length == 176640) || (data.Length == 177330))
            {
                z2 = 20;
            }
            CHSVolume V = new CHSVolume(source, source, 256, 1, nt, 0, 1, 0);

            for (Int32 t = 1; t <= 17; t++)
            {
                V[t, 0] = new Track(z1);
            }
            for (Int32 t = 18; t <= 24; t++)
            {
                V[t, 0] = new Track(z2);
            }
            for (Int32 t = 25; t <= 30; t++)
            {
                V[t, 0] = new Track(z3);
            }
            for (Int32 t = 31; t <= nt; t++)
            {
                V[t, 0] = new Track(z4);
            }
            Int32 p = 0;
            Int32 q = (data.Length == V.BlockCount * 257) ? V.BlockCount * 256 : -1;

            for (Int32 t = 1; t <= nt; t++)
            {
                Track T = V[t, 0];
                for (Int32 s = 0; s < T.Length; s++)
                {
                    Sector S = new Sector(s, 256, data, p);
                    p += 256;
                    if (q != -1)
                    {
                        S.ErrorCode = data[q++];
                    }
                    T[s] = S;
                }
            }
            return(V);
        }
Пример #2
0
        public static CHSVolume Load(String source, Byte[] data)
        {
            if (!IsValid(data))
            {
                return(null);
            }
            Int32     z1 = 29, z2 = 27, z3 = 25, z4 = 23;
            Int32     nt = 77;
            CHSVolume V  = new CHSVolume(source, source, 256, 1, nt, 0, 1, 0);

            for (Int32 t = 1; t <= 39; t++)
            {
                V[t, 0] = new Track(z1);
            }
            for (Int32 t = 40; t <= 53; t++)
            {
                V[t, 0] = new Track(z2);
            }
            for (Int32 t = 54; t <= 64; t++)
            {
                V[t, 0] = new Track(z3);
            }
            for (Int32 t = 65; t <= nt; t++)
            {
                V[t, 0] = new Track(z4);
            }
            Int32 p = 0;
            Int32 q = (data.Length == V.BlockCount * 257) ? V.BlockCount * 256 : -1;

            for (Int32 t = 1; t <= nt; t++)
            {
                Track T = V[t, 0];
                for (Int32 s = 0; s < T.Length; s++)
                {
                    Sector S = new Sector(s, 256, data, p);
                    p += 256;
                    if (q != -1)
                    {
                        S.ErrorCode = data[q++];
                    }
                    T[s] = S;
                }
            }
            return(V);
        }
Пример #3
0
        public CBMDOS(CHSVolume volume)
        {
            mVol      = volume;
            mDirTrack = (volume.MaxCylinder <= 42) ? 18 : 39;
            Byte ver = volume[mDirTrack, 0, 0][2];

            if (ver == 1)
            {
                mType = "CBMDOS1";
            }
            else if (ver == 65)
            {
                mType = "CBMDOS2";
            }
            else if (ver == 67)
            {
                mType = (volume.MaxCylinder > 77) ? "CBMDOS2.7" : "CBMDOS2.5";
            }
            mBlocksFree = CountFreeBlocks();
        }
Пример #4
0
        private Int32 SPIC;   // sectors per (perfect) interleave cycle

        public InterleavedVolume(CHSVolume volume, Int32 interleave, Int32 headSkew, Int32 cylSkew, Int32 start)
        {
            if (interleave < 0)
            {
                throw new ArgumentOutOfRangeException("interleave");
            }
            if (interleave == 0)
            {
                interleave = 1;
            }
            mVol        = volume;
            mSource     = String.Format("{0} [I={1:D0},{2:D0},{3:D0}@{4:D0}]", volume.Source, interleave, headSkew, cylSkew, start);
            mInfo       = String.Format("{0}\nInterleave={1:D0},HeadSkew={2:D0},CylSkew={3:D0},Start={4:D0}", volume.Info, interleave, headSkew, cylSkew, start);
            mInterleave = interleave;
            mHeadSkew   = headSkew;
            mCylSkew    = cylSkew;
            mStart      = start;
            SPT         = mVol.MaxSector(0, 0) - mVol.MinSector(0, 0) + 1;
            TPC         = mVol.MaxHead - mVol.MinHead + 1;
            SPIC        = SPT / GCD(SPT, interleave);
        }
Пример #5
0
        // Load ImageDisk .IMD image file
        public static CHSVolume Load(String source, Byte[] data)
        {
            Int32 p, n;

            Int32[] SS = new Int32[0];

            // determine disk geometry
            Int32 nc = -1;
            Int32 nh = -1;
            Int32 ss = -1;

            for (p = 0; data[p++] != 0x1a;)
            {
                ;                              // skip ASCII header
            }
            while (p < data.Length)
            {
                // track header
                p++;                 // skip mode
                Int32 c = data[p++]; // cylinder num
                if (c > nc)
                {
                    nc = c;
                }
                Int32   h  = data[p++]; // head num
                Boolean cm = ((h & 0x80) != 0);
                Boolean hm = ((h & 0x40) != 0);
                h &= 0x3f;
                if (h > nh)
                {
                    nh = h;
                }
                Int32 ns = data[p++]; // sectors
                ss = data[p++];       // sector size
                ss = (ss == 0xff) ? -1 : (128 << ss);
                p += ns;              // skip sector numbering map
                if (cm)
                {
                    p += ns;     // skip cylinder map
                }
                if (hm)
                {
                    p += ns;     // skip head map
                }
                SS = new Int32[ns];
                if (ss == -1) // sector size table
                {
                    for (Int32 i = 0; i < ns; i++)
                    {
                        n     = data[p++];
                        SS[i] = n + (data[p++] << 8);
                    }
                }
                // sector data
                for (Int32 s = 0; s < ns; s++)
                {
                    switch (data[p++]) // sector data type
                    {
                    case 1:
                    case 3:
                    case 5:
                    case 7:
                        p += (ss == -1) ? SS[s] : ss;
                        break;

                    case 2:
                    case 4:
                    case 6:
                    case 8:
                        p++;
                        break;
                    }
                }
            }

            // read image (use last track's largest sector as default volume sector size)
            if (ss == -1)
            {
                for (Int32 i = 0; i < SS.Length; i++)
                {
                    if (SS[i] > ss)
                    {
                        ss = SS[i];
                    }
                }
            }
            for (p = 0; data[p] != 0x1a; p++)
            {
                ;                               // count size of ASCII header
            }
            StringBuilder buf = new StringBuilder(p);

            for (p = 0; data[p] != 0x1a; p++)
            {
                buf.Append((Char)data[p]);
            }
            p++; // skip 0x1a header terminator
            CHSVolume image = new CHSVolume(source, buf.ToString(), ss, ++nc, ++nh);

            while (p < data.Length)
            {
                // track header
                p++;                    // skip mode
                Int32   c  = data[p++]; // cylinder num
                Int32   h  = data[p++]; // head num
                Boolean cm = ((h & 0x80) != 0);
                Boolean hm = ((h & 0x40) != 0);
                h &= 0x3f;
                Int32 ns = data[p++]; // sectors
                Track t  = new Track(ns);
                ss = data[p++];       // sector size
                ss = (ss == 0xff) ? -1 : (128 << ss);
                Int32[] SM = new Int32[ns];
                for (Int32 i = 0; i < ns; i++)
                {
                    SM[i] = data[p++];                            // sector numbering map
                }
                // TODO: don't skip these
                if (cm)
                {
                    p += ns;     // skip cylinder map
                }
                if (hm)
                {
                    p += ns;     // skip head map
                }
                SS = new Int32[ns];
                if (ss == -1) // sector size table
                {
                    for (Int32 i = 0; i < ns; i++)
                    {
                        n     = data[p++];
                        SS[i] = n + (data[p++] << 8);
                    }
                }
                // sector data
                for (Int32 s = 0; s < ns; s++)
                {
                    switch (data[p++]) // sector data type
                    {
                    case 1:
                    case 3:
                    case 5:
                    case 7:
                        n    = (ss == -1) ? SS[s] : ss;
                        t[s] = new Sector(SM[s], n, data, p);
                        p   += n;
                        break;

                    case 2:
                    case 4:
                    case 6:
                    case 8:
                        n    = (ss == -1) ? SS[s] : ss;
                        t[s] = new Sector(SM[s], n, data[p++]);
                        break;
                    }
                }
                image[c, h] = t;
            }

            return(image);
        }
Пример #6
0
        public static CHSVolume Load(String source, Byte[] data)
        {
            // header
            if (!HasHeader(data))
            {
                return(null);
            }
            Int32   p   = 0;
            Byte    b   = data[p++];
            Byte    b2  = data[p++];
            Boolean adc = false;

            if ((b == (Byte)'t') && (b2 == (Byte)'d'))
            {
                adc = true;
            }
            else if ((b != (Byte)'T') || (b2 != (Byte)'D'))
            {
                Debug.WriteLine(1, "File does not appear to be TeleDisk format (no TD header)");
                return(null);
            }
            if ((b = data[p++]) != 0)
            {
                Debug.WriteLine(1, "Multi-file images not supported (volume sequence is {0:D0}, expect 0)", b);
                return(null);
            }
            p++; // skip check signature byte
            p++; // skip version number byte
            p++; // skip source density byte
            p++; // skip drive type byte
            Int32 stepping = data[p++];

            p++;                  // skip dos mode byte
            Int32 nh = data[p++]; // number of sides

            p += 2;               // header CRC
            if (adc)
            {
                LZSS.Decompressor D = new LZSS.Decompressor(data, p);
                data = D.GetBytes();
                p    = 0;
            }

            // comment block
            Int32  n;
            String info = source;

            if ((stepping & 0x80) != 0)
            {
                if (p + 10 >= data.Length)
                {
                    return(null);
                }
                p += 2; // CRC
                n  = Buffer.GetUInt16L(data, ref p);
                p += 6; // date/time
                StringBuilder buf = new StringBuilder(n);
                for (Int32 i = 0; i < n; i++)
                {
                    b = Buffer.GetByte(data, ref p);
                    buf.Append((b == 0) ? '\n' : (Char)b);
                }
                info = buf.ToString();
            }

            // determine disk geometry
            Int32 q  = p;
            Int32 nc = -1;

            Int32[] ct = new Int32[256];
            while (p < data.Length)
            {
                // track header
                Int32 ns = Buffer.GetByte(data, ref p); // number of sectors on this track
                if (ns == 255)
                {
                    break;
                }
                Int32 c = Buffer.GetByte(data, ref p) + 1;
                if (c > nc)
                {
                    nc = c;
                }
                Int32 h = Buffer.GetByte(data, ref p) + 1;
                if (h > nh)
                {
                    nh = h;
                }
                p++; // CRC

                // sectors
                for (Int32 s = 0; s < ns; s++)
                {
                    // sector header
                    p++;                                  // skip cylinder id
                    p++;                                  // skip side id
                    p++;                                  // skip sector id
                    b = Buffer.GetByte(data, ref p);      // sector size
                    ct[b]++;
                    Byte f = Buffer.GetByte(data, ref p); // flags
                    p++;                                  // skip CRC
                    if ((f & 0x30) != 0)
                    {
                        continue;
                    }
                    n  = Buffer.GetUInt16L(data, ref p);
                    p += n;
                }
            }
            Int32 ss = -1;

            n = 0;
            for (Int32 i = 0; i < 256; i++)
            {
                if (ct[i] > n)
                {
                    n  = ct[i];
                    ss = 128 << i;
                }
            }
            CHSVolume vol = new CHSVolume(source, source, ss, nc, nh);

            // track data
            p = q;
            while (p < data.Length)
            {
                // track header
                Int32 ns = Buffer.GetByte(data, ref p); // number of sectors on this track
                if (ns == 255)
                {
                    break;
                }
                Int32 c = Buffer.GetByte(data, ref p);
                Int32 h = Buffer.GetByte(data, ref p);
                p++; // CRC
                Track T = new Track(ns);
                vol[c, h] = T;

                // sectors
                for (Int32 s = 0; s < ns; s++)
                {
                    // sector header
                    p++;                                    // skip cylinder id
                    p++;                                    // skip side id
                    Int32 id = Buffer.GetByte(data, ref p); // sector id
                    n = 128 << Buffer.GetByte(data, ref p); // sector size
                    Byte f = Buffer.GetByte(data, ref p);   // flags
                    p++;                                    // skip CRC
                    if ((f & 0x30) != 0)
                    {
                        continue;
                    }
                    Int32 l = Buffer.GetUInt16L(data, ref p) - 1;
                    switch (Buffer.GetByte(data, ref p))
                    {
                    case 0:
                        T[s] = new Sector(id, n, data, p);
                        p   += n;
                        break;

                    case 1:
                        T[s] = new Sector(id, n);
                        q    = 0;
                        while (n > 0)
                        {
                            Int32 k = Buffer.GetUInt16L(data, ref p);
                            b  = Buffer.GetByte(data, ref p);
                            b2 = Buffer.GetByte(data, ref p);
                            for (Int32 i = 0; i < k; i++)
                            {
                                T[s][q++] = b;
                                T[s][q++] = b2;
                                n        -= 2;
                            }
                        }
                        break;

                    case 2:
                        T[s] = new Sector(id, n);
                        q    = 0;
                        while (n > 0)
                        {
                            Int32 k = Buffer.GetByte(data, ref p);
                            if (k == 0)
                            {
                                k = Buffer.GetByte(data, ref p);
                                T[s].CopyFrom(data, p, q, k);
                                p += k;
                                q += k;
                                n -= k;
                            }
                            else
                            {
                                k *= 2;
                                Int32 z = Buffer.GetByte(data, ref p);
                                for (Int32 i = 0; i < z; i++)
                                {
                                    T[s].CopyFrom(data, p, q, k);
                                    q += k;
                                    n -= k;
                                }
                                p += k;
                            }
                        }
                        break;
                    }
                }
            }

            return(vol);
        }