trunk/src/lib/util/cdrom.c
| r22882 | r22883 | |
| 136 | 136 | |
| 137 | 137 | /* loop until our current LBA is less than the start LBA of the next track */ |
| 138 | 138 | for (track = 0; track < file->cdtoc.numtrks; track++) |
| 139 | { |
| 139 | 140 | if (loglba < file->cdtoc.tracks[track + 1].logframeofs) |
| 140 | 141 | { |
| 142 | // is this a no-pregap-data track? compensate for the logical offset pointing to the "wrong" sector. |
| 143 | if ((file->cdtoc.tracks[track].pgdatasize == 0) && (loglba > file->cdtoc.tracks[track].pregap)) |
| 144 | { |
| 145 | loglba -= file->cdtoc.tracks[track].pregap; |
| 146 | } |
| 147 | |
| 141 | 148 | // convert to physical and proceed |
| 142 | 149 | physlba = file->cdtoc.tracks[track].physframeofs + (loglba - file->cdtoc.tracks[track].logframeofs); |
| 143 | 150 | chdlba = physlba - file->cdtoc.tracks[track].physframeofs + file->cdtoc.tracks[track].chdframeofs; |
| 144 | 151 | tracknum = track; |
| 145 | 152 | return chdlba; |
| 146 | 153 | } |
| 154 | } |
| 147 | 155 | |
| 148 | 156 | return loglba; |
| 149 | 157 | } |
| r22882 | r22883 | |
| 196 | 204 | { |
| 197 | 205 | file->cdtoc.tracks[i].physframeofs = physofs; |
| 198 | 206 | file->cdtoc.tracks[i].chdframeofs = 0; |
| 199 | | |
| 200 | | // pregap counts against this track |
| 201 | | logofs += file->cdtoc.tracks[i].pregap; |
| 202 | 207 | file->cdtoc.tracks[i].logframeofs = logofs; |
| 203 | 208 | |
| 204 | | // postgap counts against the next track |
| 209 | // if the pregap sectors aren't in the track, add them to the track's logical length |
| 210 | if (file->cdtoc.tracks[i].pgdatasize == 0) |
| 211 | { |
| 212 | logofs += file->cdtoc.tracks[i].pregap; |
| 213 | } |
| 214 | |
| 215 | // postgap adds to the track length |
| 205 | 216 | logofs += file->cdtoc.tracks[i].postgap; |
| 206 | 217 | |
| 207 | 218 | physofs += file->cdtoc.tracks[i].frames; |
| 208 | 219 | logofs += file->cdtoc.tracks[i].frames; |
| 209 | 220 | |
| 210 | | LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d postgap %d logofs %d physofs %d chdofs %d\n", i+1, |
| 221 | /* printf("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d pgmode %d presize %d postgap %d logofs %d physofs %d chdofs %d\n", i+1, |
| 211 | 222 | file->cdtoc.tracks[i].trktype, |
| 212 | 223 | file->cdtoc.tracks[i].subtype, |
| 213 | 224 | file->cdtoc.tracks[i].datasize, |
| 214 | 225 | file->cdtoc.tracks[i].subsize, |
| 215 | 226 | file->cdtoc.tracks[i].frames, |
| 216 | 227 | file->cdtoc.tracks[i].extraframes, |
| 217 | | file->cdtoc.tracks[i].pregap, |
| 228 | file->cdtoc.tracks[i].pregap, |
| 229 | file->cdtoc.tracks[i].pgtype, |
| 230 | file->cdtoc.tracks[i].pgdatasize, |
| 218 | 231 | file->cdtoc.tracks[i].postgap, |
| 219 | 232 | file->cdtoc.tracks[i].logframeofs, |
| 220 | 233 | file->cdtoc.tracks[i].physframeofs, |
| 221 | | file->cdtoc.tracks[i].chdframeofs)); |
| 234 | file->cdtoc.tracks[i].chdframeofs);*/ |
| 222 | 235 | } |
| 223 | 236 | |
| 224 | 237 | /* fill out dummy entries for the last track to help our search */ |
| r22882 | r22883 | |
| 277 | 290 | { |
| 278 | 291 | file->cdtoc.tracks[i].physframeofs = physofs; |
| 279 | 292 | file->cdtoc.tracks[i].chdframeofs = chdofs; |
| 280 | | |
| 281 | | // pregap counts against this track |
| 282 | | logofs += file->cdtoc.tracks[i].pregap; |
| 283 | 293 | file->cdtoc.tracks[i].logframeofs = logofs; |
| 284 | 294 | |
| 295 | // if the pregap sectors aren't in the track, add them to the track's logical length |
| 296 | if (file->cdtoc.tracks[i].pgdatasize == 0) |
| 297 | { |
| 298 | logofs += file->cdtoc.tracks[i].pregap; |
| 299 | } |
| 300 | |
| 285 | 301 | // postgap counts against the next track |
| 286 | 302 | logofs += file->cdtoc.tracks[i].postgap; |
| 287 | 303 | |
| r22882 | r22883 | |
| 290 | 306 | chdofs += file->cdtoc.tracks[i].extraframes; |
| 291 | 307 | logofs += file->cdtoc.tracks[i].frames; |
| 292 | 308 | |
| 293 | | LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d postgap %d logofs %d physofs %d chdofs %d\n", i+1, |
| 309 | /* printf("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d pregap %d pgmode %d presize %d postgap %d logofs %d physofs %d chdofs %d\n", i+1, |
| 294 | 310 | file->cdtoc.tracks[i].trktype, |
| 295 | 311 | file->cdtoc.tracks[i].subtype, |
| 296 | 312 | file->cdtoc.tracks[i].datasize, |
| 297 | 313 | file->cdtoc.tracks[i].subsize, |
| 298 | 314 | file->cdtoc.tracks[i].frames, |
| 299 | 315 | file->cdtoc.tracks[i].extraframes, |
| 300 | | file->cdtoc.tracks[i].pregap, |
| 316 | file->cdtoc.tracks[i].pregap, |
| 317 | file->cdtoc.tracks[i].pgtype, |
| 318 | file->cdtoc.tracks[i].pgdatasize, |
| 301 | 319 | file->cdtoc.tracks[i].postgap, |
| 302 | 320 | file->cdtoc.tracks[i].logframeofs, |
| 303 | 321 | file->cdtoc.tracks[i].physframeofs, |
| 304 | | file->cdtoc.tracks[i].chdframeofs)); |
| 322 | file->cdtoc.tracks[i].chdframeofs);*/ |
| 305 | 323 | } |
| 306 | 324 | |
| 307 | 325 | /* fill out dummy entries for the last track to help our search */ |
| r22882 | r22883 | |
| 339 | 357 | CORE READ ACCESS |
| 340 | 358 | ***************************************************************************/ |
| 341 | 359 | |
| 342 | | chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 chdsector, UINT32 tracknum, UINT32 startoffs, UINT32 length) |
| 360 | chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UINT32 chdsector, UINT32 tracknum, UINT32 startoffs, UINT32 length) |
| 343 | 361 | { |
| 362 | // if this is pregap info that isn't actually in the file, just return blank data |
| 363 | if ((file->cdtoc.tracks[tracknum].pgdatasize == 0) && (lbasector < (file->cdtoc.tracks[tracknum].logframeofs + file->cdtoc.tracks[tracknum].pregap))) |
| 364 | { |
| 365 | // printf("PG missing sector: LBA %d, trklog %d\n", lbasector, file->cdtoc.tracks[tracknum].logframeofs); |
| 366 | memset(dest, 0, length); |
| 367 | return CHDERR_NONE; |
| 368 | } |
| 369 | |
| 344 | 370 | // if a CHD, just read |
| 345 | 371 | if (file->chd != NULL) |
| 346 | 372 | return file->chd->read_bytes(UINT64(chdsector) * UINT64(CD_FRAME_SIZE) + startoffs, dest, length); |
| r22882 | r22883 | |
| 353 | 379 | |
| 354 | 380 | sourcefileoffset += chdsector * bytespersector + startoffs; |
| 355 | 381 | |
| 382 | // printf("Reading sector %d from track %d at offset %lld\n", chdsector, tracknum, sourcefileoffset); |
| 383 | |
| 356 | 384 | core_fseek(srcfile, sourcefileoffset, SEEK_SET); |
| 357 | 385 | core_fread(srcfile, dest, length); |
| 358 | 386 | |
| r22882 | r22883 | |
| 398 | 426 | |
| 399 | 427 | if ((datatype == tracktype) || (datatype == CD_TRACK_RAW_DONTCARE)) |
| 400 | 428 | { |
| 401 | | return (read_partial_sector(file, buffer, chdsector, tracknum, 0, file->cdtoc.tracks[tracknum].datasize) == CHDERR_NONE); |
| 429 | return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 0, file->cdtoc.tracks[tracknum].datasize) == CHDERR_NONE); |
| 402 | 430 | } |
| 403 | 431 | else |
| 404 | 432 | { |
| 405 | 433 | /* return 2048 bytes of mode 1 data from a 2352 byte mode 1 raw sector */ |
| 406 | 434 | if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE1_RAW)) |
| 407 | 435 | { |
| 408 | | return (read_partial_sector(file, buffer, chdsector, tracknum, 16, 2048) == CHDERR_NONE); |
| 436 | return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2048) == CHDERR_NONE); |
| 409 | 437 | } |
| 410 | 438 | |
| 411 | 439 | /* return 2352 byte mode 1 raw sector from 2048 bytes of mode 1 data */ |
| r22882 | r22883 | |
| 421 | 449 | bufptr[14] = msf&0xff; |
| 422 | 450 | bufptr[15] = 1; // mode 1 |
| 423 | 451 | LOG(("CDROM: promotion of mode1/form1 sector to mode1 raw is not complete!\n")); |
| 424 | | return (read_partial_sector(file, bufptr+16, chdsector, tracknum, 0, 2048) == CHDERR_NONE); |
| 452 | return (read_partial_sector(file, bufptr+16, lbasector, chdsector, tracknum, 0, 2048) == CHDERR_NONE); |
| 425 | 453 | } |
| 426 | 454 | |
| 427 | 455 | /* return 2048 bytes of mode 1 data from a mode2 form1 or raw sector */ |
| 428 | 456 | if ((datatype == CD_TRACK_MODE1) && ((tracktype == CD_TRACK_MODE2_FORM1)||(tracktype == CD_TRACK_MODE2_RAW))) |
| 429 | 457 | { |
| 430 | | return (read_partial_sector(file, buffer, chdsector, tracknum, 24, 2048) == CHDERR_NONE); |
| 458 | return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 24, 2048) == CHDERR_NONE); |
| 431 | 459 | } |
| 432 | 460 | |
| 433 | 461 | /* return mode 2 2336 byte data from a 2352 byte mode 1 or 2 raw sector (skip the header) */ |
| 434 | 462 | if ((datatype == CD_TRACK_MODE2) && ((tracktype == CD_TRACK_MODE1_RAW) || (tracktype == CD_TRACK_MODE2_RAW))) |
| 435 | 463 | { |
| 436 | | return (read_partial_sector(file, buffer, chdsector, tracknum, 16, 2336) == CHDERR_NONE); |
| 464 | return (read_partial_sector(file, buffer, lbasector, chdsector, tracknum, 16, 2336) == CHDERR_NONE); |
| 437 | 465 | } |
| 438 | 466 | |
| 439 | 467 | LOG(("CDROM: Conversion from type %d to type %d not supported!\n", tracktype, datatype)); |
| r22882 | r22883 | |
| 469 | 497 | return 1; |
| 470 | 498 | |
| 471 | 499 | // read the data |
| 472 | | chd_error err = read_partial_sector(file, buffer, chdsector, tracknum, file->cdtoc.tracks[tracknum].datasize, file->cdtoc.tracks[tracknum].subsize); |
| 500 | chd_error err = read_partial_sector(file, buffer, lbasector, chdsector, tracknum, file->cdtoc.tracks[tracknum].datasize, file->cdtoc.tracks[tracknum].subsize); |
| 473 | 501 | return (err == CHDERR_NONE); |
| 474 | 502 | } |
| 475 | 503 | |
| r22882 | r22883 | |
| 493 | 521 | |
| 494 | 522 | /* convert to a CHD sector offset and get track information */ |
| 495 | 523 | logical_to_chd_lba(file, frame, track); |
| 524 | |
| 496 | 525 | return track; |
| 497 | 526 | } |
| 498 | 527 | |
| r22882 | r22883 | |
| 883 | 912 | track->pgsub = CD_SUB_NONE; |
| 884 | 913 | track->pgdatasize = 0; |
| 885 | 914 | track->pgsubsize = 0; |
| 886 | | cdrom_convert_type_string_to_pregap_info(pgtype, track); |
| 887 | | cdrom_convert_subtype_string_to_pregap_info(pgsub, track); |
| 915 | if (track->pregap > 0) |
| 916 | { |
| 917 | if (pgtype[0] == 'V') |
| 918 | { |
| 919 | cdrom_convert_type_string_to_pregap_info(&pgtype[1], track); |
| 920 | } |
| 888 | 921 | |
| 922 | cdrom_convert_subtype_string_to_pregap_info(pgsub, track); |
| 923 | } |
| 924 | |
| 889 | 925 | /* set the postgap info */ |
| 890 | 926 | track->postgap = postgap; |
| 891 | 927 | } |
| r22882 | r22883 | |
| 957 | 993 | astring metadata; |
| 958 | 994 | if (!(toc->flags & CD_FLAG_GDROM)) |
| 959 | 995 | { |
| 996 | char submode[32]; |
| 997 | |
| 998 | if (toc->tracks[i].pgdatasize > 0) |
| 999 | { |
| 1000 | strcpy(&submode[1], cdrom_get_type_string(toc->tracks[i].pgtype)); |
| 1001 | submode[0] = 'V'; // indicate valid submode |
| 1002 | } |
| 1003 | else |
| 1004 | { |
| 1005 | strcpy(submode, cdrom_get_type_string(toc->tracks[i].pgtype)); |
| 1006 | } |
| 1007 | |
| 960 | 1008 | metadata.format(CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), |
| 961 | 1009 | cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].pregap, |
| 962 | | cdrom_get_type_string(toc->tracks[i].pgtype), cdrom_get_subtype_string(toc->tracks[i].pgsub), |
| 1010 | submode, cdrom_get_subtype_string(toc->tracks[i].pgsub), |
| 963 | 1011 | toc->tracks[i].postgap); |
| 964 | | |
| 965 | 1012 | err = chd->write_metadata(CDROM_TRACK_METADATA2_TAG, i, metadata); |
| 966 | 1013 | } |
| 967 | 1014 | else |
| r22882 | r22883 | |
| 1275 | 1322 | memset(§or[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES); |
| 1276 | 1323 | memset(§or[ECC_Q_OFFSET], 0, 2 * ECC_Q_NUM_BYTES); |
| 1277 | 1324 | } |
| 1325 | |