int SYNC2Pulse(ITZXDataBlock TZXDataBlock)
 {
     EarBit = EarBit ^ 64;
     TZXState.Next();
     PulseCounter = 2;
     usedBits     = 8;
     return(((TZXDataBlock[0] & 0x80) > 0) ? TZXDataBlock.OneLength : TZXDataBlock.ZeroLength);
 }
        int DataBytes(ITZXDataBlock TZXDataBlock)
        {
            EarBit = EarBit ^ 64;
            PulseCounter--;
            if (PulseCounter > 0)
            {
                return(((TZXCurrentByte & 0x80) == 0x80) ? TZXDataBlock.OneLength : TZXDataBlock.ZeroLength);
            }
            if (usedBits > 1)
            {
                usedBits--;
                PulseCounter     = 2;
                TZXCurrentByte <<= 1;
                return(((TZXCurrentByte & 0x80) == 0x80) ? TZXDataBlock.OneLength : TZXDataBlock.ZeroLength);
            }
            TZXDataBlock.Progress++;
            TZXTapeCounter++;

            if (TZXDataBlock.Progress >= TZXDataBlock.TAPBlock.Length)
            {
                if (TZXDataBlock.PauseLength > 0)
                {
                    TZXState.Next();
                    OnLoaded();
                    return(TZXDataBlock.PauseLength * 3500);
                }
                else
                {
                    if (TZXTapeCounter > TZXFile.TZXLength)
                    {
                        TZXState.Next();
                        OnLoaded();
                        return(TZXDataBlock.PauseLength * 3500);
                    }
                    if (TZXTapeCounter != TZXFile.TZXLength)
                    {
                        TZXState.Reset();
                        return(GetNextBlock());
                    }
                }
            }
            OnProgress(TZXFile, TZXDataBlock.TAPBlock.Length, TZXTapeCounter, TZXDataBlock.Progress, Percent(TZXFile.TZXLength, TZXTapeCounter), Percent(TZXDataBlock.TAPBlock.Length - 1, TZXDataBlock.Progress), TZXDataBlock.ToString(), TZXDataBlock);
            usedBits = TZXDataBlock.UsedBits;

            PulseCounter = 2;
            if (TZXDataBlock.Progress < TZXDataBlock.TAPBlock.Data.Length)
            {
                TZXCurrentByte = TZXDataBlock.TAPBlock.Data[TZXDataBlock.Progress];
            }
            return(((TZXCurrentByte & 0x80) == 0x80) ? TZXDataBlock.OneLength : TZXDataBlock.ZeroLength);
        }
 int PilotTone(ITZXDataBlock TZXDataBlock)
 {
     EarBit = EarBit ^ 64;
     if (TZXDataBlock.Progress < TZXDataBlock.PulseToneLength)
     {
         TZXDataBlock.Progress++;
         return(TZXDataBlock.PulseLength);
     }
     else
     {
         TZXDataBlock.Progress = 0;
         TZXState.Next();
         return(TZXDataBlock.Sync1Length);
     }
 }
 public static void LoadRequest()
 {
     if (IsPlaying)
     {
         return;
     }
     //TZXTapeCounter = 0;
     if (!isPlaying)
     {
         TZXTapeCounter = 0;
         tZXBlockIndex  = -1;
         TZXState.Reset();
         pulseLength = 0;
         OnProgress(null, 0, 0, 0, 0, 0, "", null);
     }
     IsPlaying = true;
     pulseDone = 0;
     EarBit    = 0;
 }
 int SYNC1Pulse(ITZXDataBlock TZXDataBlock)
 {
     EarBit = EarBit ^ 64;
     TZXState.Next();
     return(TZXDataBlock.Sync2Length);
 }
        int GetNextBlock(bool increment)
        {
            if (TZXBlockIndex == 0)
            {
                TZXTapeCounter = 0;
            }
            if (increment)
            {
                TZXBlockIndex++;
            }
            if (TZXBlockIndex > TZXFile.Blocks.Count)
            {
                IsPlaying = false;
                OnLoaded();
                return(0);
            }
            pulseLength = 0;
            TZXBlock    = TZXFile.Blocks[TZXBlockIndex];

            switch (TZXBlock.ID)
            {
            case TZXBlockType.TapeDataBlock:
            case TZXBlockType.StandardSpeedDataBlock:
            case TZXBlockType.TurboSpeedDataBlock:
            {
                ITZXDataBlock tZXBlock = TZXBlock as ITZXDataBlock;
                pulseLength       = tZXBlock.PulseLength;
                tZXBlock.Progress = 0;
                usedBits          = tZXBlock.UsedBits;
                TZXState.Reset();
                TZXCurrentByte = tZXBlock.TAPBlock.FirstByte();
                break;
            }

            case TZXBlockType.PureDataBlock:
            {
                PureDataBlock tZXBlock = TZXBlock as PureDataBlock;
                PulseCounter = 2;

                if ((tZXBlock[0] & 0x80) > 0)
                {
                    pulseLength = tZXBlock.OneLength;
                }
                else
                {
                    pulseLength = tZXBlock.ZeroLength;
                }
                usedBits          = tZXBlock.UsedBits;
                tZXBlock.Progress = 0;
                TZXState.State    = TZXStates.DataBytes;
                TZXCurrentByte    = tZXBlock.TAPBlock.FirstByte();
                break;
            }

            case TZXBlockType.PureTone:
            {
                PureTone tZXBlock = TZXBlock as PureTone;
                PulseToneLength   = tZXBlock.numberOfPulses;
                pulseLength       = tZXBlock.PulseLength;
                tZXBlock.Progress = 0;
                TZXState.Reset();
                break;
            }

            case TZXBlockType.SequenceOfPulsesOfVariousLengths:
            {
                SequenceOfPulsesOfVariousLengths tZXBlock = TZXBlock as SequenceOfPulsesOfVariousLengths;
                PulseToneLength   = tZXBlock.PulseToneLength;
                pulseLength       = tZXBlock.PulsesLengths[0];
                tZXBlock.Progress = 0;
                TZXState.Reset();
                break;
            }

            case TZXBlockType.PauseSilenceOrStopTheTapeCommand:
            {
                PauseStopTheTape tZXBlock = TZXBlock as PauseStopTheTape;
                if (tZXBlock.PauseDuration == 0)
                {
                    StartStopTheTape();
                }
                else
                {
                    pulseLength    = tZXBlock.PauseDuration * 3500;
                    TZXState.State = TZXStates.EndPause;
                }
                break;
            }

            case TZXBlockType.StopTheTapeIfIn48kMode:
            {
                StartStopTheTape();
                break;
            }

            case TZXBlockType.JumpToBlock:
            {
                JumpToBlock tZXBlock = TZXBlock as JumpToBlock;
                sbyte       n        = (sbyte)tZXBlock.RelativeJumpValue;
                TZXBlockIndex += n;
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.LoopStart:
            {
                LoopStart tZXBlock = TZXBlock as LoopStart;
                loopCounter = tZXBlock.NumberOfRepetitions;
                TZXBlockIndex++;
                loopNext = TZXBlockIndex;
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.LoopEnd:
            {
                LoopEnd tZXBlock = TZXBlock as LoopEnd;
                loopCounter--;
                if (loopCounter > 0)
                {
                    TZXBlockIndex = loopNext;
                }
                else
                {
                    TZXBlockIndex++;
                }
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.CallSequence:
            {
                CallSequence tZXBlock = TZXBlock as CallSequence;
                stack.Push(TZXBlockIndex);
                numberOfCalls = tZXBlock.NumberOfCallsToBeMade;
                callList      = tZXBlock.ArrayOfCallBlockNumbers;
                callCounter   = 0;
                sbyte n = (sbyte)tZXBlock.ArrayOfCallBlockNumbers[callCounter++];
                TZXBlockIndex = TZXBlockIndex += n;
                GetNextBlock(false);
                break;
            }

            case TZXBlockType.ReturnFromSequence:
            {
                if (callCounter < numberOfCalls)
                {
                    sbyte n = (sbyte)callList[callCounter++];
                    TZXBlockIndex = callSequenceOrigin + n;
                    GetNextBlock(false);
                }
                else
                {
                    if (stack != null)
                    {
                        if (stack.Count > 0)
                        {
                            TZXBlockIndex = stack.Pop();
                        }
                    }
                    GetNextBlock();
                }

                break;
            }

            case TZXBlockType.EndOfFile:
            {
                IsPlaying = false;
                OnLoaded();
            }
            break;

            default:
                GetNextBlock();
                break;
            }
            return(pulseLength);
        }