/// <summary>
        /// Disassembles the sound effect.
        /// </summary>
        /// <param name="trackInfo">The MusicTrackInfo object used to retrieve track information.</param>
        /// <returns>An annotated disassembly of the sound effect.</returns>
        private string DisassembleSoundEffect(ref MusicTrackInfo trackInfo)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(string.Format("TRACK{0}START:", trackInfo.TrackIndex));

            // The format of a sound effect is:
            // Priority Byte
            // Channel Usage
            // Sound Effect data.
            int currentPos = trackInfo.TrackOffset;

            sb.AppendLine(string.Format(".byte ${0} ;priority. Lo=music priority, Hi=sfx priority", this.ROM[currentPos].ToHex()));
            currentPos++;

            sb.AppendLine(string.Format(".byte ${0} ;channel usage", this.ROM[currentPos].ToHex()));
            currentPos++;

            sb.AppendLine(this.DisassembleSoundEffectData(trackInfo.TrackIndex, currentPos));

            return sb.ToString();
        }
        /// <summary>
        /// Disassembles the music track.
        /// </summary>
        /// <param name="trackInfo">The MusicTrackInfo object used to retrieve track information.</param>
        /// <returns>An annotated disassembly of the music track.</returns>
        private string DisassembleMusicTrack(ref MusicTrackInfo trackInfo)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(string.Format("TRACK{0}START:", trackInfo.TrackIndex));

            // The format of the music track is as follows:
            // Priority Byte
            // Channel 0 Pointer - Maybe 0000 to denote not used.
            // Channel 1 Pointer - Maybe 0000 to denote not used.
            // Channel 2 Pointer - Maybe 0000 to denote not used.
            // Channel 3 Pointer - Maybe 0000 to denote not used. Terminated with the end of data opcode.
            // Vibrato Table Pointer - Maybe 0000 to denote not used. To work out how many groups of 4 bytes there
            // are, the SetVibratoIndex command is tracked.
            int currentPos = trackInfo.TrackOffset;

            sb.AppendLine(string.Format(".byte ${0} ;priority. Lo=music priority, Hi=sfx priority", this.ROM[currentPos].ToHex()));
            currentPos++;

            // Channel 0
            if (this.ROM[currentPos] + this.ROM[currentPos + 1] > 0)
            {
                sb.AppendLine(".word Lbl_Track" + trackInfo.TrackIndex + "_Channel0");
            }
            else
            {
                sb.AppendLine(".word $0000");
            }

            currentPos += 2;

            // Channel 1
            if (this.ROM[currentPos] + this.ROM[currentPos + 1] > 0)
            {
                sb.AppendLine(".word Lbl_Track" + trackInfo.TrackIndex + "_Channel1");
            }
            else
            {
                sb.AppendLine(".word $0000");
            }

            currentPos += 2;

            // Channel 2
            if (this.ROM[currentPos] + this.ROM[currentPos + 1] > 0)
            {
                sb.AppendLine(".word Lbl_Track" + trackInfo.TrackIndex + "_Channel2");
            }
            else
            {
                sb.AppendLine(".word $0000");
            }

            currentPos += 2;

            // Channel 3
            if (this.ROM[currentPos] + this.ROM[currentPos + 1] > 0)
            {
                sb.AppendLine(".word Lbl_Track" + trackInfo.TrackIndex + "_Channel3");
            }
            else
            {
                sb.AppendLine(".word $0000");
            }

            currentPos += 2;

            bool hasVibratoPointer = false;

            // Vibrato
            if (this.ROM[currentPos] + this.ROM[currentPos + 1] > 0)
            {
                hasVibratoPointer = true;
                sb.AppendLine(".word Lbl_Track" + trackInfo.TrackIndex + "_Vibrato");
            }
            else
            {
                sb.AppendLine(".word $0000");
            }

            currentPos += 2;

            // Reset the track pointer.
            currentPos = trackInfo.TrackOffset + 1;
            int vibratoTracks = -1;

            // Channel 0
            sb.Append(this.DisassembleMusicChannelData(trackInfo.TrackIndex, currentPos, ref vibratoTracks, 0));
            currentPos += 2;

            // Channel 1
            sb.Append(this.DisassembleMusicChannelData(trackInfo.TrackIndex, currentPos, ref vibratoTracks, 1));
            currentPos += 2;

            // Channel 2
            sb.Append(this.DisassembleMusicChannelData(trackInfo.TrackIndex, currentPos, ref vibratoTracks, 2));
            currentPos += 2;

            // Channel 3
            sb.Append(this.DisassembleMusicChannelData(trackInfo.TrackIndex, currentPos, ref vibratoTracks, 3));
            currentPos += 2;

            // Vibrato
            if (vibratoTracks > -1 || hasVibratoPointer == true)
            {
                sb.Append(this.DisassembleMusicVibrato(trackInfo.TrackIndex, vibratoTracks, currentPos));
            }

            return sb.ToString();
        }