Esempio n. 1
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);
        }
Esempio n. 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 = 154;
            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 <= 77; t++)
            {
                V[t, 0] = new Track(z4);
            }
            for (Int32 t = 78; t <= 116; t++)
            {
                V[t, 0] = new Track(z1);
            }
            for (Int32 t = 117; t <= 130; t++)
            {
                V[t, 0] = new Track(z2);
            }
            for (Int32 t = 131; t <= 141; t++)
            {
                V[t, 0] = new Track(z3);
            }
            for (Int32 t = 142; 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);
        }