void CommandReadTOC() { switch (CommandBuffer[1]) { case 0: // return number of tracks { DataIn.Clear(); DataIn.Enqueue(0x01); DataIn.Enqueue(((byte)disc.Session1.Tracks.Count).BinToBCD()); SetPhase(BusPhase_DataIn); break; } case 1: // return total disc length in minutes/seconds/frames { //zero 07-jul-2015 - I may have broken this int totalLbaLength = disc.Session1.LeadoutLBA; byte m, s, f; DiscUtils.Convert_LBA_To_AMSF(totalLbaLength + 150, 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. TODO - did zero adapt this right? track indexing might be off { int track = CommandBuffer[2].BCDtoBin(); var tracks = disc.Session1.Tracks; if (CommandBuffer[2] > 0x99) { throw new Exception("invalid track number BCD request... is something I need to handle?"); } if (track == 0) { track = 1; } int lbaPos; if (track > disc.Session1.InformationTrackCount) { lbaPos = disc.Session1.LeadoutLBA; //zero 03-jul-2015 - did I adapt this right? } else { lbaPos = tracks[track].LBA; } byte m, s, f; DiscUtils.Convert_LBA_To_AMSF(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.Session1.Tracks[track].IsAudio) { DataIn.Enqueue(0); } else { DataIn.Enqueue(4); } SetPhase(BusPhase_DataIn); break; } default: Console.WriteLine("unimplemented READ TOC command argument!"); break; } }