Projekte > Optische Laufwerke > Medieninformationen

Table of Contents (RAW)

READ TOC/PMA/ATIP Command - Operation Code $43

Die Table of Contents (TOC) ist das Inhaltsverzeichnis. Das Command ist mit bestimmten Feature (siehe Feature List) verbunden. Im Gegensatz zum Antwortformat formatierte TOC im Kapitel Table of Contents (MMC) ist das Antwortformat rohe TOC nur mit dem Feature CD READ verbunden.

Der READ TOC/PMA/ATIP Command Descriptor Block ist in Kapitel 6.25.2.1 dargestellt:

  7 6 5 4 3 2 1 0
0 Operation Code ($43)
1 Reserviert MSF (1b) Reserviert
2 Reserviert Format (0010b)
3 Reserviert
4
5
6 Track/Session Number ($00)
7 Allocation Length
8
9 Control

 

Zu setzende Werte:

Operation Code: $43 - READ TOC/PMA/ATIP Command.

MSF: 1b - Die Adressen sollen in MSF (Minuten:Sekunden:Frames) angegeben werden. Das Bit muss hier nicht gesetzt werden. Die Angabe wird vom Laufwerk ignoriert da das gewählte Format es als gesetzt definiert.

Format: 0010b Raw TOC - Die Antwort soll eine vollständige rohe TOC enthalten.

Track/Session Number: $00 - Die Daten werden beginnend ab der angegebenen Sessionnummer zurückgegeben.

Allocation Length: $F03F - Die Länge der Antwortstruktur. Das Response Format 0010b - Formatted TOC hat für CDs keine feste Länge. Die Felder für die Längenangaben sind jeweils zwei Byte lang, so dass die Länge theoretisch bis $FFFF betragen kann. Werte über $F03F (61503) führten zu Fehlern, so dass hier dieser Wert gewählt wurde. Bei 100 möglichen Tracks ist das dies mehr als ausreichend.

Control - ?

 

Antwortstruktur

Die Beschreibung des Antwortformates ist in der MMC-6 in Kapitel 6.25.3.4.1 enthalten:

  7 6 5 4 3 2 1 0
0 TOC Data Length
1
2 First Complette Session Number
3 Last Complette Session Number
  TOC Track Descriptor(s)
0 Session Number
1 ADR CONTROL
2 TNO
3 POINT
4 MIN
5 SEC
6 FRAME
7 ZERO
8 PMIN
9 PSEC
10 PFRAME

 
TOC Data Length
Gibt in Bytes an, wie lang die folgende Datenstruktur ist.

First Complette Session Number: Die erste vollständige Session ist auf Eins gesetzt.

Last Complette Session Number: Gibt die letzte vollständige Session an. Bei Single Session Discs oder wenn das Laufwerk keine Multisession Discs unterstützt ist dies Eins.

ADR: Gibt den Typ der Information an.

$0 - Q Sub-channel mode Informationen werden nicht unterstützt
$1 - Q Sub-channel Daten enthalten die gegenwärtige Position
$5 - Q Sub-channel enthält zusätzliche Informationen über CD-R und CD-RW Aufnahmen.

CONTROL: Gibt die Attribute des Tracks an.

00x0b - Zwei Audiokanäle ohne Preemphasis
00x1b - Zwei AudioKanäle mit Preemphasis 50/15
10x0b - Audiokanäle ohne Preemphasis (Reserviert für CD-R/RW)
10x1b - Audiokanäle mit Preemphasis 50/15 (reserviert für CD-R/RW)
01x0b - Datentrack, ununterbrochen aufgezeichnet
01x1b - Datentrack, schrittweise aufgenommen
11xxb - Reserviert
xx0xb - Digital kopiergeschützt
xx1xb - Digital kopieren erlaubt

Die Einträge für TNO, POINT, MIN, SEC, FRAME und ZERO ergeben als Binärzahl einen Wert zwischen 0 und 99bcd.

Die zurückgegebenen Daten der TOC einer Multisession-Disc werden in aufsteigender Reihenfolge der Sessionnummer angeordnet, wobei Duplikate entfernt wurden. Die Daten innerhalb einer Session sind in der Reihenfolge der Q Subchannel POINT Feldwerte A0h Afh und Titelnummern, B0h - BFh angeordnet. Nur aufgezeichnete Punkte werden zurückgegeben. Die Trackbeschreibungsformate im Q Subchannel:

CTRL ADR TNO POINT MIN SEC FRAME ZERO PMIN PSEC PFRAME
4, 1 1 $00 $01..$63 ATIME (Absolute Zeit) $00 Startposition Track
4, 1 1 $00 $A0 ATIME (Absolute Zeit) $00 Erster
Track
Disk
Typ
$00
4, 1 1 $00 $A1 ATIME (Absolute Zeit) $00 Letzter
Track
$00 $00
4, 1 1 $00 $A2 ATIME (Absolute Zeit) $00 Startposition Lead-out
4, 1 5 $00 $B0 Startzeit des nächstmöglichen
Programms im
Aufnahmebereich der Disk
# der
Pointer
Maximale Startzeit des äußersten
Lead-out-Bereichs im
Aufnahmebereich der Disk
4, 6 5 $00 $B1 $00 $00 $00 $00 # Skip
Interval Ptr
(N<=40)
# Skip
Track Ptr
(N<=21)
$00
4, 6 5 $00 $B2..$B4 Skip # Skip # Skip # Skip # Skip # Skip # Skip #
4, 6 5 $00 $01..$40 Endzeit für das Intervall, das
übersprungen werden soll.
Reser-
viert
Startzeit für das Intervall, das
übersprungen werden soll.
4, 6 5 $00 $C0 Opt. Brenn-
leistung
Reser-
viert
Reser-
viert
Reser-
viert
Startzeit des ersten Lead-in-
Bereiches der Disk.
4, 6 5 $00 $C1 Kopie der Information vom Point A1 des ATIP.

 
Die POINT Felder:

ADR Point Field Beschreibung
1 $01..$63 Tracknummerangaben
1 $A0 Erster Track im Programmbereich
1 $A1 Letzter Track im Programmbereich
1 $A2 Startposition des Lead-Out Bereiches
5 $01..$40 Sprungabstandszeiger
5 $B0 Zur Identifikation einer Multisession-Disk (Foto CD). Enthält die
Startzeit des nächstmöglichen Programmbereiches
5 $B1 Anzahl der Sprungintervallzeiger und Sprungtrackzuweisungen
5 $$01..$40 Sprungintervallzeiger
5 $B2..$B4 Sprungtrackzuweisungszeiger
5 $C0 Startzeit des ersten Lead-In Bereiches der Disk (Dies existiert nur
im ersten Lead-In Bereich)
5 $C1 Kopie der Information vom Zusatzbereich 1 des ATIP

 
Die Disk Types:

Wert Beschreibung
$00 CD-DA oder CD-ROM mit erstem Track in Mode 1
$10 CD-I
$20 CD-ROM XA mit erstem Track in Mode 2

 

Deklarationen

 
  {
  *  Für die Auswertung.
  }
  type
    TRawTOCTrackDescriptor = record
      SessionNumber : Byte;
      ADR           : Byte;
      CONTROL       : Byte;
      TNO           : Byte;
      POINT         : Byte;
      MIN           : Byte;
      SEC           : Byte;
      FRAME         : Byte;
      ZERO          : Byte;
      PMIN          : Byte;
      PSEC          : Byte;
      PFRAME        : Byte;
    end;
 
  type
    TRawTOC = record
      DataLength         : Word;
      FirstSessionNumber : Byte;
      LastSessionNumber  : Byte;
      TrackDescriptor    : Array of TRawTOCTrackDescriptor;
    end;
 
  {
  *  Für den Befehl.
  }
  const
    RespFmtTOC    = $00;
    RespFmtMSI    = $01;
    RespFmtRawTOC = $02;
    RespFmtPMA    = $03;
    RespFmtATIP   = $04;
    RespFmtCDTEXT = $05;
 
  const
    SCSIOP_READ_TOC_PMA_ATIP = $43;
 
  type
    TREAD_TOC_PMA_ATIP_CDB = record
      OperationCode      : Byte;
      MSF                : Byte;
      Format             : Byte;
      TrackSessionNumber : Byte;
      AllocationLength   : Word;
      Control            : Byte;
    end;
 
  type
    TREAD_TOC_DATA = record
      General : Array[$00..$03] of byte;
      Data    : Array[$0000..$EFFF] of Byte;
    end;
 
          

 

Ausführung und Auswertung

Nach dem Ausfüllen des Command Descriptors Blockes wird die Abfrage ausgeführt und die Antwort ausgewertet.

 
  function TOptDrives.ReadTOCRaw(aDevice: THandle): Boolean;
  {*******************************************************************************
  *  Die rohe Table of Contents ermitteln.
  }
  var
    READ_TOC_PMA_ATIP_CDB  : TREAD_TOC_PMA_ATIP_CDB;
    pReadTOCData           : PREAD_TOC_PMA_ATIP_DATA;
    aCDB                   : Array of Byte;
    nDescCount             : Integer;
    i                      : Integer;
  begin
    Result := False;
    {
    *  TOC initialisieren.
    }
    FillChar(FDrive[FActive].TableOfContentsRAW,
             SizeOf(FDrive[FActive].TableOfContentsRAW), $00);
    {
    *  Den Command Descriptor Block füllen.
    }
    ZeroMemory(@READ_TOC_PMA_ATIP_CDB, SizeOf(READ_TOC_PMA_ATIP_CDB));
    READ_TOC_PMA_ATIP_CDB.OperationCode    := SCSIOP_READ_TOC_PMA_ATIP;
    READ_TOC_PMA_ATIP_CDB.MSF              := 1;
    READ_TOC_PMA_ATIP_CDB.Format           := RF_RawTOC;
    READ_TOC_PMA_ATIP_CDB.AllocationLength := SizeOf(TREAD_TOC_PMA_ATIP_DATA);
    {
    *  Den Command Descriptor Block übertragen.
    }
    SetLength(aCDB, 10);
    aCDB[0] := READ_TOC_PMA_ATIP_CDB.OperationCode;
    aCDB[1] := READ_TOC_PMA_ATIP_CDB.MSF and $01 shl 1;
    aCDB[2] := READ_TOC_PMA_ATIP_CDB.Format and $0F;
    aCDB[7] := HiByte(READ_TOC_PMA_ATIP_CDB.AllocationLength);
    aCDB[8] := LoByte(READ_TOC_PMA_ATIP_CDB.AllocationLength);
    {
    *  Befehl ausführen.
    }
    GetMem(pReadTOCData, SizeOf(TREAD_TOC_PMA_ATIP_DATA));
    Result := GET_SCSI_PASS_THROUGH_DIRECT(aDevice, aCDB, pReadTOCData,
                                           SizeOf(TREAD_TOC_PMA_ATIP_DATA));
    if Result then
    with FDrive[FActive].TableOfContentsRAW
    do begin
      DataLength := pReadTOCData.General[0] shl 8 or pReadTOCData.General[1];
      {
      *  Prüfen, ob Daten folgen.
      }
      if DataLength > 0
      then begin
        {
        *  General
        }
        FirstSessionNumber := pReadTOCData.General[2];
        LastSessionNumber  := pReadTOCData.General[3];
        {
        *  Wenn Tracks angegeben sind.
        }
        if DataLength > 2
        then begin
          nDescCount := (DataLength - 2) div 11;
          SetLength(TrackDescriptor, nDescCount);
          for i := 0 to nDescCount - 1 do
          with TrackDescriptor[i]
          do begin
            SessionNumber := pReadTOCData.Data[(i * 11)];
            ADR           := pReadTOCData.Data[(i * 11) + 1] and $F0 shr 4;
            CONTROL       := pReadTOCData.Data[(i * 11) + 1] and $0F;
            TNO           := pReadTOCData.Data[(i * 11) + 2];
            POINT         := pReadTOCData.Data[(i * 11) + 3];
            MIN           := pReadTOCData.Data[(i * 11) + 4];
            SEC           := pReadTOCData.Data[(i * 11) + 5];
            FRAME         := pReadTOCData.Data[(i * 11) + 6];
            ZERO          := pReadTOCData.Data[(i * 11) + 7];
            PMIN          := pReadTOCData.Data[(i * 11) + 8];
            PSEC          := pReadTOCData.Data[(i * 11) + 9];
            PFRAME        := pReadTOCData.Data[(i * 11) + 10];
          end;
        end;
      end;
    end;
  end;
          

 

Demo, welche diese Funktion nutzt:

Table of Contents (RAW) (podTableOfContentsRAW.7z - 310 kb) MD5 (1 kb). Stand: 22. Juli 2013

Bei Start Address und Comment werden nur ADR = 1 und Point $01..$63 sowie $A0..$A2 berücksichtigt, da mir die anderen Points auf meinen CDs noch nicht begegnet sind.

Änderungen an der Demo

Datum Beschreibung
26.02.2012Aktualisiert: Groupbox "Optische Laufwerke".

Beispiel für eine AudioCd mit Datenanteil.

 

Altenative Demo mit anderer Darstellung::

Table Of Contents TOC (RAW) alternativ. (podTableOfContentsRAWalt.7z - 313 kb) MD5 (1 kb). Stand: 22. Juli 2013