public static void CheckTapeRecorderPlayback()
        {
            TapeRecorder tapeRecorder = new _TapeRecorder();

            Tape testTape = new Tape("TestTape",
                new TapeSection("section 1",
                    new ToneSequence("tone", 4, 5),                                 // 20 TStates
                    new PulsesSequence("pulses", new ushort[] {1,2,3,4}),           // 10 TStates
                    new DataSequence("data", new byte[] {15,175}, 1, 2, 4)),        // 36 TStates
                new TapeSection("section 2",
                    new PauseSequence("pause", 1)),                                 // 3500 TStates
                new TapeSection("section 3",
                    new SamplesSequence("samples", new byte[] { 15, 175 }, 2, 7))); // 30 TStates

            tapeRecorder.InsertTape(testTape);

            StringBuilder sbResult = new StringBuilder();

            tapeRecorder.Start();
            sbResult.AppendLine(tapeRecorder.PlayingTime + "," + tapeRecorder.SoundSignal.Level + "," + tapeRecorder.GetPosition());

            for (int i = 1; i < 70; i++)
            {
                tapeRecorder.Tick();
                sbResult.AppendLine(tapeRecorder.PlayingTime + "," + tapeRecorder.SoundSignal.Level + "," + tapeRecorder.GetPosition());
            }

            for (int i = 1; i <= 3492; i++)
            {
                tapeRecorder.Tick();
            }

            for (int i = 1; i <= 35; i++)
            {
                tapeRecorder.Tick();
                sbResult.AppendLine(tapeRecorder.PlayingTime + "," + tapeRecorder.SoundSignal.Level + "," + tapeRecorder.GetPosition());
            }

            string testResult = sbResult.ToString();

            string expectedResult = null;
            using (StreamReader reader = new StreamReader(PlatformSpecific.GetStreamForProjectFile("TapeFiles/Logs/CheckTapeRecorderPlayback.csv")))
            {
                expectedResult = reader.ReadToEnd();
            }

            if (testResult != expectedResult)
            {
                throw new Exception("TapeRecorder playback test failed");
            }
        }
        public static void Check_CPUTapeRecorderAccess()
        {
            ZXSpectrumComputer computer = new ZXSpectrumComputer();

            Tape testTape = new Tape("TestTape",
                                new TapeSection("section 1",
                                    new ToneSequence("tone", 6, 26)));
            computer.TapeRecorder.InsertTape(testTape);

            // From ROM function LD-EDGE-1
            StringBuilder testProgram = new StringBuilder();
            // 7 TStates
            testProgram.AppendLine("LD      A,$7F           ; prepare to read keyboard and EAR port");
            // 11 TSTates
            testProgram.AppendLine("IN      A,($FE)         ; row $7FFE. bit 6 is EAR, bit 0 is SPACE key.");
            // 10 TStates
            testProgram.AppendLine("JP 0");
            computer.LoadProgramInROM(testProgram.ToString());

            computer.TapeRecorder.Start();
            computer.ExecuteInstructionCount(2);
            if (computer.TapeRecorder.SoundSignal.Level == 0 && (computer.CPU.A & 0x40) != 0)
            {
                throw new Exception("Tape Recorder access error");
            }
            computer.ExecuteInstructionCount(3);
            if (computer.TapeRecorder.SoundSignal.Level == 1 && (computer.CPU.A & 0x40) == 0)
            {
                throw new Exception("Tape Recorder access error");
            }

            computer.Keyboard.OnKeyPress(Keyboard.Keys.Space);
            computer.ExecuteInstructionCount(6);
            if (computer.TapeRecorder.SoundSignal.Level == 0 && (computer.CPU.A & 0x40) != 0)
            {
                throw new Exception("Tape Recorder access error");
            }
            computer.ExecuteInstructionCount(3);
            if (computer.TapeRecorder.SoundSignal.Level == 1 && (computer.CPU.A & 0x40) == 0)
            {
                throw new Exception("Tape Recorder access error");
            }
        }
        public void InsertTape(Tape insertedTape)
        {
            if(Tape != null)
            {
                Eject();
            }

            Tape = insertedTape;

            RewindToStart();
        }