home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / cdrom / compactplayer / source / cd.c < prev    next >
C/C++ Source or Header  |  1995-12-28  |  6KB  |  298 lines

  1. #include "sysheaders.h"
  2. #include "cdpanel.h"
  3. #include "CompactPlayer.h"
  4.  
  5. /********************************************************
  6.  * SCSI
  7.  */
  8.  
  9. struct MsgPort *CDPort;
  10. struct IOStdReq *CDIO;
  11. struct IOStdReq *CDIO2;
  12. union CDTOC CDTOC[100];
  13.  
  14. #define BLOCKSPERSECOND 75
  15.  
  16. int __stdargs
  17. Open_CD(void)
  18. {
  19.     if ((CDPort        = CreateMsgPort()) &&
  20.         (CDIO        = CreateIORequest(CDPort, sizeof(struct IOStdReq))) &&
  21.         (CDIO2        = CreateIORequest(CDPort, sizeof(struct IOStdReq))) &&
  22.         !OpenDevice(Device, Unit, (struct IORequest *)CDIO, NULL))
  23.     {
  24.         *CDIO2 = *CDIO;
  25.         CDIO2->io_Command = 0;
  26.  
  27.         CD_Eject = Eject_CD;
  28.         CD_Stop = Stop_CD;
  29.         CD_Play = Play_CD;
  30.         CD_PauseResume = PauseResume_CD;
  31.         CD_Seek = Seek_CD;
  32.         CD_Snoop = Snoop_CD;
  33.         CD_ReadTOC = ReadTOC_CD;
  34.         CD_IsCD = IsCD_CD;
  35.         CD_Close = (void (*)(void))Close_CD;
  36.  
  37.         if (CD_IsCD())
  38.             return 0;
  39.     }
  40.     ErrorMsg(GS(DEVICE_FAIL), Device, Unit);
  41.     Close_CD();
  42.     return -1;
  43. }
  44.  
  45. void __stdargs
  46. Close_CD(void)
  47. {
  48.     if (CDIO2)
  49.     {
  50.         if (CDIO2->io_Command != 0)
  51.         {
  52.             AbortIO((struct IORequest *)CDIO2);
  53.             WaitIO((struct IORequest *)CDIO2);
  54.         }
  55.         DeleteIORequest(CDIO2);
  56.     }
  57.     if (CDIO)
  58.     {
  59.         if (CDIO->io_Command != 0)
  60.             CloseDevice((struct IORequest *)CDIO);
  61.         DeleteIORequest(CDIO);
  62.         CDIO = NULL;
  63.     }
  64.     if (CDPort)
  65.     {
  66.         DeleteMsgPort(CDPort);
  67.         CDPort = NULL;
  68.     }
  69.  
  70.     CD_Eject = (void (*)(UBYTE))Dummy;
  71.     CD_Stop = (void (*)(void))Dummy;
  72.     CD_Play = (void (*)(ULONG))Dummy;
  73.     CD_PauseResume = (void (*)(UBYTE))Dummy;
  74.     CD_Seek = (void (*)(LONG))Dummy;
  75.     CD_Snoop = (ULONG (*)(ULONG *, ULONG *, ULONG *, ULONG))Dummy;
  76.     CD_ReadTOC = (ULONG (*)(void))Dummy;
  77.     CD_IsCD = (BOOL (*)(void))Dummy;
  78.     CD_Close = (void (*)(void))Dummy;
  79. }
  80.  
  81. static int
  82. DoCD( ULONG cmd, APTR data, int dsize )
  83. {
  84.     if (CDIO)
  85.     {
  86.         CDIO->io_Command = cmd;
  87.         CDIO->io_Offset = 0;
  88.         CDIO->io_Data = data;
  89.         CDIO->io_Length = dsize;
  90.         
  91.         DoIO((struct IORequest *)CDIO);
  92.         
  93.         return CDIO->io_Error;
  94.     }
  95.     return -1;
  96. }
  97.  
  98. void
  99. Eject_CD(UBYTE out)
  100. {
  101.     DoCD( CD_EJECT, NULL, out ? 1 : 0 );
  102. }
  103.  
  104. void
  105. Stop_CD(void)
  106. {
  107.     if (CDIO2->io_Command != 0)
  108.     {
  109.         AbortIO((struct IORequest *)CDIO2);
  110.         WaitIO((struct IORequest *)CDIO2);
  111.     }
  112. }
  113.  
  114. void
  115. Play_CD(ULONG track)
  116. {
  117.     ULONG address, length;
  118.     
  119.     /* Play a track. Basic program (random order) support in here, even
  120.      * though there is no program editor yet. */
  121.     
  122.     if (TOCP[0] != ~0)
  123.     {
  124.         if (TOCP[track] == ~0)
  125.             return;
  126.         address = TOCL[TOCP[track-1]]+1;
  127.     }
  128.     else
  129.     {
  130.         if (track > Tracks)
  131.             return;
  132.         address = TOCL[track-1]+1;
  133.     }
  134.     Track = track;
  135.  
  136.     CDIO2->io_Offset = address;
  137.     
  138. #ifdef SINGLE_TRACK_PLAY
  139.     if (TOCP[0] != ~0)
  140.         length = TOCL[TOCP[track]] - address - 1;
  141.     else
  142.         length = TOCL[Tracks-1] - address - 1;
  143.  
  144.     CDIO2->io_Length = length;
  145. #else
  146.     /* continuous play */
  147.     if (TOCP[0] != ~0)
  148.         EndAddress = TOCL[TOCP[track]] - 1;
  149.     else
  150.         EndAddress = TOCL[Tracks-1] - 1;
  151.  
  152.     CDIO2->io_Length = EndAddress - address;
  153. #endif
  154.     
  155.     /* because a Toshiba XM3601B can abort a PLAY_AUDIO sent immediately
  156.      * after media change without any error code, we have a kludge that makes
  157.      * it restart. */
  158.     JustStarted = TRUE;
  159.     
  160.     CDIO2->io_Command = CD_PLAYLSN;
  161.     SendIO((struct IORequest *)CDIO2);
  162. }
  163.  
  164. void
  165. PauseResume_CD( UBYTE pause )
  166. {
  167.     DoCD( CD_PAUSE, NULL, pause ? 1 : 0 );
  168. }
  169.  
  170. void
  171. Seek_CD( LONG seconds )
  172. {
  173.     
  174. }
  175.  
  176. ULONG
  177. Snoop_CD( ULONG *track, ULONG *tracktime, ULONG *time, ULONG ostat )
  178. {
  179.     static struct QCode qc;
  180.     static struct CDInfo ci;
  181.     ULONG status;
  182.     
  183.     if (!DoCD( CD_QCODELSN, &qc, 0 ))
  184.     {
  185.         Track = *track = qc.Track;
  186.         *time = qc.DiskPosition.LSN / BLOCKSPERSECOND;
  187.         *tracktime = qc.TrackPosition.LSN / BLOCKSPERSECOND + 3 /* !!!! why the hell? */;
  188.     }
  189.     if (!DoCD( CD_INFO, &ci, sizeof(ci) ))
  190.     {
  191.         if (!(ci.Status & CDSTSF_CLOSED))
  192.         {
  193.             Ejected = TRUE;
  194.             status = CDP_EJECTED;
  195.         }
  196.         else
  197.         {
  198.             Ejected = FALSE;
  199.             status = CDP_EMPTY;
  200.  
  201.             if (ci.Status & CDSTSF_DISK)
  202.             {
  203.                 Ejected = FALSE;
  204.                 status = CDP_STOPPED;
  205.             }
  206.             if (ci.Status & CDSTSF_PLAYING)
  207.             {
  208. #ifndef SINGLE_TRACK_PLAY
  209.                 if (*time >= EndAddress)
  210.                 {
  211.                     CD_Play(Track + 1);
  212.                     return CD_Snoop(track, tracktime, time, CDP_STOPPED);
  213.                 }
  214. #endif
  215.                 status = CDP_PLAYING;
  216.             }
  217.             if (ci.Status & CDSTSF_PAUSED)
  218.             {
  219.                 status = CDP_PAUSED;
  220.             }
  221.             if (!(ci.Status & (CDSTSF_PLAYING|CDSTSF_PAUSED)))
  222.             {
  223.                 if (JustStarted && !(qc.CtlAdr & CTL_DATA))
  224.                 {
  225.                     CD_Play(Track);
  226.                     return CD_Snoop(track, tracktime, time, CDP_STOPPED);
  227.                 }
  228.                 else
  229.                 if (ostat == CDP_PLAYING)
  230.                 {
  231.                     CD_Play(Track + 1);
  232.                     return CD_Snoop(track, tracktime, time, CDP_STOPPED);
  233.                 }
  234.                 JustStarted = FALSE;
  235.                 *track = Track = 0;
  236.                 return CDP_STOPPED;
  237.             }
  238.             if (*tracktime > 1)
  239.                 JustStarted = TRUE;
  240.         }
  241.             
  242.         return status;
  243.     }
  244.     return CDP_EMPTY;
  245. }
  246.  
  247. ULONG
  248. ReadTOC_CD(void)
  249. {
  250.     if (!DoCD( CD_TOCLSN, CDTOC, 100 ))
  251.     {
  252.         union CDTOC *toc;
  253.         ULONG tracks = 0;
  254.         
  255.         for (toc = &CDTOC[1]; tracks < CDTOC[0].Summary.LastTrack; toc++)
  256.         {
  257.             TOCL[tracks] = toc->Entry.Position.LSN + 32; /* adding 32 makes it scsi.device compat */
  258.             TOCT[tracks] = TOCL[tracks] / BLOCKSPERSECOND;
  259.             TOCF[tracks] = toc->Entry.CtlAdr & CTL_DATA ? 1 : 0;
  260.             TOCS[tracks] = &TitleBuffer[(tracks+2)*40];
  261.             Sprintf(TOCS[tracks], GS(TRACK_NUM), tracks+1);
  262.             tracks++;
  263.         }
  264.         TOCS[tracks] = NULL;
  265.         TOCL[tracks] = CDTOC[0].Summary.LeadOut.LSN + 32;
  266.         TOCT[tracks] = TOCL[tracks] / BLOCKSPERSECOND;
  267.  
  268.         if (!GetIndex( tracks, TOCL[2], TOCL[tracks]))
  269.         {
  270.             TITLE[0] = NULL;
  271.             TITLE[1] = NULL;
  272.         }
  273.         
  274.         if (!TITLE[0])
  275.         {
  276.             TITLE[0] = &TitleBuffer[0];
  277.             strcpy(TITLE[0], GS(UNKNOWN_ARTIST));
  278.         }
  279.  
  280.         if (!TITLE[1])
  281.         {
  282.             TITLE[1] = &TitleBuffer[40];
  283.             strcpy(TITLE[1], GS(UNKNOWN_TITLE));
  284.         }
  285.  
  286.         return tracks;
  287.     }
  288.     return 0;
  289. }
  290.  
  291. BOOL
  292. IsCD_CD(void)
  293. {
  294.     static struct CDInfo ci;
  295.     
  296.     return (BOOL)(DoCD( CD_INFO, &ci, sizeof(ci) ) ? FALSE : TRUE);
  297. }
  298.