Search
lxdream.org :: lxdream :: r782:1af8b5ce627c
lxdream 0.9.1
released Jun 29
Download Now
changeset782:1af8b5ce627c
parent781:88d48559380a
child783:ef81aa93524f
authornkeynes
dateTue Jul 29 06:35:28 2008 +0000 (15 years ago)
Workaround OS X's inability to handle CD reads of unknown size (ie where the read
request failed to specify an expected sector type) - read raw sectors and parse it
out by hand.
src/drivers/cd_osx.c
src/gdrom/gddriver.h
src/gdrom/gdimage.c
src/gdrom/gdrom.h
1.1 --- a/src/drivers/cd_osx.c Mon Jul 28 11:21:12 2008 +0000
1.2 +++ b/src/drivers/cd_osx.c Tue Jul 29 06:35:28 2008 +0000
1.3 @@ -153,52 +153,78 @@
1.4 return 0;
1.5 }
1.6
1.7 -static gdrom_error_t cdrom_osx_read_sector( gdrom_disc_t disc, uint32_t sector,
1.8 +static gdrom_error_t cdrom_osx_read_sector( gdrom_disc_t disc, uint32_t lba,
1.9 int mode, unsigned char *buf, uint32_t *length )
1.10 {
1.11 + gdrom_image_t image = (gdrom_image_t)disc;
1.12 + int real_lba = lba - 150;
1.13 + int sector_size;
1.14 + int direct_read = 1;
1.15 + char data[MAX_SECTOR_SIZE];
1.16 osx_cdrom_drive_t drive = OSX_DRIVE(disc);
1.17 +
1.18 int fh = osx_cdrom_get_media_handle(drive);
1.19 if( fh == -1 ) {
1.20 return PKT_ERR_NODISC;
1.21 } else {
1.22 dk_cd_read_t readcd;
1.23 + memset( &readcd, 0, sizeof(readcd) );
1.24 + readcd.buffer = buf;
1.25
1.26 - memset( &readcd, 0, sizeof(readcd) );
1.27 // This is complicated by needing to know the exact read size. Gah.
1.28 if( READ_CD_RAW(mode) ) {
1.29 - *length = 2352;
1.30 + sector_size = 2352;
1.31 readcd.sectorArea = 0xF8;
1.32 + } else if ( READ_CD_MODE(mode) == READ_CD_MODE_ANY ) {
1.33 + /* Sector could be anything - need to do a raw read and then parse
1.34 + * the requested data out ourselves
1.35 + */
1.36 + int track_no = gdrom_image_get_track_by_lba( image, lba );
1.37 + struct gdrom_track *track = &image->track[track_no-1];
1.38 +
1.39 + sector_size = 2352;
1.40 + if( track->mode == GDROM_CDDA ) {
1.41 + readcd.sectorArea = kCDSectorAreaUser;
1.42 + } else {
1.43 + readcd.sectorArea = 0xF8;
1.44 + readcd.buffer = data;
1.45 + direct_read = 0;
1.46 + }
1.47 } else {
1.48 // This is incomplete...
1.49 if( READ_CD_DATA(mode) ) {
1.50 readcd.sectorArea = kCDSectorAreaUser;
1.51 switch( READ_CD_MODE(mode) ) {
1.52 case READ_CD_MODE_CDDA:
1.53 - *length = 2352;
1.54 + sector_size = 2352;
1.55 break;
1.56 case READ_CD_MODE_1:
1.57 case READ_CD_MODE_2_FORM_1:
1.58 - *length = 2048;
1.59 + sector_size = 2048;
1.60 break;
1.61 case READ_CD_MODE_2:
1.62 - *length = 2336;
1.63 + sector_size = 2336;
1.64 break;
1.65 case READ_CD_MODE_2_FORM_2:
1.66 - *length = 2324;
1.67 + sector_size = 2324;
1.68 break;
1.69 }
1.70 }
1.71 }
1.72
1.73 - readcd.offset = *length * (sector - 150);
1.74 + readcd.offset = sector_size * real_lba;
1.75 readcd.sectorType = READ_CD_MODE(mode)>>1;
1.76 - readcd.bufferLength = *length;
1.77 - readcd.buffer = buf;
1.78 + readcd.bufferLength = sector_size;
1.79 if( ioctl( fh, DKIOCCDREAD, &readcd ) == -1 ) {
1.80 return -1;
1.81 + }
1.82 +
1.83 + if( direct_read ) {
1.84 + *length = sector_size;
1.85 } else {
1.86 - return 0;
1.87 + gdrom_extract_raw_data_sector( data, mode, buf, length );
1.88 }
1.89 + return 0;
1.90 }
1.91 }
1.92
2.1 --- a/src/gdrom/gddriver.h Mon Jul 28 11:21:12 2008 +0000
2.2 +++ b/src/gdrom/gddriver.h Tue Jul 29 06:35:28 2008 +0000
2.3 @@ -203,6 +203,10 @@
2.4 */
2.5 void gdrom_image_destroy_no_close( gdrom_disc_t d );
2.6
2.7 +/**
2.8 + * Determine the track number containing the specified sector by lba.
2.9 + */
2.10 +int gdrom_image_get_track_by_lba( gdrom_image_t image, uint32_t lba );
2.11
2.12 /**
2.13 * Given a base filename (eg for a .cue file), generate the path for the given
2.14 @@ -218,6 +222,13 @@
2.15 /************* Host-native support functions ***************/
2.16
2.17 /**
2.18 + * Given a raw (2352 byte) data sector, extract the requested components into the
2.19 + * target buffer. length will also be updated with the length of the copied
2.20 + * data
2.21 + */
2.22 +void gdrom_extract_raw_data_sector( char *sector_data, int mode, unsigned char *buf, uint32_t *length );
2.23 +
2.24 +/**
2.25 * Parse a format 2 TOC, and write the results into the supplied disc structure.
2.26 */
2.27 void mmc_parse_toc2( gdrom_image_t disc, unsigned char *buf );
3.1 --- a/src/gdrom/gdimage.c Mon Jul 28 11:21:12 2008 +0000
3.2 +++ b/src/gdrom/gdimage.c Tue Jul 29 06:35:28 2008 +0000
3.3 @@ -131,7 +131,7 @@
3.4 free( disc );
3.5 }
3.6
3.7 -static int gdrom_image_get_track_by_lba( gdrom_image_t image, uint32_t lba )
3.8 +int gdrom_image_get_track_by_lba( gdrom_image_t image, uint32_t lba )
3.9 {
3.10 int i;
3.11 for( i=0; i<image->track_count; i++ ) {
3.12 @@ -228,6 +228,22 @@
3.13 }
3.14 }
3.15
3.16 +void gdrom_extract_raw_data_sector( char *sector_data, int channels, unsigned char *buf, uint32_t *length )
3.17 +{
3.18 + int sector_mode;
3.19 + int start, size;
3.20 + struct cdrom_sector_header *secthead = (struct cdrom_sector_header *)sector_data;
3.21 + if( secthead->mode == 1 ) {
3.22 + sector_mode = GDROM_MODE1;
3.23 + } else {
3.24 + sector_mode = ((secthead->subhead[2] & 0x20) == 0 ) ? GDROM_MODE2_FORM1 : GDROM_MODE2_FORM2;
3.25 + }
3.26 + gdrom_get_read_bounds( sector_mode, channels, &start, &size );
3.27 +
3.28 + memcpy( buf, sector_data+start, size );
3.29 + *length = size;
3.30 +}
3.31 +
3.32 /**
3.33 * Read a single sector from a disc image. If you thought this would be simple,
3.34 * I have just one thing to say to you: Bwahahahahahahahah.
4.1 --- a/src/gdrom/gdrom.h Mon Jul 28 11:21:12 2008 +0000
4.2 +++ b/src/gdrom/gdrom.h Tue Jul 29 06:35:28 2008 +0000
4.3 @@ -90,9 +90,6 @@
4.4 */
4.5 gdrom_error_t gdrom_get_info( unsigned char *buf, int session );
4.6
4.7 -uint8_t gdrom_get_track_no_by_lba( uint32_t lba );
4.8 -
4.9 -
4.10 /**
4.11 * Native CD-ROM API - provided by drivers/cd_*.c
4.12 *
.