void CommandReadTOC() { switch (CommandBuffer[1]) { case 0: // return number of tracks { DataIn.Clear(); DataIn.Enqueue(0x01); DataIn.Enqueue(((byte)disc.TOC.Sessions[0].Tracks.Count).BinToBCD()); SetPhase(BusPhase_DataIn); break; } case 1: // return total disc length in minutes/seconds/frames { int totalLbaLength = disc.LBACount; byte m, s, f; Disc.ConvertLBAtoMSF(totalLbaLength, out m, out s, out f); DataIn.Clear(); DataIn.Enqueue(m.BinToBCD()); DataIn.Enqueue(s.BinToBCD()); DataIn.Enqueue(f.BinToBCD()); SetPhase(BusPhase_DataIn); break; } case 2: // Return starting position of specified track in MSF format { int track = CommandBuffer[2].BCDtoBin(); var tracks = disc.TOC.Sessions[0].Tracks; if (CommandBuffer[2] > 0x99) { throw new Exception("invalid track number BCD request... is something I need to handle?"); } if (track == 0) { track = 1; } track--; int lbaPos; if (track > tracks.Count) { lbaPos = disc.TOC.Sessions[0].length_aba - 150; } else { lbaPos = tracks[track].Indexes[1].aba - 150; } byte m, s, f; Disc.ConvertLBAtoMSF(lbaPos, out m, out s, out f); DataIn.Clear(); DataIn.Enqueue(m.BinToBCD()); DataIn.Enqueue(s.BinToBCD()); DataIn.Enqueue(f.BinToBCD()); if (track > tracks.Count || disc.TOC.Sessions[0].Tracks[track].TrackType == ETrackType.Audio) { DataIn.Enqueue(0); } else { DataIn.Enqueue(4); } SetPhase(BusPhase_DataIn); break; } default: Console.WriteLine("unimplemented READ TOC command argument!"); break; } }