/* DIGIGRAB grabs CD Audio data digitally to a file */
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <alloc.h>
#define MULTIPLEX_INT 0x2f
#define INIT_MP_INT 0x1500
#define CDREQ_MP_INT 0x1510
#define STAT_HAS_AN_ERROR 0x8000
#define STAT_BUSY 0x0200
#define STAT_DONE 0x0100
int CDRomLoaded,CDRomDrive;
#define CD_READ_LONG 128
#define READ_IOCTL_COMMAND 3
#define WRITE_IOCTL_COMMAND 12
#define CD_STATUS_COMMAND 6
#define GET_AUDIO_DISKINFO 10
#define GET_AUDIO_TRACKINFO 11
#define ADDR_HSG 0
#define ADDR_RED 1
#define COOKED 0
#define RAW 1
#define FALSE 0
#define TRUE 1
static int StatusWord;
typedef struct {
unsigned char ParamLength;
unsigned char SubUnit;
unsigned char CommandCode;
unsigned int Status;
unsigned long Reserved1;
unsigned long Reserved2;
unsigned char AddressMode;
unsigned long Transfaddr;
unsigned int Numsec;
unsigned long Startsec;
unsigned char Readmode;
unsigned char Interlsiz;
unsigned char Interlskip;
} ReadLongStru;
typedef struct {
unsigned char ParamLength;
unsigned char SubUnit;
unsigned char CommandCode;
unsigned int Status;
unsigned long Reserved1;
unsigned long Reserved2;
unsigned char Meddescr;
unsigned long Transfaddr;
unsigned int Numbytes;
unsigned int Startsec;
unsigned long volID;
} IOCTLStru;
typedef struct {
unsigned char CntrlCode;
unsigned char LowTrack;
unsigned char HighTrack;
unsigned long StartLeadout;
} DiskInfoStruc;
typedef struct {
unsigned char CntrlCode;
unsigned char Tracknum;
unsigned long Startpoint;
unsigned char TrackCtrlInfo;
} TrackInfoStruc;
ReadLongStru ReadLongBlock;
IOCTLStru IOCTLBlock;
DiskInfoStruc DiskInfoBlock;
TrackInfoStruc TrackInfoBlock[100];
unsigned long Red2HSG(unsigned long RedValue);
long LastSector;
int NumTracks;
int *buffer;
main(int argc, char *argv[])
{
unsigned long ssec,esec;
unsigned int nsec,secstograb,i,j,offs;
unsigned char filename[80];
FILE *outfp;
int Track,StartMin,StartSec,EndMin,EndSec,StartFrame,EndFrame;
float TempFloat;
char LocalBuffer[132];
char c = ':';
unsigned char skip;
if (!CheckCD2F()){
printf("MSCDEX NOT LOADED\n");
exit(1);
}
GetDiskInfo();
for(i = DiskInfoBlock.LowTrack; i <= DiskInfoBlock.HighTrack; i++)
GetTrackInfo(i);
ssec = atol(argv[1]);
buffer = calloc(5000,1);
outfp = fopen("1sect.raw","wb");
ReadLong(ssec,1);
while(ReadLongBlock.Status & STAT_HAS_AN_ERROR)
ReadLong(ssec,1);
fwrite(&buffer[i],2,1176,outfp);
fclose(outfp);
free(buffer);
}
CheckCD2F()
{
union REGS regs;
regs.x.ax = INIT_MP_INT;
int86(MULTIPLEX_INT,®s,®s);
CDRomLoaded = regs.x.bx;
CDRomDrive = regs.x.cx;
}
GetDiskInfo()
{
union REGS regs;
struct SREGS sregs;
DiskInfoBlock.CntrlCode = GET_AUDIO_DISKINFO;
IOCTLBlock.ParamLength = 13;
IOCTLBlock.SubUnit = 0;
IOCTLBlock.CommandCode = READ_IOCTL_COMMAND;
IOCTLBlock.Status = 0;
IOCTLBlock.Meddescr = 0;
IOCTLBlock.Transfaddr = (unsigned long)&DiskInfoBlock;
IOCTLBlock.Numbytes = 7;
IOCTLBlock.Startsec = 0;
IOCTLBlock.volID = 0;
regs.x.ax = CDREQ_MP_INT;
regs.x.bx = FP_OFF(&IOCTLBlock);
regs.x.cx = CDRomDrive;
sregs.es = FP_SEG(&IOCTLBlock);
int86x(MULTIPLEX_INT,®s,®s,&sregs);
return(IOCTLBlock.Status);
}
GetTrackInfo(unsigned char trk)
{
union REGS regs;
struct SREGS sregs;
TrackInfoBlock[trk].CntrlCode = GET_AUDIO_TRACKINFO;
TrackInfoBlock[trk].Tracknum = trk;
IOCTLBlock.ParamLength = 13;
IOCTLBlock.SubUnit = 0;
IOCTLBlock.CommandCode = READ_IOCTL_COMMAND;
IOCTLBlock.Status = 0;
IOCTLBlock.Meddescr = 0;
IOCTLBlock.Transfaddr = (unsigned long)&(TrackInfoBlock[trk]);
IOCTLBlock.Numbytes = 7;
IOCTLBlock.Startsec = 0;
IOCTLBlock.volID = 0;
regs.x.ax = CDREQ_MP_INT;
regs.x.bx = FP_OFF(&IOCTLBlock);
regs.x.cx = CDRomDrive;
sregs.es = FP_SEG(&IOCTLBlock);
int86x(MULTIPLEX_INT,®s,®s,&sregs);
return(IOCTLBlock.Status);
}
ReadLong(unsigned long SSec,unsigned int numsecs)
{
union REGS regs;
struct SREGS sregs;
ReadLongBlock.ParamLength = 13;
ReadLongBlock.SubUnit = 0;
ReadLongBlock.CommandCode = CD_READ_LONG;
ReadLongBlock.Status = 0;
ReadLongBlock.AddressMode = ADDR_HSG;
ReadLongBlock.Transfaddr = (int far*) buffer;
ReadLongBlock.Numsec = numsecs;
ReadLongBlock.Startsec = SSec;
ReadLongBlock.Readmode = RAW;
ReadLongBlock.Interlsiz = 0;
ReadLongBlock.Interlskip = 0;
regs.x.ax = CDREQ_MP_INT;
regs.x.bx = FP_OFF(&ReadLongBlock);
regs.x.cx = CDRomDrive;
sregs.es = FP_SEG(&ReadLongBlock);
int86x(MULTIPLEX_INT,®s,®s,&sregs);
return(ReadLongBlock.Status);
}
unsigned long Red2HSG(unsigned long RedValue)
{
unsigned long Mins;
unsigned long Secs;
unsigned long PlusFrames;
PlusFrames = RedValue & 0x000000ffL;
Secs = ((RedValue & 0x0000ff00L) >> 8);
Mins = ((RedValue & 0x00ff0000L) >> 16);
return((Mins*60+Secs)*75+PlusFrames);
}