home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 17
/
CD_ASCQ_17_101194.iso
/
dos
/
prg
/
cthugha5
/
cthu5src
/
cdrom.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-19
|
14KB
|
801 lines
; /*\
; |*| cdrom.c
; |*|
; |*| routines for c-interface to mscdex audio functions
; |*|
; |*| Copyright (c) 1992, Media Vision, Inc. All Rights Reserved
; |*|
; \*/
#include "cdrom.h"
static int OURDISCSTATUS[26];
; /*\
; |*| cdplay(int drive, long frame, long lframe)
; |*|
; |*| begin audio play on drive from frame for lframe frames
; |*|
; |*| Entry: drive number, starting frame, count of frames to play
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdplay(int drive, long frame, long lframe)
{
struct ioctlplay iop;
iop.cdh.len= 13;
iop.cdh.unit= (char) drive;
iop.cdh.cmd= CD_CMD_PLAY;
iop.cdh.stat= 0;
iop.addrmode= 0;
iop.startsector= frame- 150;
iop.sectorcount= lframe;
senddevreq(drive, &iop);
if (!(iop.cdh.stat& 0x8000) || (iop.cdh.stat& 0x0100))
{
OURDISCSTATUS[drive]|= CDISPLAYING;
OURDISCSTATUS[drive]&= (-1^ CDISPAUSED);
}
return(iop.cdh.stat);
}
; /*\
; |*| cdstop(int drive)
; |*|
; |*| stop audio play on drive
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdstop(int drive)
{
struct ioctlstop ios;
if (cdstatus(drive)& CDISPLAYING)
cdpause(drive);
ios.cdh.len= 13;
ios.cdh.unit= (char) drive;
ios.cdh.cmd= CD_CMD_STOP;
ios.cdh.stat= 0;
senddevreq(drive, &ios);
if (!(ios.cdh.stat& 0x8000) || (ios.cdh.stat& 0x0100))
{
OURDISCSTATUS[drive]&= (-1^ (CDISPAUSED| CDISPLAYING));
}
return(ios.cdh.stat);
}
; /*\
; |*| cdpause(int drive)
; |*|
; |*| pause audio play on drive
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: return 0 if not playing, else return driver status
; |*|
; \*/
cdpause(int drive)
{
struct ioctlstop ios;
if (!(cdstatus(drive)& CDISPLAYING))
return(0);
ios.cdh.len= 13;
ios.cdh.unit= (char) drive;
ios.cdh.cmd= CD_CMD_STOP;
ios.cdh.stat= 0;
senddevreq(drive, &ios);
if (!(ios.cdh.stat& 0x8000))
{
OURDISCSTATUS[drive]|= CDISPAUSED;
OURDISCSTATUS[drive]&= (-1^ CDISPLAYING);
}
return(ios.cdh.stat);
}
; /*\
; |*| cdresume(int drive)
; |*|
; |*| resume paused audio play on drive
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdresume(int drive)
{
struct ioctlresume ior;
ior.cdh.len= 13;
ior.cdh.unit= (char) drive;
ior.cdh.cmd= CD_CMD_RESUME;
ior.cdh.stat= 0;
senddevreq(drive, &ior);
if (!(ior.cdh.stat& 0x8000))
{
if ((cdstatus(drive)& CDISPLAYING))
OURDISCSTATUS[drive]|= CDISPLAYING;
OURDISCSTATUS[drive]&= (-1^ CDISPAUSED);
}
return(ior.cdh.stat);
}
; /*\
; |*| cdseek(int drive, long frame)
; |*|
; |*| move head on drive to specified frame
; |*|
; |*| Entry: drive number, frame number
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdseek(int drive, long frame)
{
struct ioctlseek ios;
ios.cdh.len= 13;
ios.cdh.unit= (char) drive;
ios.cdh.cmd= CD_CMD_SEEK;
ios.cdh.stat= 0;
ios.addrmode= 0;
ios.buffer= (void far *) 0;
ios.sectorcount= 0;
ios.startsector= frame- 150;
senddevreq(drive, &ios);
if (!(ios.cdh.stat& 0x8000))
{
OURDISCSTATUS[drive]&= (-1^ (CDISPLAYING| CDISPAUSED));
}
return(ios.cdh.stat);
}
; /*\
; |*| cdreset(int drive)
; |*|
; |*| reset the driver for specified drive
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdreset(int drive)
{
struct ioctlwrite iow;
char dummy= CD_CMD_RESET;
iow.cdh.len= 13;
iow.cdh.unit= (char) drive;
iow.cdh.cmd= IOCTL_WRITE;
iow.cdh.stat= 0;
iow.mdb= 0;
iow.buffer= (void far *) &dummy;
iow.size= sizeof(dummy);
iow.ssn= 0;
iow.errbuf= (void far *) 0;
senddevreq(drive, &iow);
if (!(iow.cdh.stat& 0x8000))
OURDISCSTATUS[drive]&= (-1^ (CDISPAUSED| CDISPLAYING| CDISHERE));
return(iow.cdh.stat);
}
; /*\
; |*| cdeject(int drive)
; |*|
; |*| eject disc in drive
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdeject(int drive)
{
struct ioctlwrite iow;
char dummy= CD_CMD_EJECT;
iow.cdh.len= 13;
iow.cdh.unit= (char) drive;
iow.cdh.cmd= IOCTL_WRITE;
iow.cdh.stat= 0;
iow.mdb= 0;
iow.buffer= (void far *) &dummy;
iow.size= sizeof(dummy);
iow.ssn= 0;
iow.errbuf= (void far *) 0;
senddevreq(drive, &iow);
if (!(iow.cdh.stat& 0x8000))
OURDISCSTATUS[drive]&= (-1^ (CDISPAUSED| CDISPLAYING| CDISHERE));
return(iow.cdh.stat);
}
; /*\
; |*| cdstatus(int drive)
; |*|
; |*| get audio status of drive number, update internal status variable
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: internal status variable
; |*|
; \*/
cdstatus(int drive)
{
int status= 0;
long d1, d2;
status= cdaudiostatus(drive, &d1, &d2);
return(OURDISCSTATUS[drive]);
}
; /*\
; |*| cdaudiostatus(int drive, long *nextstart, long *nextend)
; |*|
; |*| get audio status of drive number, update internal status variable
; |*|
; |*| Entry: drive number, pointers to nextstart and nextend frames
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdaudiostatus(int drive, long *nextstart, long *nextend)
{
int status= 0;
struct ioctlread ior;
struct ioctlstat ios;
struct qchaninfo sqi;
cdqchaninfo(drive, &sqi);
ior.cdh.len= 13;
ior.cdh.unit= (char) drive;
ior.cdh.cmd= IOCTL_READ;
ior.cdh.stat= 0;
ior.mdb= 0;
ior.buffer= (void far *) &ios;
ior.size= sizeof(ios);
ior.ssn= 0;
ior.errbuf= (void far *) 0;
ios.cmd= 15;
ios.status= 0;
ios.startloc= 0;
ios.endloc= 0;
senddevreq(drive, &ior);
if (ior.cdh.stat& 0x0200) status|= CDISPLAYING;
if (ios.status& 0x0001) status|= CDISPAUSED;
OURDISCSTATUS[drive]&= CDISHERE;
if (OURDISCSTATUS[drive]& CDISHERE)
if (!status)
{
int i= 0;
long d;
long s;
struct qchaninfo dqi;
s= msftolong(* ((long *) &sqi.min));
do
{
long *pd= (long *) &dqi.min;
cdqchaninfo(drive, &dqi);
d= msftolong(*pd);
}
while (++i < 5 && d - s < 75);
if (i < 5) status|= CDISPLAYING;
}
OURDISCSTATUS[drive]|= status;
*nextstart= ios.startloc;
*nextend= ios.endloc;
return(ios.status);
}
; /*\
; |*| cdmediachanged(int drive, int *yesorno)
; |*|
; |*| check if media has changed for drive
; |*|
; |*| Entry: drive number, pointer to flag
; |*|
; |*| Exit: return 0 if successful, else return -1 if error occurred
; |*|
; \*/
cdmediachanged(int drive, int *yesorno)
{
int status= 0;
struct ioctlread ior;
struct {
char cmd;
char changed;
} dummy;
ior.cdh.len= sizeof(struct cdreqheader);
ior.cdh.unit= (char) drive;
ior.cdh.cmd= IOCTL_READ;
ior.cdh.stat= 0;
ior.mdb= 0;
ior.buffer= (void far *) &dummy;
ior.size= sizeof(dummy);
ior.ssn= 0;
ior.errbuf= (void far *) 0;
dummy.cmd= 9;
dummy.changed= 0;
senddevreq(drive, &ior);
status= ior.cdh.stat;
if (status& 0x8000)
return(-1);
*yesorno= dummy.changed;
return(0);
}
; /*\
; |*| int cddiscinfo(int drive, struct discinfo *di)
; |*|
; |*| get information on disc in drive
; |*|
; |*| Entry: drive number, address of buffer
; |*|
; |*| Exit: return driver status
; |*|
; \*/
int cddiscinfo(int drive, struct discinfo *di)
{
int status= 0;
struct ioctlread ior;
ior.cdh.len= sizeof(struct cdreqheader);
ior.cdh.unit= (char) drive;
ior.cdh.cmd= IOCTL_READ;
ior.cdh.stat= 0;
ior.mdb= 0;
ior.buffer= (void far *) di;
ior.size= sizeof(struct discinfo);
ior.ssn= 0;
ior.errbuf= (void far *) 0;
di->cmd= CD_GETDISCINFO;
di->strk= 0;
di->ltrk= 0;
di->eodisc= 0;
senddevreq(drive, &ior);
status= ior.cdh.stat;
if (status& 0x8000 || !(status& 0x0100))
OURDISCSTATUS[drive]&= (-1^ CDISHERE);
else
OURDISCSTATUS[drive]|= CDISHERE;
return(status);
}
; /*\
; |*| int cdtrackinfo(int drive, int track, struct trackinfo *ti)
; |*|
; |*| get information on track of disc in drive
; |*|
; |*| Entry: drive number, track number, address of buffer
; |*|
; |*| Exit: return driver status
; |*|
; \*/
int cdtrackinfo(int drive, int track, struct trackinfo *ti)
{
int status= 0;
struct ioctlread ior;
ior.cdh.len= 13;
ior.cdh.unit= (char) drive;
ior.cdh.cmd= IOCTL_READ;
ior.cdh.stat= 0;
ior.mdb= 0;
ior.buffer= (void far *) ti;
ior.size= sizeof(struct trackinfo);
ior.ssn= 0;
ior.errbuf= (void far *) 0;
ti->cmd= CD_GETTRACKINFO;
ti->track= (char) track;
ti->min= 0;
ti->sec= 0;
ti->frame= 0;
ti->control= 0;
senddevreq(drive, &ior);
status|= ior.cdh.stat;
return(status);
}
; /*\
; |*| int cdqchaninfo(int drive, struct qchaninfo *qi)
; |*|
; |*| get status from q-channel for drive
; |*|
; |*| Entry: drive number, address of buffer
; |*|
; |*| Exit: return driver status
; |*|
; \*/
int cdqchaninfo(int drive, struct qchaninfo *qi)
{
int status= 0;
struct ioctlread ior;
ior.cdh.len= sizeof(struct cdreqheader);
ior.cdh.unit= (char) drive;
ior.cdh.cmd= IOCTL_READ;
ior.cdh.stat= 0;
ior.mdb= 0;
ior.buffer= (void far *) qi;
ior.size= sizeof(struct qchaninfo);
ior.ssn= 0;
ior.errbuf= (void far *) 0;
qi->cmd= CD_GETQCHANINFO;
qi->caa= 0;
qi->track= 0;
qi->index= 0;
qi->min= 0;
qi->sec= 0;
qi->frame= 0;
qi->reserved1= 0;
qi->amin= 0;
qi->asec= 0;
qi->aframe= 0;
senddevreq(drive, &ior);
status= ior.cdh.stat;
if (status& 0x8000 || !(status& 0x0100))
OURDISCSTATUS[drive]&= (-1^ CDISHERE);
else
OURDISCSTATUS[drive]|= CDISHERE;
return(status);
}
; /*\
; |*| isanaudiocd(int drive)
; |*|
; |*| check if disc in drive is an audio cd
; |*|
; |*| Entry: drive number
; |*|
; |*| Exit: return 1 if is an audio cd, else return 0
; |*|
; \*/
isanaudiocd(int drive)
{
int failcount= 0;
struct discinfo di;
do
{
if (!((cddiscinfo(drive, &di))& 0x8000))
return(1);
}
while (++failcount < 5);
return(0);
}
; /*\
; |*| cdseekmsf(int drive, int min, int sec, int frame)
; |*|
; |*| move head on drive to frame specified by min:sec:frame
; |*|
; |*| Entry: drive number, minutes, seconds, frames
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdseekmsf(int drive, int min, int sec, int frame)
{
long f;
f= (long) min* 60;
f+= (long) sec;
f*= (long) 75;
f+= (long) frame;
return(cdseek(drive, f));
}
; /*\
; |*| cdplaymsf(int drive, int min, int sec, int frame, int lmin, int lsec, int lframe)
; |*|
; |*| begin play for drive according at min:sec:frame for min:sec:frame
; |*|
; |*| Entry: drive number, minutes:seconds:frames to start and
; |*| minutes:seconds:frames for length
; |*|
; |*| Exit: return driver status
; |*|
; \*/
cdplaymsf(int drive, int min, int sec, int frame, int lmin, int lsec, int lframe)
{
long f;
long lf;
f= (long) min* 60;
f+= (long) sec;
f*= (long) 75;
f+= (long) frame;
lf= (long) lmin* 60;
lf+= (long) lsec;
lf*= (long) 75;
lf+= (long) lframe;
return(cdplay(drive, f, lf));
}
; /*\
; |*| long redtolong(long redaddress)
; |*|
; |*| convert redbook address to frame number
; |*|
; |*| Entry: redbook address (0x00MMSSFF)
; |*|
; |*| Exit: frame number
; |*|
; \*/
long redtolong(long redaddress)
{
long longval= 0;
union
{
struct {
char frame;
char sec;
char min;
char dead;
} rtl;
long l;
} d;
d.l= redaddress;
longval+= d.rtl.min;
longval*= 60;
longval+= d.rtl.sec;
longval*= 75;
longval+= d.rtl.frame;
return(longval);
}
; /*\
; |*| long longtored(long longval)
; |*|
; |*| convert frame number to redbook address
; |*|
; |*| Entry: frame value
; |*|
; |*| Exit: redbook address (0x00MMSSFF)
; |*|
; \*/
long longtored(long longval)
{
union
{
struct {
char frame;
char sec;
char min;
char dead;
} rtl;
long l;
} d;
d.rtl.min= longval/ 4500;
d.rtl.sec= (longval% 4500)/ 75;
d.rtl.frame= (longval% 4500)% 75;
return(d.l);
}
; /*\
; |*| long msftolong(long msfvalue)
; |*|
; |*| convert FFSSMM00 value to frame number
; |*|
; |*| Entry: msf value (0xFFSSMM00)
; |*|
; |*| Exit: frame number
; |*|
; \*/
long msftolong(long msfvalue)
{
long longval= 0;
union
{
struct {
char min;
char sec;
char frame;
char dead;
} mtl;
long l;
} d;
d.l= msfvalue;
longval+= d.mtl.min;
longval*= 60;
longval+= d.mtl.sec;
longval*= 75;
longval+= d.mtl.frame;
return(longval);
}
; /*\
; |*| inttobcd(int data)
; |*|
; |*| convert an integer to BCD representation
; |*|
; |*| Entry: integer
; |*|
; |*| Exit: value as BCD
; |*|
; \*/
inttobcd(int data)
{
int val;
val= (data/ 10)<< 4;
val+= (data% 10);
return(val);
}
; /*\
; |*| bcdtoint(int data)
; |*|
; |*| convert a BCD number to an integer
; |*|
; |*| Entry: BCD number
; |*|
; |*| Exit: integer value
; |*|
; \*/
bcdtoint(int data)
{
int val;
val= data& 0x0F;
val+= ((data&0xF0)>> 4)* 10;
return(val);
}
; /*\
; |*| fixmsf(int *min, int *sec, int *frame)
; |*|
; |*| boundarize elements of msf number
; |*|
; |*| Entry: int pointers to minutes, seconds and frame variables
; |*|
; |*| Exit: return -1 if minute ends up negative, 0 if not and
; |*| affect pointed to numbers
; |*|
; \*/
fixmsf(int *min, int *sec, int *frame)
{
int f= *frame;
int s= *sec;
int m= *min;
while (f >= 75)
{
f-= 75;
s+= 1;
}
while (s >= 60)
{
s-= 60;
m+= 1;
}
while (f < 0)
{
f+= 75;
s-= 1;
}
while (s < 0)
{
s+= 60;
m-= 1;
}
if (m < 0)
return(-1);
*frame= f;
*sec= s;
*min= m;
return(0);
}