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 | |