/***********************************************\
*                                               *
*          CDx Audio Access Sample Code         *
*                                               *
*  Prints the disc's table of contents          *
*                                               *
*  This version uses the cdx.device (v1.7+)     *
\***********************************************/

#include <exec/types.h>
#include <exec/io.h>
#include <CDx.h>

int   GetNumTracks(void);
int   GetLeadout(void);
int   TrackLoc(ULONG,struct CDTOC *);

extern   struct   IOStdReq       *Req;

main(argc,argv)
int   argc;
char **argv;
{
   int   i,error,numtracks,drive;
   struct   CDTOC toc;

   ParseParams("CDcontents [DRIVE n]",argc,argv,&drive,0);

   if (OpenCDx(drive))
      Cleanup("Drive not found",0);

   error = GetNumTracks();
   if (error)
      Cleanup(0,error);

   numtracks = Req->io_Actual;
   printf("Number of tracks: %ld\n\n",numtracks);

   printf("Track   Start Min/Sec/Frm  Type         Pre-Emphasis  Digital Copying\n");
   printf("---------------------------------------------------------------------\n");

   for (i=1;i<=numtracks;i++) {
      error = TrackLoc(i,&toc);
      if (error)
         Cleanup(0,error);

      printf(" %3ld           %2ld  %2ld  %2ld  ",i,
         MSF_MIN(toc.Position),
         MSF_SEC(toc.Position),
         MSF_FRM(toc.Position));
      if (toc.AddrCtrl & DATATRK)
         printf("Data        ");
      else
         printf((toc.AddrCtrl & FOURCHAN)?"Quadraphonic":"Stereo      ");

      printf("      %ls         %ls\n",
         (toc.AddrCtrl & PREEMPH)?"On ":"Off",
         (toc.AddrCtrl & COPYOK)?"Permitted":"Prohibited");
   }

   error = GetLeadout();
   if (error)
      Cleanup(0,error);

   printf("Leadout        %2ld  %2ld  %2ld\n",
      MSF_MIN(Req->io_Actual),
      MSF_SEC(Req->io_Actual),
      MSF_FRM(Req->io_Actual));

   Cleanup(0,0);
}


int GetNumTracks(void)
{
   Req->io_Command = CD_NUMTRACKS;
   DoIO((struct IORequest *)Req);

   return((int)Req->io_Error);
}


int GetLeadout(void)
{
   Req->io_Command = CD_LEADOUT;
   DoIO((struct IORequest *)Req);

   return((int)Req->io_Error);
}


int TrackLoc(track,toc)
ULONG track;
struct CDTOC *toc;
{
   Req->io_Command = CD_TRACKLOCMSF;
   Req->io_Offset = track;
   Req->io_Length = 1;
   Req->io_Data = (APTR)toc;
   DoIO((struct IORequest *)Req);

   return((int)Req->io_Error);
}
