14a6 /* DIGIGRAB grabs CD Audio data digitally to a file */ #include #include #include #include #include #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); } . 0