private void dumpButton_Click(object sender, EventArgs e)
        {
            if (!validateWavFilename())
            {
                return;
            }

            Application.DoEvents();

            using (NAudio.Wave.WaveFileReader waveFile = new NAudio.Wave.WaveFileReader(wavFilenameTextBox.Text))
            {
                tapFile = new TapFile();

                WaveSeeker waveSeeker = new WaveSeeker(waveFile);

                infoTextBox.Clear();
                // Read Header Information
                if (!readHeaderInfo(waveSeeker))
                {
                    return;
                }

                byte theByte = 0;

                short  counter     = 0;
                string charVersion = "";

                // while not eof...
                while (waveSeeker.readByte(out theByte))
                {
                    infoTextBox.AppendText(theByte.ToString("X2") + " ");
                    charVersion += printableChar((char)theByte);
                    if (counter == 7)
                    {
                        infoTextBox.AppendText(" " + charVersion + Environment.NewLine);
                        charVersion = "";
                        counter     = 0;
                    }
                    else
                    {
                        counter++;
                    }
                }

                // Formatting...
                while (counter < 8)
                {
                    infoTextBox.AppendText("   ");
                    counter++;
                }

                if (charVersion != "")
                {
                    infoTextBox.AppendText(" " + charVersion + Environment.NewLine + Environment.NewLine);
                }
            }
        }
        private void ReloadButton_Click(object sender, EventArgs e)
        {
            if (!validateWavFilename())
            {
                return;
            }

            Application.DoEvents();

            using (NAudio.Wave.WaveFileReader waveFile = new NAudio.Wave.WaveFileReader(wavFilenameTextBox.Text))
            {
                tapFile = new TapFile();

                WaveSeeker waveSeeker = new WaveSeeker(waveFile);

                // Read Header Information
                if (!readHeaderInfo(waveSeeker))
                {
                    return;
                }

                // If we don't know the program length
                if (tapFile.programLength == 0)
                {
                    return;
                }

                // Read program itself
                if (!readProgramBytes(waveSeeker))
                {
                    return;
                }

                // Display program bytes
                displayProgramBytes();

                // Validate Basic terminator
                if ((tapFile.fileType == 'B') && (tapFile.program[tapFile.programLength - 1] != 0x80))
                {
                    infoTextBox.AppendText("Warning: 'End-of-program' terminator missing (&80)" + Environment.NewLine);
                }

                // Actual length
                infoTextBox.AppendText(Environment.NewLine + "Length: " + tapFile.programLength + " (agreed)" + Environment.NewLine);

                infoTextBox.AppendText(Environment.NewLine + "Trailing Information:" + Environment.NewLine + "---------------------" + Environment.NewLine);

                // Read checksum
                if ((tapFile.fileType == 'M') || (tapFile.fileType == 'D') || (tapFile.fileType == '9'))
                {
                    if (!waveSeeker.readChecksum(out tapFile.checksum))
                    {
                        infoTextBox.AppendText("Warning: Checksum wrong/not found (ignored)" + Environment.NewLine);
                    }

                    infoTextBox.AppendText("Checksum: " + tapFile.checksum.ToString("X2") + Environment.NewLine);

                    // Calculate actual checksum
                    byte actualChecksum = 0;
                    for (int i = 0; i < tapFile.program.Length; i++)
                    {
                        actualChecksum += tapFile.program[i];
                    }
                    infoTextBox.AppendText("Calculated Checksum: " + actualChecksum.ToString("X2"));
                    if (tapFile.checksum == actualChecksum)
                    {
                        infoTextBox.AppendText(" (agreed)" + Environment.NewLine);
                    }
                    else
                    {
                        infoTextBox.AppendText(Environment.NewLine + "Warning: checksums disagree (ignored)" + Environment.NewLine);
                    }
                    tapFile.checksum = actualChecksum;

                    if ((tapFile.fileType == 'M') || (tapFile.fileType == 'D'))
                    {
                        waveSeeker.readByte(out tapFile.mysteryByte);
                        infoTextBox.AppendText("Mystery byte: " + tapFile.mysteryByte.ToString("X2") + Environment.NewLine);
                    }
                }

                // Read excution point
                if (tapFile.fileType != '9' && tapFile.fileType != 'D')
                {
                    tapFile.executionPoint = waveSeeker.readUShort();
                    infoTextBox.AppendText("Execution point: 0x" + tapFile.executionPoint.ToString("X4") + Environment.NewLine);
                }

                // Scroll to top
                infoTextBox.SelectionStart  = 0;
                infoTextBox.SelectionLength = 1;
                infoTextBox.ScrollToCaret();

                // Now enable Tap controls.
                saveButton.Enabled = isSaveEnabled();
            }
        }