Exemple #1
0
        private static int ReadGeneralizedDataBlock(byte[] buf, int index, ref TapeBlock tb)
        {
            tb.Description = "CSW Recording";
            int size  = getInt32(buf, index); index += 4;
            int pause = getUInt16(buf, index); index += 2;
            int totp  = getInt32(buf, index); index += 4;
            int npp   = buf[index]; index += 1;
            int asp   = buf[index]; index += 1;
            int totd  = getInt32(buf, index); index += 4;
            int npd   = buf[index]; index += 1;
            int asd   = buf[index]; index += 1;


            return(size);
        }
 public override void Deserialize(Stream stream)
 {
     byte[] array = new byte[2];
     while (stream.Position < stream.Length)
     {
         stream.Read(array, 0, 2);
         int num = (int)BitConverter.ToUInt16(array, 0);
         if (num == 0)
         {
             return;
         }
         byte[] array2 = new byte[num];
         stream.Read(array2, 0, num);
         TapeBlock tapeBlock = new TapeBlock();
         tapeBlock.Description = TapSerializer.getBlockDescription(array2, 0, array2.Length);
         tapeBlock.Periods     = TapSerializer.getBlockPeriods(array2, 0, array2.Length, 2168, 667, 735, 855, 1710, (array2[0] < 4) ? 8064 : 3220, 1000, 8);
         this._tape.Blocks.Add(tapeBlock);
     }
 }
Exemple #3
0
        private static IEnumerable <ITapeBlock> Load(Stream stream, int tactsPerSecond)
        {
            var reader = new WavStreamReader(stream);

            var ratio = tactsPerSecond / (double)reader.Header.FmtSampleRate; // usually 3.5mhz / 44khz

            var rleData = LoadRleData(reader);

            var list         = new List <TapeBlock>();
            var pulses       = new List <int>();
            var blockTime    = 0;
            var blockCounter = 0;

            foreach (var rle in rleData)
            {
                var len = (int)Math.Round(rle * ratio, MidpointRounding.AwayFromZero);
                pulses.Add(len);

                blockTime += len;
                if (blockTime >= tactsPerSecond * 2)
                {
                    var tb = new TapeBlock();
                    tb.Description = string.Format("WAV-{0:D3}", blockCounter++);
                    tb.Periods     = new List <int>(pulses);
                    list.Add(tb);
                    blockTime = 0;
                    pulses.Clear();
                }
            }
            if (pulses.Count > 0)
            {
                var tb = new TapeBlock();
                tb.Description = string.Format("WAV-{0:D3}", blockCounter++);
                tb.Periods     = new List <int>(pulses);
                list.Add(tb);
            }
            return(list);
        }
Exemple #4
0
        private static IEnumerable <ITapeBlock> Load(Stream stream)
        {
            var list = new List <TapeBlock>();

            byte[] bsize = new byte[2];
            while (stream.Position < stream.Length)
            {
                stream.Read(bsize, 0, 2);
                int size = BitConverter.ToUInt16(bsize, 0);
                if (size == 0)
                {
                    break;
                }
                byte[] block = new byte[size];
                stream.Read(block, 0, size);
                var tb = new TapeBlock();
                tb.Description = getBlockDescription(block, 0, block.Length);
                tb.Periods     = getBlockPeriods(block, 0, block.Length, 2168, 667, 735, 855, 1710, (block[0] < 4) ? 8064 : 3220, 1000, 8);
                tb.TapData     = block;
                list.Add(tb);
            }
            return(list);
        }
Exemple #5
0
        private static IEnumerable <ITapeBlock> Load(Stream stream, int tactsPerSecond)
        {
            try
            {
                var hdr = new byte[0x34];
                stream.Read(hdr, 0, 0x20);

                var txtInfo = string.Empty;
                if (Encoding.ASCII.GetString(hdr, 0, 22) != "Compressed Square Wave")
                {
                    Locator.Resolve <IUserMessage>()
                    .Error("CSW loader\n\nInvalid CSW file, identifier not found!");
                    return(null);
                }
                var version = hdr[0x17];
                if (version > 2)
                {
                    Locator.Resolve <IUserMessage>()
                    .Error("CSW loader\n\nFormat CSW V{0}.{1} not supported!", hdr[0x17], hdr[0x18]);
                    return(null);
                }
                if (version == 2)  // CSW V2
                {
                    stream.Read(hdr, 0x20, 0x14);

                    var binDesc = new List <byte>();
                    for (var i = 0; i < 16 && hdr[0x24 + i] != 0; i++)
                    {
                        binDesc.Add(hdr[0x24 + i]);
                    }
                    txtInfo = Encoding.ASCII.GetString(binDesc.ToArray());

                    var extHdr = new byte[hdr[0x23]];
                    stream.Read(extHdr, 0, extHdr.Length);
                }
                var cswSampleRate = version == 2 ?
                                    BitConverter.ToInt32(hdr, 0x19) :
                                    BitConverter.ToUInt16(hdr, 0x19);
                var cswCompressionType = version == 2 ?
                                         hdr[0x21] :
                                         hdr[0x1B];
                // Flags b0: initial polarity; if set, the signal starts at logical high
                var cswFlags = version == 2 ?
                               hdr[0x22] :
                               hdr[0x1C];
                var cswPulseCount = version == 2 ?
                                    BitConverter.ToInt32(hdr, 0x1D) :
                                    (int)stream.Length - 0x20;
                var rleData = LoadRleData(
                    stream,
                    cswCompressionType,
                    cswPulseCount);

                var ratio = tactsPerSecond / (double)cswSampleRate; // usually 3.5mhz / 44khz

                var list         = new List <TapeBlock>();
                var pulses       = new List <int>();
                var blockTime    = 0;
                var blockCounter = 0;
                foreach (var rle in rleData)
                {
                    var len = (int)Math.Round(rle * ratio, MidpointRounding.AwayFromZero);
                    pulses.Add(len);

                    blockTime += len;
                    if (blockTime >= tactsPerSecond * 2)
                    {
                        var tb = new TapeBlock();
                        tb.Description = string.Format("CSW-{0:D3}", blockCounter++);
                        tb.Periods     = new List <int>(pulses);
                        list.Add(tb);
                        blockTime = 0;
                        pulses.Clear();
                    }
                }
                if (pulses.Count > 0)
                {
                    var tb = new TapeBlock();
                    tb.Description = string.Format("CSW-{0:D3}", blockCounter++);
                    tb.Periods     = new List <int>(pulses);
                    list.Add(tb);
                }

                if (txtInfo != string.Empty)
                {
                    var desc = new TapeBlock();
                    desc.Periods     = new List <int>();
                    desc.Description = string.Format("[{0}]", txtInfo);
                    list.Insert(0, desc);
                }
                return(list);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                Locator.Resolve <IUserMessage>()
                .Error("CSW loader\n\n{0}", ex.Message);
                return(null);
            }
        }
Exemple #6
0
        private static IEnumerable <ITapeBlock> Load(Stream stream, int frequency)
        {
            byte[] snbuf = new byte[stream.Length];
            stream.Read(snbuf, 0, snbuf.Length);

            if (Encoding.ASCII.GetString(snbuf, 0, 7) != "ZXTape!" || snbuf[7] != 0x1A)
            {
                Locator.Resolve <IUserMessage>()
                .Error("TZX loader\n\nInvalid TZX file, identifier not found!");
                return(null);
            }
            //int verMajor = snbuf[0x08];
            //int verMinor = snbuf[0x09];


            int ptr = 0;
            int size, pause, i, n, t, t0, j;
            int pl, p, last;//, *end; char *p;
            //int loop_n = 0, loop_p = 0;
            //byte[] nm = new byte[512];

            //TapeBlock tb = null;
            //bool grouping = false;

            //int newOffset;

            List <TapeBlock> tzxBlocks = new List <TapeBlock>();
            Stack <KeyValuePair <int, int> > loopStack = new Stack <KeyValuePair <int, int> >();

            while (ptr < snbuf.Length)
            {
                int blockId = snbuf[ptr++];

                TapeBlock tb = new TapeBlock();
                tb.TzxId = blockId;

                switch (blockId)
                {
                    #region ID 10 - Standard Speed Data Block
                case 0x10:     // Standard Speed Data Block
                    size           = getUInt16(snbuf, ptr + 2);
                    pause          = getUInt16(snbuf, ptr);
                    ptr           += 4;
                    tb.Description = TapSerializer.getBlockDescription(snbuf, ptr, size);
                    tb.Periods     = TapSerializer.getBlockPeriods(snbuf, ptr, size, 2168, 667, 735, 855, 1710, (snbuf[ptr] < 4) ? 8064 : 3220, pause, 8);
                    tb.TapData     = TapSerializer.getBlockTapData(snbuf, ptr, size);
                    ptr           += size;
                    break;
                    #endregion

                    #region ID 11 - Turbo Speed Data Block
                case 0x11:     // Turbo Speed Data Block
                    size           = 0xFFFFFF & getInt32(snbuf, ptr + 0x0F);
                    tb.Description = TapSerializer.getBlockDescription(snbuf, ptr + 0x12, size);
                    tb.Periods     = TapSerializer.getBlockPeriods(snbuf, ptr + 0x12, size,
                                                                   getUInt16(snbuf, ptr), getUInt16(snbuf, ptr + 2),
                                                                   getUInt16(snbuf, ptr + 4), getUInt16(snbuf, ptr + 6),
                                                                   getUInt16(snbuf, ptr + 8), getUInt16(snbuf, ptr + 10),
                                                                   getUInt16(snbuf, ptr + 13), snbuf[ptr + 12]);
                    //tb.TapData = TapSerializer.getBlockTapData(snbuf, ptr+0x12, size);
                    // todo: test used bits - ptr+12
                    ptr += size + 0x12;
                    break;
                    #endregion

                    #region ID 12 - Pure Tone
                case 0x12:     // Pure Tone
                    tb.Description = "Pure Tone";
                    pl             = getUInt16(snbuf, ptr);
                    n          = getUInt16(snbuf, ptr + 2);
                    tb.Periods = new List <int>(n);
                    for (i = 0; i < n; i++)
                    {
                        tb.Periods.Add(pl);
                    }
                    ptr += 4;
                    break;
                    #endregion

                    #region ID 13 - Pulse sequence
                case 0x13:     // Pulse sequence
                    tb.Description = "Pulse sequence";
                    n          = snbuf[ptr++];
                    tb.Periods = new List <int>(n);
                    for (i = 0; i < n; i++, ptr += 2)
                    {
                        tb.Periods.Add(getUInt16(snbuf, ptr));
                    }
                    break;
                    #endregion

                    #region ID 14 - Pure Data Block
                case 0x14:     // Pure Data Block
                    tb.Description = "Pure Data Block";
                    size           = 0xFFFFFF & getInt32(snbuf, ptr + 7);
                    tb.Periods     = TapSerializer.getBlockPeriods(snbuf, ptr + 0x0A, size,
                                                                   0, 0, 0, getUInt16(snbuf, ptr),
                                                                   getUInt16(snbuf, ptr + 2),
                                                                   -1,
                                                                   getUInt16(snbuf, ptr + 5), snbuf[ptr + 4]);
                    tb.TapData = TapSerializer.getBlockTapData(snbuf, ptr + 0x0A, size);
                    ptr       += size + 0x0A;
                    break;
                    #endregion

                    #region ID 15 - Direct Recording
                case 0x15:     // Direct Recording
                    tb.Description = "Direct Recording";
                    size           = 0xFFFFFF & getInt32(snbuf, ptr + 5);
                    t0             = getUInt16(snbuf, ptr);
                    pause          = getUInt16(snbuf, ptr + 2);
                    last           = snbuf[ptr + 4];
                    ptr           += 8;
                    pl             = 0; n = 0;
                    for (i = 0; i < size; i++)     // count number of pulses
                    {
                        for (j = 0x80; j != 0; j >>= 1)
                        {
                            if (((snbuf[ptr + i] ^ pl) & j) != 0)
                            {
                                n++;
                                pl ^= -1;
                            }
                        }
                    }
                    t          = 0; pl = 0;
                    tb.Periods = new List <int>(n + 2);
                    for (i = 1; i < size; i++, ptr++)     // find pulses
                    {
                        for (j = 0x80; j != 0; j >>= 1)
                        {
                            t += t0;
                            if (((snbuf[ptr] ^ pl) & j) != 0)
                            {
                                tb.Periods.Add(t);
                                pl ^= -1;
                                t   = 0;
                            }
                        }
                    }
                    // find pulses - last byte
                    for (j = 0x80; j != (byte)(0x80 >> last); j >>= 1)
                    {
                        t += t0;
                        if (((snbuf[ptr] ^ pl) & j) != 0)
                        {
                            tb.Periods.Add(t);
                            pl ^= -1;
                            t   = 0;
                        }
                    }
                    ptr++;
                    tb.Periods.Add(t);     // last pulse ???
                    if (pause != 0)
                    {
                        tb.Periods.Add(pause * 3500);
                    }
                    break;
                    #endregion

                    //#region ID 18
                    //case 0x18:
                    //    tb.Description = "CSW Recording";
                    //    break;
                    //#endregion

                    #region ID 19 - Generalized Data Block
                case 0x19:
                    ptr += ReadGeneralizedDataBlock(snbuf, ptr, ref tb);
                    break;
                    #endregion

                    #region ID 20 - Pause (silence) or 'Stop the Tape' command
                case 0x20:     // Pause (silence) or 'Stop the Tape' command
                    pause          = getUInt16(snbuf, ptr);
                    tb.Description = (pause != 0 ? "[Pause " + pause + " ms]" : "[Stop the Tape]");
                    tb.Periods     = new List <int>(2);
                    ptr           += 2;
                    if (pause == 0)     // at least 1ms pulse as specified in TZX 1.13
                    {
                        tb.Command = TapeCommand.STOP_THE_TAPE;
                        tb.Periods.Add(3500);
                        pause = -1;
                    }
                    else
                    {
                        pause *= 3500;
                    }
                    tb.Periods.Add(pause);
                    break;
                    #endregion

                    #region ID 21 - Group start
                case 0x21:     // Group start
                    n = snbuf[ptr++];
                    tb.Description = "[GROUP: " + Encoding.ASCII.GetString(snbuf, ptr, n) + "]";
                    tb.Command     = TapeCommand.BEGIN_GROUP;
                    ptr           += n;
                    tb.Periods     = new List <int>();
                    //grouping = true;
                    break;
                    #endregion

                    #region ID 22 - Group end
                case 0x22:     // Group end
                    tb.Description = "[END GROUP]";
                    tb.Command     = TapeCommand.END_GROUP;
                    tb.Periods     = new List <int>();
                    //grouping = false;
                    break;
                    #endregion

                    #region ID 23 - Jump to block
                case 0x23:                                                            // Jump to block
                    tb.Description = "[JUMP TO BLOCK " + getUInt16(snbuf, ptr) + "]"; // 1=next block, 2=skip 1 block, -1=prev block
                    tb.Periods     = new List <int>();
                    ptr           += 2;
                    break;
                    #endregion

                    #region ID 24 - Loop start
                case 0x24:                              // Loop start
                {
                    int loop_p = tzxBlocks.Count + 1;   // from next
                    int loop_n = getUInt16(snbuf, ptr); // TODO: as Command
                    loopStack.Push(new KeyValuePair <int, int>(loop_p, loop_n));
                    ptr           += 2;
                    tb.Description = string.Format("[LOOP {0}]", loop_n);
                    tb.Periods     = new List <int>();
                    break;
                }
                    #endregion

                    #region ID 25 - Loop end
                case 0x25:     // Loop end
                {
                    tb.Description = string.Format("[END LOOP]");
                    tb.Periods     = new List <int>();

                    KeyValuePair <int, int> loopInfo = loopStack.Pop();
                    int loop_p = loopInfo.Key;
                    int loop_n = loopInfo.Value;

                    if (loop_n == 0)
                    {
                        break;          // loop_n is repeat count, =1 for mem economy
                    }
                    size = tzxBlocks.Count - loop_p;
                    for (i = 0; i < loop_n; i++)
                    {
                        TapeBlock repeatBlock = new TapeBlock();
                        repeatBlock.Description = string.Format("[LOOP REPEAT {0}]", i + 1);
                        repeatBlock.Periods     = new List <int>();
                        tzxBlocks.Add(repeatBlock);
                        for (int z = 0; z < size; z++)
                        {
                            tzxBlocks.Add(tzxBlocks[loop_p + z]);
                        }
                    }
                    break;
                }
                    #endregion

                    #region ID 26 - Call sequence
                case 0x26:     // Call sequence
                    tb.Description = "[CALL SEQUENCE]";
                    tb.Periods     = new List <int>();
                    ptr           += 2 + 2 * getUInt16(snbuf, ptr);
                    break;
                    #endregion

                    #region ID 27 - Return from sequence
                case 0x27:     // Return from sequence
                    tb.Description = "[RETURN SEQUENCE]";
                    tb.Periods     = new List <int>();
                    break;
                    #endregion

                    #region ID 28 - Select block
                case 0x28:     // Select block
                    tb.Description = "[SELECT BLOCK]";
                    tb.Periods     = new List <int>();
                    ptr           += 2 + getUInt16(snbuf, ptr);
                    break;
                    #endregion

                    #region ID 2A - Stop tape if in 48K mode
                case 0x2A:     // Stop tape if in 48K mode
                    tb.Description = "[Stop tape if in 48K mode]";
                    tb.Command     = TapeCommand.STOP_THE_TAPE_48K;
                    tb.Periods     = new List <int>();
                    ptr           += 4 + getUInt16(snbuf, ptr);
                    break;
                    #endregion


                    #region ID 30 - Text description
                case 0x30:     // Text description
                    n = snbuf[ptr++];
                    tb.Description = "[" + Encoding.ASCII.GetString(snbuf, ptr, n) + "]";
                    tb.Periods     = new List <int>();
                    ptr           += n;
                    break;
                    #endregion

                    #region ID 31 - Message block
                case 0x31:    // Message block
                    ptr++;    //n = snbuf[ptr++]; // msg display time
                    n = snbuf[ptr++];
                    tb.Description = "[Message: " + Encoding.ASCII.GetString(snbuf, ptr, n) + "]";
                    tb.Command     = TapeCommand.SHOW_MESSAGE;
                    tb.Periods     = new List <int>();
                    ptr           += n;
                    break;
                    #endregion

                    #region ID 32 - Archive info+
                case 0x32:     // Archive info
                {
                    tb.Description = "Archive info";
                    tb.Periods     = new List <int>();
                    p = ptr + 3;
                    StringBuilder builderInfo = new StringBuilder();
                    for (i = 0; i < snbuf[ptr + 2]; i++)
                    {
                        string info;
                        int    infoType = snbuf[p++];
                        switch (infoType)
                        {
                        case 0: info = "Full title"; break;

                        case 1: info = "Publisher"; break;

                        case 2: info = "Author"; break;

                        case 3: info = "Year"; break;

                        case 4: info = "Language"; break;

                        case 5: info = "Type"; break;

                        case 6: info = "Price"; break;

                        case 7: info = "Protection"; break;

                        case 8: info = "Origin"; break;

                        case 0xFF: info = "Comment"; break;

                        default: info = "info"; break;
                        }
                        size = snbuf[p++];
                        string infoValue = Encoding.ASCII.GetString(snbuf, p, size);
                        p += size;

                        if (infoType == 0 || infoType == 7 || infoType == 0xFF)
                        {
                            if (builderInfo.Length > 0 && infoValue.Length > 0)         // insert separator
                            {
                                builderInfo.Append("; ");
                            }
                            builderInfo.Append(string.Format("{0}: {1}", info, infoValue));
                        }
                    }
                    tb.Description = builderInfo.ToString();
                    ptr           += 2 + getUInt16(snbuf, ptr);
                    break;
                }
                    #endregion

                    #region ID 33 - Hardware type
                case 0x33:            // Hardware type
                    n = snbuf[ptr++]; // hwinfo count
                    tb.Description = "[HARDWARE TYPE]";
                    tb.Periods     = new List <int>();
                    ptr           += 3 * n;
                    break;
                    #endregion

                    #region ID 34 - Emulation info
                case 0x34:     // Emulation info
                    tb.Description = "[EMULATION INFO]";
                    tb.Periods     = new List <int>();
                    ptr           += 8;
                    break;
                    #endregion

                    #region ID 35 - Custom info block+
                case 0x35:     // Custom info block
                {
                    string infoValue = Encoding.ASCII.GetString(snbuf, ptr, 0x10);
                    tb.Description = string.Format("[CUSTOM INFO - {0}]", infoValue);
                    ptr           += 0x10;
                    tb.Periods     = new List <int>();
                    int customLength = BitConverter.ToInt32(snbuf, ptr);
                    ptr += 4 + customLength;
                    break;
                }
                    #endregion

                    #region ID 40 - Snapshot block
                case 0x40:     // Snapshot block
                    tb.Description = "[SNAPSHOT - ";
                    if (snbuf[ptr] == 0)
                    {
                        tb.Description += ".Z80]";
                    }
                    else if (snbuf[ptr] == 1)
                    {
                        tb.Description += ".SNA]";
                    }
                    else
                    {
                        tb.Description += "???]";
                    }
                    ptr++;
                    size       = snbuf[ptr] | snbuf[ptr + 1] << 8 | snbuf[ptr + 2] << 16;
                    ptr       += 3;
                    tb.Periods = new List <int>();
                    ptr       += size;
                    break;
                    #endregion

                    #region ID 5A - "Glue" block+
                case 0x5A:     // "Glue" block
                    tb.Description = string.Format("[GLUE]");
                    tb.Periods     = new List <int>();
                    ptr           += 9;
                    break;
                    #endregion

                default:
                    tb.Description = string.Format(
                        "[NOT SUPPORTED BLOCK 0x{0:X2}]",
                        snbuf[ptr - 1]);
                    tb.Periods = new List <int>();
                    ptr       += getInt32(snbuf, ptr) & 0xFFFFFF;
                    ptr       += 4;
                    break;
                }
                tzxBlocks.Add(tb);
            }
            var ltb = tzxBlocks.Count > 0 ?
                      tzxBlocks[tzxBlocks.Count - 1] :
                      null;
            if (ltb != null)
            {
                ltb.Periods.Add(frequency / 220);
                ltb.Periods.Add(frequency / 220);
            }
            return(tzxBlocks);
        }
        public override void Deserialize(Stream stream)
        {
            List <int> list = new List <int>();

            byte[] array = new byte[52];
            stream.Read(array, 0, 32);
            if (Encoding.ASCII.GetString(array, 0, 22) != "Compressed Square Wave")
            {
                PlatformFactory.Platform.ShowWarning("Invalid CSW file, identifier not found! ", "CSW loader");
                return;
            }
            if (array[23] > 2)
            {
                PlatformFactory.Platform.ShowWarning(string.Concat(new string[]
                {
                    "Format CSW V",
                    array[23].ToString(),
                    ".",
                    array[24].ToString(),
                    " not supported!"
                }), "CSW loader");
                return;
            }
            if (array[23] == 2)
            {
                stream.Read(array, 32, 20);
                byte[] array2 = new byte[(int)array[35]];
                stream.Read(array2, 0, array2.Length);
            }
            int num  = (array[23] == 2) ? BitConverter.ToInt32(array, 25) : ((int)BitConverter.ToUInt16(array, 25));
            int num2 = (int)((array[23] == 2) ? array[33] : array[27]);

            byte[] array3;
            if (array[23] == 2)
            {
                array3 = new byte[BitConverter.ToInt32(array, 29)];
            }
            else
            {
                array3 = new byte[stream.Length - 32L];
            }
            if (num2 == 1)
            {
                stream.Read(array3, 0, array3.Length);
            }
            else
            {
                if (num2 != 2)
                {
                    PlatformFactory.Platform.ShowWarning("Unknown compression type!", "CSW loader");
                    return;
                }
                this.csw2_uncompress(stream, array3);
            }
            int num3 = (int)(this._tape.Z80FQ / (ulong)((long)num));
            int i    = 0;

            while (i < array3.Length)
            {
                int num4 = (int)array3[i++] * num3;
                if (num4 == 0)
                {
                    num4 = BitConverter.ToInt32(array3, i) / num3;
                    i   += 4;
                }
                list.Add(num4);
            }
            list.Add((int)(this._tape.Z80FQ / 10UL));
            TapeBlock tapeBlock = new TapeBlock();

            tapeBlock.Description = "CSW tape image";
            tapeBlock.Periods     = list;
            this._tape.Blocks.Add(tapeBlock);
        }
Exemple #8
0
        public override void Deserialize(Stream stream)
        {
            byte[] array = new byte[stream.Length];
            stream.Read(array, 0, array.Length);
            if (Encoding.ASCII.GetString(array, 0, 7) != "ZXTape!" || array[7] != 26)
            {
                PlatformFactory.Platform.ShowWarning("Invalid TZX file, identifier not found! ", "TZX loader");
                return;
            }
            int i    = 0;
            int num  = 0;
            int num2 = 0;

            while (i < array.Length)
            {
                byte      b = array[i++];
                TapeBlock tapeBlock;
                switch (b)
                {
                case 16:
                {
                    tapeBlock = new TapeBlock();
                    int num3 = (int)FormatSerializer.getUInt16(array, i + 2);
                    int num4 = (int)FormatSerializer.getUInt16(array, i);
                    i += 4;
                    tapeBlock.Description = TapSerializer.getBlockDescription(array, i, num3);
                    tapeBlock.Periods     = TapSerializer.getBlockPeriods(array, i, num3, 2168, 667, 735, 855, 1710, (array[i] < 4) ? 8064 : 3220, num4, 8);
                    i += num3;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 17:
                {
                    tapeBlock = new TapeBlock();
                    int num3 = 16777215 & FormatSerializer.getInt32(array, i + 15);
                    tapeBlock.Description = TapSerializer.getBlockDescription(array, i + 18, num3);
                    tapeBlock.Periods     = TapSerializer.getBlockPeriods(array, i + 18, num3, (int)FormatSerializer.getUInt16(array, i), (int)FormatSerializer.getUInt16(array, i + 2), (int)FormatSerializer.getUInt16(array, i + 4), (int)FormatSerializer.getUInt16(array, i + 6), (int)FormatSerializer.getUInt16(array, i + 8), (int)FormatSerializer.getUInt16(array, i + 10), (int)FormatSerializer.getUInt16(array, i + 13), (int)array[i + 12]);
                    i += num3 + 18;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 18:
                {
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "Pure Tone";
                    int num5 = (int)FormatSerializer.getUInt16(array, i);
                    int num6 = (int)FormatSerializer.getUInt16(array, i + 2);
                    tapeBlock.Periods = new List <int>(num6);
                    for (int j = 0; j < num6; j++)
                    {
                        tapeBlock.Periods.Add(num5);
                    }
                    i += 4;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 19:
                {
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "Pulse sequence";
                    int num6 = (int)array[i++];
                    tapeBlock.Periods = new List <int>(num6);
                    int j = 0;
                    while (j < num6)
                    {
                        tapeBlock.Periods.Add((int)FormatSerializer.getUInt16(array, i));
                        j++;
                        i += 2;
                    }
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 20:
                {
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "Pure Data Block";
                    int num3 = 16777215 & FormatSerializer.getInt32(array, i + 7);
                    tapeBlock.Periods = TapSerializer.getBlockPeriods(array, i + 10, num3, 0, 0, 0, (int)FormatSerializer.getUInt16(array, i), (int)FormatSerializer.getUInt16(array, i + 2), -1, (int)FormatSerializer.getUInt16(array, i + 5), (int)array[i + 4]);
                    i += num3 + 10;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 21:
                {
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "Direct Recording";
                    int num3  = 16777215 & FormatSerializer.getInt32(array, i + 5);
                    int @uint = (int)FormatSerializer.getUInt16(array, i);
                    int num4  = (int)FormatSerializer.getUInt16(array, i + 2);
                    int num7  = (int)array[i + 4];
                    i += 8;
                    int num5 = 0;
                    int num6 = 0;
                    int j;
                    for (j = 0; j < num3; j++)
                    {
                        for (int num8 = 128; num8 != 0; num8 >>= 1)
                        {
                            if ((((int)array[i + j] ^ num5) & num8) != 0)
                            {
                                num6++;
                                num5 ^= -1;
                            }
                        }
                    }
                    int num9 = 0;
                    num5 = 0;
                    tapeBlock.Periods = new List <int>(num6 + 2);
                    j = 1;
                    while (j < num3)
                    {
                        for (int num8 = 128; num8 != 0; num8 >>= 1)
                        {
                            num9 += @uint;
                            if ((((int)array[i] ^ num5) & num8) != 0)
                            {
                                tapeBlock.Periods.Add(num9);
                                num5 ^= -1;
                                num9  = 0;
                            }
                        }
                        j++;
                        i++;
                    }
                    for (int num8 = 128; num8 != (int)((byte)(128 >> num7)); num8 >>= 1)
                    {
                        num9 += @uint;
                        if ((((int)array[i] ^ num5) & num8) != 0)
                        {
                            tapeBlock.Periods.Add(num9);
                            num5 ^= -1;
                            num9  = 0;
                        }
                    }
                    i++;
                    tapeBlock.Periods.Add(num9);
                    if (num4 != 0)
                    {
                        tapeBlock.Periods.Add(num4 * 3500);
                    }
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 22:
                case 23:
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:
                case 29:
                case 30:
                case 31:
                case 41:
                case 43:
                case 44:
                case 45:
                case 46:
                case 47:
                    break;

                case 32:
                {
                    tapeBlock = new TapeBlock();
                    int num4 = (int)FormatSerializer.getUInt16(array, i);
                    tapeBlock.Description = ((num4 != 0) ? ("[Pause " + num4 + " ms]") : "[Stop the Tape]");
                    tapeBlock.Periods     = new List <int>(2);
                    i += 2;
                    if (num4 == 0)
                    {
                        tapeBlock.Command = TapeCommand.STOP_THE_TAPE;
                        tapeBlock.Periods.Add(3500);
                        num4 = -1;
                    }
                    else
                    {
                        num4 *= 3500;
                    }
                    tapeBlock.Periods.Add(num4);
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 33:
                {
                    tapeBlock = new TapeBlock();
                    int num6 = (int)array[i++];
                    tapeBlock.Description = "[GROUP: " + Encoding.ASCII.GetString(array, i, num6) + "]";
                    tapeBlock.Command     = TapeCommand.BEGIN_GROUP;
                    i += num6;
                    tapeBlock.Periods = new List <int>();
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 34:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[END GROUP]";
                    tapeBlock.Command     = TapeCommand.END_GROUP;
                    tapeBlock.Periods     = new List <int>();
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 35:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[JUMP TO BLOCK " + FormatSerializer.getUInt16(array, i) + "]";
                    tapeBlock.Periods     = new List <int>();
                    i += 2;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 36:
                    num  = (int)FormatSerializer.getUInt16(array, i);
                    num2 = this._tape.Blocks.Count;
                    i   += 2;
                    continue;

                case 37:
                    if (num != 0)
                    {
                        int num3 = this._tape.Blocks.Count - num2;
                        for (int k = 0; k < num3; k++)
                        {
                            this._tape.Blocks.Add(this._tape.Blocks[num + k]);
                        }
                        num = 0;
                        continue;
                    }
                    continue;

                case 38:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[CALL SEQUENCE]";
                    tapeBlock.Periods     = new List <int>();
                    i += (int)(2 + 2 * FormatSerializer.getUInt16(array, i));
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 39:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[RETURN SEQUENCE]";
                    tapeBlock.Periods     = new List <int>();
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 40:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[SELECT BLOCK]";
                    tapeBlock.Periods     = new List <int>();
                    i += (int)(2 + FormatSerializer.getUInt16(array, i));
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 42:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[Stop tape if in 48K mode]";
                    tapeBlock.Command     = TapeCommand.STOP_THE_TAPE_48K;
                    tapeBlock.Periods     = new List <int>();
                    i += (int)(4 + FormatSerializer.getUInt16(array, i));
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 48:
                {
                    tapeBlock = new TapeBlock();
                    int num6 = (int)array[i++];
                    tapeBlock.Description = "[" + Encoding.ASCII.GetString(array, i, num6) + "]";
                    tapeBlock.Periods     = new List <int>();
                    i += num6;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 49:
                {
                    tapeBlock = new TapeBlock();
                    i++;
                    int num6 = (int)array[i++];
                    tapeBlock.Description = "[Message: " + Encoding.ASCII.GetString(array, i, num6) + "]";
                    tapeBlock.Command     = TapeCommand.SHOW_MESSAGE;
                    tapeBlock.Periods     = new List <int>();
                    i += num6;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 50:
                {
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "Archive info";
                    tapeBlock.Periods     = new List <int>();
                    int num10 = i + 3;
                    for (int j = 0; j < (int)array[i + 2]; j++)
                    {
                        byte   b2 = array[num10++];
                        string arg;
                        switch (b2)
                        {
                        case 0:
                            arg = "Full title";
                            break;

                        case 1:
                            arg = "Publisher";
                            break;

                        case 2:
                            arg = "Author";
                            break;

                        case 3:
                            arg = "Year";
                            break;

                        case 4:
                            arg = "Language";
                            break;

                        case 5:
                            arg = "Type";
                            break;

                        case 6:
                            arg = "Price";
                            break;

                        case 7:
                            arg = "Protection";
                            break;

                        case 8:
                            arg = "Origin";
                            break;

                        default:
                            if (b2 != 255)
                            {
                                arg = "info";
                            }
                            else
                            {
                                arg = "Comment";
                            }
                            break;
                        }
                        int num3 = (int)array[num10++];
                        tapeBlock.Description = string.Format("{0}: {1}", arg, Encoding.ASCII.GetString(array, num10, num3));
                        num10 += num3;
                    }
                    i += (int)(2 + FormatSerializer.getUInt16(array, i));
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 51:
                {
                    tapeBlock = new TapeBlock();
                    int num6 = (int)array[i++];
                    tapeBlock.Description = "[HARDWARE TYPE]";
                    tapeBlock.Periods     = new List <int>();
                    i += 3 * num6;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;
                }

                case 52:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[EMULATION INFO]";
                    tapeBlock.Periods     = new List <int>();
                    i += 8;
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                case 53:
                    tapeBlock             = new TapeBlock();
                    tapeBlock.Description = "[CUSTOM INFO - " + Encoding.ASCII.GetString(array, i, 10) + "]";
                    i += 10;
                    tapeBlock.Periods = new List <int>();
                    i += (int)(2 + FormatSerializer.getUInt16(array, i));
                    this._tape.Blocks.Add(tapeBlock);
                    continue;

                default:
                    if (b == 64)
                    {
                        tapeBlock             = new TapeBlock();
                        tapeBlock.Description = "[SNAPSHOT - ";
                        if (array[i] == 0)
                        {
                            TapeBlock tapeBlock2 = tapeBlock;
                            tapeBlock2.Description += ".Z80]";
                        }
                        else if (array[i] == 1)
                        {
                            TapeBlock tapeBlock3 = tapeBlock;
                            tapeBlock3.Description += ".SNA]";
                        }
                        else
                        {
                            TapeBlock tapeBlock4 = tapeBlock;
                            tapeBlock4.Description += "???]";
                        }
                        i++;
                        int num3 = (int)array[i] | (int)array[i + 1] << 8 | (int)array[i + 2] << 16;
                        i += 3;
                        tapeBlock.Periods = new List <int>();
                        i += num3;
                        this._tape.Blocks.Add(tapeBlock);
                        continue;
                    }
                    if (b == 90)
                    {
                        i += 9;
                        continue;
                    }
                    break;
                }
                tapeBlock             = new TapeBlock();
                tapeBlock.Description = "[UNKNOWN BLOCK 0x" + array[i - 1].ToString("X2") + "]";
                tapeBlock.Periods     = new List <int>();
                i += (FormatSerializer.getInt32(array, i) & 16777215);
                i += 4;
                this._tape.Blocks.Add(tapeBlock);
            }
        }
Exemple #9
0
 /// <summary>
 /// Стирает все символы, присутствующие на ленте.
 /// </summary>
 public void Clear()
 {
     _firstBlock = null;
     _lastBlock = null;
     _currentBlock = null;
 }
Exemple #10
0
        /// <summary>
        /// Удаляет блок из ленты.
        /// </summary>
        /// <param name="block">Удаляемый блок.</param>
        private void RemoveBlock(TapeBlock block)
        {
            if (block == null)
                throw new ArgumentNullException("Удаляемый блок не может быть неопределенным");

            if(block.Prev == null) // блок стоит первым в списке либо он единственный.
            {
                _firstBlock = block.Next;
                if(_firstBlock != null)
                    _firstBlock.Prev = null;
                else
                    _lastBlock = null;
                _currentBlock = _firstBlock;
            }
            else if(block.Next == null) // блок стоит последним в списке.
            {
                _lastBlock = block.Prev;
                _lastBlock.Next = null;
                _currentBlock = _lastBlock;
            }
            else // блок стоит в центре списка.
            {
                block.Prev.Next = block.Next;
                block.Next.Prev = block.Prev;
                _currentBlock = block.Prev;
            }
        }
Exemple #11
0
        /// <summary>
        /// Добавляет блок ячеек на свое место в списке.
        /// </summary>
        /// <param name="block">Добавляемый блок.</param>
        private void AddBlock(TapeBlock block)
        {
            if(_currentBlock == null)
            {
                _currentBlock = block;
                _firstBlock = block;
                _lastBlock = block;
                return;
            }
            TapeBlock current = _firstBlock;

            while(block.CompareTo(current) == 1)
            {
                current = current.Next;
                if (current == null) break;
            }
            if(current == null)
            {
                _lastBlock.Next = block;
                block.Prev = _lastBlock;
                _lastBlock = block;
            }
            else
            {
                if (current.Prev != null)
                {
                    current.Prev.Next = block;
                    block.Prev = current.Prev;
                }
                else
                    _firstBlock = block;
                current.Prev = block;
                block.Next = current;
            }
            _currentBlock = block;
        }
Exemple #12
0
        /// <summary>
        /// Возвращает значение указанной ячейки.
        /// </summary>
        /// <param name="cell">Индекс указанной ячейки.</param>
        /// <returns>Значение указанной ячейки.</returns>
        public int GetValue(BigInteger cell)
        {
            if (_currentBlock == null) return 0;
            if (cell < _firstBlock.FirstCell) return 0;
            if (cell > _lastBlock.LastCell) return 0;

            if (cell < _currentBlock.FirstCell)
            {
                TapeBlock initialValue = _currentBlock;
                _currentBlock = _currentBlock.Prev;
                BigInteger blockCell;
                while (_currentBlock != null)
                {
                    if (cell >= _currentBlock.FirstCell)
                    {
                        blockCell = cell - _currentBlock.FirstCell;
                        if (blockCell >= 0)
                        {
                            if (blockCell < BLOCK_SIZE)
                                return _currentBlock.GetValue((int)blockCell);
                        }
                    }
                    _currentBlock = _currentBlock.Prev;
                }
                _currentBlock = initialValue;
                return 0;
            }
            else if (cell > _currentBlock.LastCell)
            {
                TapeBlock initialValue = _currentBlock;
                _currentBlock = _currentBlock.Next;
                BigInteger blockCell;
                while (_currentBlock != null)
                {
                    if (cell <= _currentBlock.LastCell)
                    {
                        blockCell = cell - _currentBlock.FirstCell;
                        if (blockCell >= 0)
                        {
                            if (blockCell < BLOCK_SIZE)
                                return _currentBlock.GetValue((int)blockCell);
                        }
                    }

                    _currentBlock = _currentBlock.Next;
                }
                _currentBlock = initialValue;
                return 0;
            }
            else
            {
                return _currentBlock.GetValue((int)(cell - _currentBlock.FirstCell));
            }
        }