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