home *** CD-ROM | disk | FTP | other *** search
- ; /*\
- ; |*| 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);
- }
-
-
-