extern void IsoAddTDToTOC(struct IsoFile *isofile, unsigned char track, struct tocTD toctd) { int temptrack; int position; #ifdef VERBOSE_FUNCTION_TOC PrintLog("CDVDiso TOC: IsoAddTNToTOC(%u)", track); #endif /* VERBOSE_FUNCTION_TOC */ if (isofile == NULL) return; temptrack = track; if (temptrack == 0xAA) temptrack = 0; if (temptrack > 99) return; // Only up to 99 tracks allowed. if (temptrack == 0) { LBAtoMSF(toctd.lsn, &isofile->toc[27]); isofile->toc[27] = HEXTOBCD(isofile->toc[27]); isofile->toc[28] = HEXTOBCD(isofile->toc[28]); isofile->toc[29] = HEXTOBCD(isofile->toc[29]); } else { position = temptrack * 10; position += 30; isofile->toc[position] = toctd.type; isofile->toc[position + 2] = HEXTOBCD(temptrack); LBAtoMSF(toctd.lsn, &isofile->toc[position + 7]); isofile->toc[position + 7] = HEXTOBCD(isofile->toc[position + 7]); isofile->toc[position + 8] = HEXTOBCD(isofile->toc[position + 8]); isofile->toc[position + 9] = HEXTOBCD(isofile->toc[position + 9]); } // ENDIF- Is this a lead-out? (or an actual track?) } // END IsoAddTDToTOC()
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ* subq) { char temptime[3]; int i; int pos; u32 tracklsn; #ifdef VERBOSE_FUNCTION_INTERFACE PrintLog("CDVDiso interface: CDVDreadSubQ()"); #endif /* VERBOSE_FUNCTION_INTERFACE */ if(isofile == NULL) return(-1); if(deviceopencount > 0) { deviceopencount--; if(deviceopencount > 0) return(-1); } // ENDIF- Still simulating device tray open? if((isofile->cdvdtype == CDVD_TYPE_PS2DVD) || (isofile->cdvdtype == CDVD_TYPE_DVDV)) { return(-1); // DVDs don't have SubQ data } // ENDIF- Trying to get a SubQ from a DVD? // fake it i = BCDTOHEX(isofile->toc[7]); pos = i * 10; pos += 30; temptime[0] = BCDTOHEX(isofile->toc[pos + 7]); temptime[1] = BCDTOHEX(isofile->toc[pos + 8]); temptime[2] = BCDTOHEX(isofile->toc[pos + 9]); tracklsn = MSFtoLBA(temptime); while((i < BCDTOHEX(isofile->toc[17])) && (tracklsn < lsn)) { i++; pos = i * 10; pos += 30; temptime[0] = BCDTOHEX(isofile->toc[pos + 7]); temptime[1] = BCDTOHEX(isofile->toc[pos + 8]); temptime[2] = BCDTOHEX(isofile->toc[pos + 9]); tracklsn = MSFtoLBA(temptime); } // ENDIF- Loop through tracks searching for lsn track i--; subq->ctrl = 4; subq->mode = 1; subq->trackNum = HEXTOBCD(i); subq->trackIndex = HEXTOBCD(i); LBAtoMSF(lsn - tracklsn, temptime); subq->trackM = HEXTOBCD(temptime[0]); subq->trackS = HEXTOBCD(temptime[1]); subq->trackF = HEXTOBCD(temptime[2]); subq->pad = 0; // lba_to_msf(lsn + (2*75), &min, &sec, &frm); LBAtoMSF(lsn, temptime); subq->discM = HEXTOBCD(temptime[0]); subq->discS = HEXTOBCD(temptime[1]); subq->discF = HEXTOBCD(temptime[2]); return(0); } // END CDVDreadSubQ()
s32 CDreadTrack(u32 lsn, int mode, u8 *buffer) { s32 s32result; #ifdef VERBOSE_FUNCTION PrintLog("CDVD driver: CDreadTrack(%i)", lsn); #endif /* VERBOSE_FUNCTION */ s32result = 0; if (buffer == NULL) return(-1); // The CD way of figuring out where to read. LBAtoMSF(lsn, buffer); switch (mode) { case CDVD_MODE_2048: case CDVD_MODE_2328: case CDVD_MODE_2340: case CDVD_MODE_2352: errno = 4; // Interrupted system call... (simulated the first time) while (errno == 4) { errno = 0; s32result = ioctl(devicehandle, CDROMREADRAW, buffer); } // ENDWHILE- Continually being interrupted by the system... break; case CDVD_MODE_2368: // Unimplemented... as yet. default: #ifdef VERBOSE_WARNINGS PrintLog("CDVD driver: Unknown Mode %i", mode); #endif /* VERBOSE_WARNINGS */ return(-1); // Illegal Read Mode? Abort break; } // ENDSWITCH- Which read mode should we choose? if ((s32result == -1) || (errno != 0)) { #ifdef VERBOSE_WARNINGS PrintLog("CDVD driver: Error reading CD: %i:%s", errno, strerror(errno)); #endif /* VERBOSE_WARNINGS */ InitCDSectorInfo(); return(-1); } // ENDIF- Trouble getting a track count? cdmode = mode; // Save mode for buffer positioning later. return(0); // Call accomplished } // END CDreadTrack()
extern void IsoInitTOC(struct IsoFile *isofile) { int i; off64_t sectorsize; if (isofile == NULL) return; #ifdef VERBOSE_FUNCTION_TOC PrintLog("CDVDiso TOC: IsoInitTOC()"); #endif /* VERBOSE_FUNCTION_TOC */ if (isofile->multi > 0) { sectorsize = isofile->multisectorend[isofile->multiend]; } else { sectorsize = isofile->filesectorsize; } // ENDIF- Establish largest sector from multifile? (or single file?) for (i = 0; i < 2048; i++) isofile->toc[i] = 0; switch (isofile->cdvdtype) { case CDVD_TYPE_DVDV: case CDVD_TYPE_PS2DVD: if ((isofile->filesectorsize > (2048*1024)) || (isofile->multi > 0)) { isofile->toc[0] = 0x24; // Dual-Sided DVD (?) isofile->toc[4] = 0x41; isofile->toc[5] = 0x95; } else { isofile->toc[0] = 0x04; // Single-Sided DVD (?) isofile->toc[4] = 0x86; isofile->toc[5] = 0x72; } // ENDIF- Too many sectors for a single-layered disc? isofile->toc[1] = 0x02; isofile->toc[2] = 0xF2; isofile->toc[3] = 0x00; isofile->toc[16] = 0x00; isofile->toc[17] = 0x03; isofile->toc[18] = 0x00; isofile->toc[19] = 0x00; return; // DVD's don't have tracks. Might track multisession later... break; case CDVD_TYPE_PS2CD: case CDVD_TYPE_PSCD: isofile->toc[0] = 0x41; break; case CDVD_TYPE_CDDA: isofile->toc[0] = 0x01; break; default: break; } // ENDSWITCH isofile->cdvdtype - Which TOC for which type? // CD Details here... (tracks and stuff) isofile->toc[2] = 0xA0; isofile->toc[7] = 0x01; // Starting Track No. isofile->toc[12] = 0xA1; isofile->toc[17] = 0x01; // Ending Track No. isofile->toc[22] = 0xA2; LBAtoMSF(sectorsize, &isofile->toc[27]); isofile->toc[27] = HEXTOBCD(isofile->toc[27]); isofile->toc[28] = HEXTOBCD(isofile->toc[28]); isofile->toc[29] = HEXTOBCD(isofile->toc[29]); isofile->toc[40] = 0x02; // YellowBook? Data Mode? isofile->toc[42] = 0x01; // Track No. LBAtoMSF(0, &isofile->toc[47]); isofile->toc[47] = HEXTOBCD(isofile->toc[47]); isofile->toc[48] = HEXTOBCD(isofile->toc[48]); isofile->toc[49] = HEXTOBCD(isofile->toc[49]); } // END IsoInitTOC()
s32 CALLBACK CDgetDiskType(s32 ioctldisktype) { s32 offset; s32 s32result; int i; u8 j; int tempdisctype; offset = 0; errno = 0; i = 0; j = 0; tempdisctype = CDVD_TYPE_UNKNOWN; #ifdef VERBOSE_FUNCTION PrintLog("CDVD driver: CDgetDiskType()"); #endif /* VERBOSE_FUNCTION */ s32result = CDreadTrack(16, CDVD_MODE_2352, cdtempbuffer); if ((s32result != 0) || (errno != 0)) return (-1); // ENDIF- Cannot read the CD's ISO9660 volume sector? Abort disctype = CDVD_TYPE_DETCTCD; switch (ioctldisktype) { case CDS_AUDIO: #ifdef VERBOSE_DISC_TYPE PrintLog("CDVD driver: Detected CDDA Audio disc."); #endif /* VERBOSE_DISC_TYPE */ tempdisctype = CDVD_TYPE_CDDA; tocbuffer[0] = 0x01; break; case CDS_DATA_1: case CDS_MIXED: #ifdef VERBOSE_DISC_TYPE PrintLog("CDVD driver: Detected CD disc."); #endif /* VERBOSE_DISC_TYPE */ tocbuffer[0] = 0x41; CDreadTrack(16, CDVD_MODE_2048, cdtempbuffer); offset = CDgetBufferOffset(); i = 0; while ((*(playstationcdname + i) != 0) && (*(playstationcdname + i) == cdtempbuffer[offset + 8 + i])) i++; if (*(playstationcdname + i) == 0) { i = 0; while ((*(ps1name + i) != 0) && (*(ps1name + i) == cdtempbuffer[offset + 1024 + i])) i++; if (*(ps1name + i) == 0) { #ifdef VERBOSE_DISC_TYPE PrintLog("CDVD driver: Detected Playstation CD disc."); #endif /* VERBOSE_DISC_TYPE */ tempdisctype = CDVD_TYPE_PSCD; } else { #ifdef VERBOSE_DISC_TYPE PrintLog("CDVD driver: Detected Playstation 2 CD disc."); #endif /* VERBOSE_DISC_TYPE */ tempdisctype = CDVD_TYPE_PS2CD; } // ENDIF- Did we find the CD ident? (For Playstation 1 CDs) } else tempdisctype = CDVD_TYPE_UNKNOWN; // ENDIF- Did we find the Playstation name? break; default: return (-1); } // ENDSWITCH- What has ioctl disc type come up with? // Collect TN data cdheader.cdth_trk0 = 0; cdheader.cdth_trk1 = 0; s32result = ioctl(devicehandle, CDROMREADTOCHDR, &cdheader); if ((s32result == -1) || (errno != 0)) { #ifdef VERBOSE_WARNINGS PrintLog("CDVD driver: Error reading TN: (%i) %i:%s", s32result, errno, strerror(errno)); #endif /* VERBOSE_WARNINGS */ cdheader.cdth_trk0 = 1; cdheader.cdth_trk1 = 1; } // ENDIF- Failed to read in track count? Assume 1 track. #ifdef VERBOSE_DISC_INFO PrintLog("CDVD driver: Track Number Range: %i-%i", cdheader.cdth_trk0, cdheader.cdth_trk1); #endif /* VERBOSE_DISC_INFO */ tocbuffer[2] = 0xA0; tocbuffer[7] = HEXTOBCD(cdheader.cdth_trk0); tocbuffer[12] = 0xA1; tocbuffer[17] = HEXTOBCD(cdheader.cdth_trk1); // Collect disc TD data cdtrack.cdte_track = CDROM_LEADOUT; cdtrack.cdte_format = CDROM_LBA; s32result = ioctl(devicehandle, CDROMREADTOCENTRY, &cdtrack); if ((s32result == -1) || (errno != 0)) { #ifdef VERBOSE_WARNINGS PrintLog("CDVD driver: Error reading TD for disc: (%i) %i:%s", s32result, errno, strerror(errno)); #endif /* VERBOSE_WARNINGS */ return (-1); } // ENDIF- Trouble getting a track count? LBAtoMSF(cdtrack.cdte_addr.lba, &tocbuffer[27]); #ifdef VERBOSE_DISC_INFO PrintLog("CDVD driver: Total Time: %i:%i", tocbuffer[27], tocbuffer[28]); #endif /* VERBOSE_DISC_INFO */ tocbuffer[27] = HEXTOBCD(tocbuffer[27]); tocbuffer[28] = HEXTOBCD(tocbuffer[28]); tocbuffer[29] = HEXTOBCD(tocbuffer[29]); // Collect track TD data for (j = cdheader.cdth_trk0; j <= cdheader.cdth_trk1; j++) { cdtrack.cdte_track = j; // j-1? cdtrack.cdte_format = CDROM_LBA; s32result = ioctl(devicehandle, CDROMREADTOCENTRY, &cdtrack); if ((s32result == -1) || (errno != 0)) { #ifdef VERBOSE_WARNINGS PrintLog("CDVD driver: Error reading TD for track %i: (%i) %i:%s", j, s32result, errno, strerror(errno)); #endif /* VERBOSE_WARNINGS */ // No more here... } else { LBAtoMSF(cdtrack.cdte_addr.lba, &tocbuffer[j * 10 + 37]); #ifdef VERBOSE_DISC_INFO PrintLog("CDVD driver: Track %i: Data Mode %i Disc Start Time:%i:%i.%i\n", j, cdtrack.cdte_datamode, tocbuffer[j * 10 + 37], tocbuffer[j * 10 + 38], tocbuffer[j * 10 + 39]); #endif /* VERBOSE_DISC_INFO */ tocbuffer[j * 10 + 30] = cdtrack.cdte_datamode; tocbuffer[j * 10 + 32] = HEXTOBCD(j); tocbuffer[j * 10 + 37] = HEXTOBCD(tocbuffer[j * 10 + 37]); tocbuffer[j * 10 + 38] = HEXTOBCD(tocbuffer[j * 10 + 38]); tocbuffer[j * 10 + 39] = HEXTOBCD(tocbuffer[j * 10 + 39]); } // ENDIF- Trouble getting a track count? } // NEXT j- Reading each track's info in turn errno = 0; disctype = tempdisctype; // Trigger the fact we have the info (finally) return (disctype); } // END CDVDgetDiskType()