home *** CD-ROM | disk | FTP | other *** search
- #include "sysheaders.h"
- #include "cdpanel.h"
- #include "CompactPlayer.h"
-
- /********************************************************
- * SCSI
- */
-
- struct MsgPort *CDPort;
- struct IOStdReq *CDIO;
- struct IOStdReq *CDIO2;
- union CDTOC CDTOC[100];
-
- #define BLOCKSPERSECOND 75
-
- int __stdargs
- Open_CD(void)
- {
- if ((CDPort = CreateMsgPort()) &&
- (CDIO = CreateIORequest(CDPort, sizeof(struct IOStdReq))) &&
- (CDIO2 = CreateIORequest(CDPort, sizeof(struct IOStdReq))) &&
- !OpenDevice(Device, Unit, (struct IORequest *)CDIO, NULL))
- {
- *CDIO2 = *CDIO;
- CDIO2->io_Command = 0;
-
- CD_Eject = Eject_CD;
- CD_Stop = Stop_CD;
- CD_Play = Play_CD;
- CD_PauseResume = PauseResume_CD;
- CD_Seek = Seek_CD;
- CD_Snoop = Snoop_CD;
- CD_ReadTOC = ReadTOC_CD;
- CD_IsCD = IsCD_CD;
- CD_Close = (void (*)(void))Close_CD;
-
- if (CD_IsCD())
- return 0;
- }
- ErrorMsg(GS(DEVICE_FAIL), Device, Unit);
- Close_CD();
- return -1;
- }
-
- void __stdargs
- Close_CD(void)
- {
- if (CDIO2)
- {
- if (CDIO2->io_Command != 0)
- {
- AbortIO((struct IORequest *)CDIO2);
- WaitIO((struct IORequest *)CDIO2);
- }
- DeleteIORequest(CDIO2);
- }
- if (CDIO)
- {
- if (CDIO->io_Command != 0)
- CloseDevice((struct IORequest *)CDIO);
- DeleteIORequest(CDIO);
- CDIO = NULL;
- }
- if (CDPort)
- {
- DeleteMsgPort(CDPort);
- CDPort = NULL;
- }
-
- CD_Eject = (void (*)(UBYTE))Dummy;
- CD_Stop = (void (*)(void))Dummy;
- CD_Play = (void (*)(ULONG))Dummy;
- CD_PauseResume = (void (*)(UBYTE))Dummy;
- CD_Seek = (void (*)(LONG))Dummy;
- CD_Snoop = (ULONG (*)(ULONG *, ULONG *, ULONG *, ULONG))Dummy;
- CD_ReadTOC = (ULONG (*)(void))Dummy;
- CD_IsCD = (BOOL (*)(void))Dummy;
- CD_Close = (void (*)(void))Dummy;
- }
-
- static int
- DoCD( ULONG cmd, APTR data, int dsize )
- {
- if (CDIO)
- {
- CDIO->io_Command = cmd;
- CDIO->io_Offset = 0;
- CDIO->io_Data = data;
- CDIO->io_Length = dsize;
-
- DoIO((struct IORequest *)CDIO);
-
- return CDIO->io_Error;
- }
- return -1;
- }
-
- void
- Eject_CD(UBYTE out)
- {
- DoCD( CD_EJECT, NULL, out ? 1 : 0 );
- }
-
- void
- Stop_CD(void)
- {
- if (CDIO2->io_Command != 0)
- {
- AbortIO((struct IORequest *)CDIO2);
- WaitIO((struct IORequest *)CDIO2);
- }
- }
-
- void
- Play_CD(ULONG track)
- {
- ULONG address, length;
-
- /* Play a track. Basic program (random order) support in here, even
- * though there is no program editor yet. */
-
- if (TOCP[0] != ~0)
- {
- if (TOCP[track] == ~0)
- return;
- address = TOCL[TOCP[track-1]]+1;
- }
- else
- {
- if (track > Tracks)
- return;
- address = TOCL[track-1]+1;
- }
- Track = track;
-
- CDIO2->io_Offset = address;
-
- #ifdef SINGLE_TRACK_PLAY
- if (TOCP[0] != ~0)
- length = TOCL[TOCP[track]] - address - 1;
- else
- length = TOCL[Tracks-1] - address - 1;
-
- CDIO2->io_Length = length;
- #else
- /* continuous play */
- if (TOCP[0] != ~0)
- EndAddress = TOCL[TOCP[track]] - 1;
- else
- EndAddress = TOCL[Tracks-1] - 1;
-
- CDIO2->io_Length = EndAddress - address;
- #endif
-
- /* because a Toshiba XM3601B can abort a PLAY_AUDIO sent immediately
- * after media change without any error code, we have a kludge that makes
- * it restart. */
- JustStarted = TRUE;
-
- CDIO2->io_Command = CD_PLAYLSN;
- SendIO((struct IORequest *)CDIO2);
- }
-
- void
- PauseResume_CD( UBYTE pause )
- {
- DoCD( CD_PAUSE, NULL, pause ? 1 : 0 );
- }
-
- void
- Seek_CD( LONG seconds )
- {
-
- }
-
- ULONG
- Snoop_CD( ULONG *track, ULONG *tracktime, ULONG *time, ULONG ostat )
- {
- static struct QCode qc;
- static struct CDInfo ci;
- ULONG status;
-
- if (!DoCD( CD_QCODELSN, &qc, 0 ))
- {
- Track = *track = qc.Track;
- *time = qc.DiskPosition.LSN / BLOCKSPERSECOND;
- *tracktime = qc.TrackPosition.LSN / BLOCKSPERSECOND + 3 /* !!!! why the hell? */;
- }
- if (!DoCD( CD_INFO, &ci, sizeof(ci) ))
- {
- if (!(ci.Status & CDSTSF_CLOSED))
- {
- Ejected = TRUE;
- status = CDP_EJECTED;
- }
- else
- {
- Ejected = FALSE;
- status = CDP_EMPTY;
-
- if (ci.Status & CDSTSF_DISK)
- {
- Ejected = FALSE;
- status = CDP_STOPPED;
- }
- if (ci.Status & CDSTSF_PLAYING)
- {
- #ifndef SINGLE_TRACK_PLAY
- if (*time >= EndAddress)
- {
- CD_Play(Track + 1);
- return CD_Snoop(track, tracktime, time, CDP_STOPPED);
- }
- #endif
- status = CDP_PLAYING;
- }
- if (ci.Status & CDSTSF_PAUSED)
- {
- status = CDP_PAUSED;
- }
- if (!(ci.Status & (CDSTSF_PLAYING|CDSTSF_PAUSED)))
- {
- if (JustStarted && !(qc.CtlAdr & CTL_DATA))
- {
- CD_Play(Track);
- return CD_Snoop(track, tracktime, time, CDP_STOPPED);
- }
- else
- if (ostat == CDP_PLAYING)
- {
- CD_Play(Track + 1);
- return CD_Snoop(track, tracktime, time, CDP_STOPPED);
- }
- JustStarted = FALSE;
- *track = Track = 0;
- return CDP_STOPPED;
- }
- if (*tracktime > 1)
- JustStarted = TRUE;
- }
-
- return status;
- }
- return CDP_EMPTY;
- }
-
- ULONG
- ReadTOC_CD(void)
- {
- if (!DoCD( CD_TOCLSN, CDTOC, 100 ))
- {
- union CDTOC *toc;
- ULONG tracks = 0;
-
- for (toc = &CDTOC[1]; tracks < CDTOC[0].Summary.LastTrack; toc++)
- {
- TOCL[tracks] = toc->Entry.Position.LSN + 32; /* adding 32 makes it scsi.device compat */
- TOCT[tracks] = TOCL[tracks] / BLOCKSPERSECOND;
- TOCF[tracks] = toc->Entry.CtlAdr & CTL_DATA ? 1 : 0;
- TOCS[tracks] = &TitleBuffer[(tracks+2)*40];
- Sprintf(TOCS[tracks], GS(TRACK_NUM), tracks+1);
- tracks++;
- }
- TOCS[tracks] = NULL;
- TOCL[tracks] = CDTOC[0].Summary.LeadOut.LSN + 32;
- TOCT[tracks] = TOCL[tracks] / BLOCKSPERSECOND;
-
- if (!GetIndex( tracks, TOCL[2], TOCL[tracks]))
- {
- TITLE[0] = NULL;
- TITLE[1] = NULL;
- }
-
- if (!TITLE[0])
- {
- TITLE[0] = &TitleBuffer[0];
- strcpy(TITLE[0], GS(UNKNOWN_ARTIST));
- }
-
- if (!TITLE[1])
- {
- TITLE[1] = &TitleBuffer[40];
- strcpy(TITLE[1], GS(UNKNOWN_TITLE));
- }
-
- return tracks;
- }
- return 0;
- }
-
- BOOL
- IsCD_CD(void)
- {
- static struct CDInfo ci;
-
- return (BOOL)(DoCD( CD_INFO, &ci, sizeof(ci) ) ? FALSE : TRUE);
- }
-