Previous 199869 Revisions Next

r22883 Saturday 18th May, 2013 at 02:02:27 UTC by R. Belmont
Various CD-ROM / CHDMAN improvements: [R. Belmont]
- Correct import/export of bin/cue images in which the pregap sectors are present.
- Normalized TOC handling; the start of a track is always the first pregap sector.
- Finally allows reading and CDDA playing pregap sectors.  Works even if the pregap sectors are not present in the file.

nw part: Existing CHDs should work (or not) as before - previously non-working ones that were broken due to disc geometry should work if regenerated from source.

I tested this on several known-touchy cases (including Saturn Black/Matrix Reprint cinemas and PCE-CD Prince of Persia) but there are likely others.

Drivers that tried to fake around the previous lack of pregap reading on CDDA may need some adjustment.
[src/lib/util]cdrom.c cdrom.h chdcd.c
[src/mess/machine]pce.c
[src/tools]chdman.c

trunk/src/tools/chdman.c
r22882r22883
12491249      // output TRACK entry
12501250      core_fprintf(file, "  TRACK %02d %s\n", tracknum + 1, tempstr.cstr());
12511251
1252      // output PREGAP
1253      if (info.pregap > 0)
1252      // output PREGAP tag if pregap sectors are not in the file
1253      if ((info.pregap > 0) && (info.pgdatasize == 0))
1254      {
12541255         core_fprintf(file, "    PREGAP %s\n", msf_string_from_frames(tempstr, info.pregap));
1256         core_fprintf(file, "    INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs));
1257      }
1258      else if ((info.pregap > 0) && (info.pgdatasize > 0))
1259      {
1260         core_fprintf(file, "    INDEX 00 %s\n", msf_string_from_frames(tempstr, frameoffs));
1261         core_fprintf(file, "    INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs+info.pregap));
1262      }
12551263
1256      // output track data
1257      core_fprintf(file, "    INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs));
1264      // if no pregap at all, output index 01 only
1265      if (info.pregap == 0)
1266      {
1267         core_fprintf(file, "    INDEX 01 %s\n", msf_string_from_frames(tempstr, frameoffs));
1268      }
12581269
12591270      // output POSTGAP
12601271      if (info.postgap > 0)
trunk/src/lib/util/cdrom.c
r22882r22883
136136
137137   /* loop until our current LBA is less than the start LBA of the next track */
138138   for (track = 0; track < file->cdtoc.numtrks; track++)
139   {
139140      if (loglba < file->cdtoc.tracks[track + 1].logframeofs)
140141      {
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
141148         // convert to physical and proceed
142149         physlba = file->cdtoc.tracks[track].physframeofs + (loglba - file->cdtoc.tracks[track].logframeofs);
143150         chdlba = physlba - file->cdtoc.tracks[track].physframeofs + file->cdtoc.tracks[track].chdframeofs;
144151         tracknum = track;
145152         return chdlba;
146153      }
154   }
147155
148156   return loglba;
149157}
r22882r22883
196204   {
197205      file->cdtoc.tracks[i].physframeofs = physofs;
198206      file->cdtoc.tracks[i].chdframeofs = 0;
199
200      // pregap counts against this track
201      logofs += file->cdtoc.tracks[i].pregap;
202207      file->cdtoc.tracks[i].logframeofs = logofs;
203208
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
205216      logofs += file->cdtoc.tracks[i].postgap;
206217
207218      physofs += file->cdtoc.tracks[i].frames;
208219      logofs  += file->cdtoc.tracks[i].frames;
209220
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,
211222         file->cdtoc.tracks[i].trktype,
212223         file->cdtoc.tracks[i].subtype,
213224         file->cdtoc.tracks[i].datasize,
214225         file->cdtoc.tracks[i].subsize,
215226         file->cdtoc.tracks[i].frames,
216227         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,
218231         file->cdtoc.tracks[i].postgap,
219232         file->cdtoc.tracks[i].logframeofs,
220233         file->cdtoc.tracks[i].physframeofs,
221         file->cdtoc.tracks[i].chdframeofs));
234         file->cdtoc.tracks[i].chdframeofs);*/
222235   }
223236
224237   /* fill out dummy entries for the last track to help our search */
r22882r22883
277290   {
278291      file->cdtoc.tracks[i].physframeofs = physofs;
279292      file->cdtoc.tracks[i].chdframeofs = chdofs;
280
281      // pregap counts against this track
282      logofs += file->cdtoc.tracks[i].pregap;
283293      file->cdtoc.tracks[i].logframeofs = logofs;
284294
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
285301      // postgap counts against the next track
286302      logofs += file->cdtoc.tracks[i].postgap;
287303
r22882r22883
290306      chdofs  += file->cdtoc.tracks[i].extraframes;
291307      logofs  += file->cdtoc.tracks[i].frames;
292308
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,
294310         file->cdtoc.tracks[i].trktype,
295311         file->cdtoc.tracks[i].subtype,
296312         file->cdtoc.tracks[i].datasize,
297313         file->cdtoc.tracks[i].subsize,
298314         file->cdtoc.tracks[i].frames,
299315         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,
301319         file->cdtoc.tracks[i].postgap,
302320         file->cdtoc.tracks[i].logframeofs,
303321         file->cdtoc.tracks[i].physframeofs,
304         file->cdtoc.tracks[i].chdframeofs));
322         file->cdtoc.tracks[i].chdframeofs);*/
305323   }
306324
307325   /* fill out dummy entries for the last track to help our search */
r22882r22883
339357    CORE READ ACCESS
340358***************************************************************************/
341359
342chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 chdsector, UINT32 tracknum, UINT32 startoffs, UINT32 length)
360chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UINT32 chdsector, UINT32 tracknum, UINT32 startoffs, UINT32 length)
343361{
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
344370   // if a CHD, just read
345371   if (file->chd != NULL)
346372      return file->chd->read_bytes(UINT64(chdsector) * UINT64(CD_FRAME_SIZE) + startoffs, dest, length);
r22882r22883
353379
354380   sourcefileoffset += chdsector * bytespersector + startoffs;
355381
382//   printf("Reading sector %d from track %d at offset %lld\n", chdsector, tracknum, sourcefileoffset);
383
356384   core_fseek(srcfile, sourcefileoffset, SEEK_SET);
357385   core_fread(srcfile, dest, length);
358386
r22882r22883
398426
399427   if ((datatype == tracktype) || (datatype == CD_TRACK_RAW_DONTCARE))
400428   {
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);
402430   }
403431   else
404432   {
405433      /* return 2048 bytes of mode 1 data from a 2352 byte mode 1 raw sector */
406434      if ((datatype == CD_TRACK_MODE1) && (tracktype == CD_TRACK_MODE1_RAW))
407435      {
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);
409437      }
410438
411439      /* return 2352 byte mode 1 raw sector from 2048 bytes of mode 1 data */
r22882r22883
421449         bufptr[14] = msf&0xff;
422450         bufptr[15] = 1; // mode 1
423451         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);
425453      }
426454
427455      /* return 2048 bytes of mode 1 data from a mode2 form1 or raw sector */
428456      if ((datatype == CD_TRACK_MODE1) && ((tracktype == CD_TRACK_MODE2_FORM1)||(tracktype == CD_TRACK_MODE2_RAW)))
429457      {
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);
431459      }
432460
433461      /* return mode 2 2336 byte data from a 2352 byte mode 1 or 2 raw sector (skip the header) */
434462      if ((datatype == CD_TRACK_MODE2) && ((tracktype == CD_TRACK_MODE1_RAW) || (tracktype == CD_TRACK_MODE2_RAW)))
435463      {
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);
437465      }
438466
439467      LOG(("CDROM: Conversion from type %d to type %d not supported!\n", tracktype, datatype));
r22882r22883
469497      return 1;
470498
471499   // 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);
473501   return (err == CHDERR_NONE);
474502}
475503
r22882r22883
493521
494522   /* convert to a CHD sector offset and get track information */
495523   logical_to_chd_lba(file, frame, track);
524
496525   return track;
497526}
498527
r22882r22883
883912      track->pgsub = CD_SUB_NONE;
884913      track->pgdatasize = 0;
885914      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         }
888921
922         cdrom_convert_subtype_string_to_pregap_info(pgsub, track);
923      }
924
889925      /* set the postgap info */
890926      track->postgap = postgap;
891927   }
r22882r22883
957993      astring metadata;
958994      if (!(toc->flags & CD_FLAG_GDROM))
959995      {
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
9601008         metadata.format(CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype),
9611009               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),
9631011               toc->tracks[i].postgap);
964
9651012         err = chd->write_metadata(CDROM_TRACK_METADATA2_TAG, i, metadata);
9661013      }
9671014      else
r22882r22883
12751322   memset(&sector[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES);
12761323   memset(&sector[ECC_Q_OFFSET], 0, 2 * ECC_Q_NUM_BYTES);
12771324}
1325
trunk/src/lib/util/cdrom.h
r22882r22883
111111   /* fields used in CHDMAN only */
112112   UINT32 padframes;   /* number of frames of padding to add to the end of the track; needed for GDI */
113113
114   /* fields used in MAME only */
115   UINT32 logframeofs; /* logical frame offset: offset including pre/postgaps */
116   UINT32 physframeofs; /* physical frame offset: offset ignoring pre/postgaps */
114   /* fields used in MAME/MESS only */
115   UINT32 logframeofs; /* logical frame of actual track data - offset by pregap size if pregap not physically present */
116   UINT32 physframeofs; /* physical frame of actual track data in CHD data */
117117   UINT32 chdframeofs; /* frame number this track starts at on the CHD */
118118};
119119
trunk/src/lib/util/chdcd.c
r22882r22883
756756
757757            if (!strcmp(token, "BINARY"))
758758            {
759               outinfo.track[trknum].swap = false;
759               outinfo.track[trknum+1].swap = false;
760760            }
761761            else if (!strcmp(token, "MOTOROLA"))
762762            {
763               outinfo.track[trknum].swap = true;
763               outinfo.track[trknum+1].swap = true;
764764            }
765765            else if (!strcmp(token, "WAVE"))
766766            {
r22882r22883
844844               if ((outtoc.tracks[trknum].pregap == 0) && (outinfo.track[trknum].idx0offs != -1))
845845               {
846846                  outtoc.tracks[trknum].pregap = frames - outinfo.track[trknum].idx0offs;
847                  outtoc.tracks[trknum].pgtype = outtoc.tracks[trknum].trktype;
848                  switch (outtoc.tracks[trknum].pgtype)
849                  {
850                     case CD_TRACK_MODE1:
851                     case CD_TRACK_MODE2_FORM1:
852                        outtoc.tracks[trknum].pgdatasize = 2048;
853                        break;
854
855                     case CD_TRACK_MODE1_RAW:
856                     case CD_TRACK_MODE2_RAW:
857                     case CD_TRACK_AUDIO:
858                        outtoc.tracks[trknum].pgdatasize = 2352;
859                        break;
860
861                     case CD_TRACK_MODE2:
862                     case CD_TRACK_MODE2_FORM_MIX:
863                        outtoc.tracks[trknum].pgdatasize = 2336;
864                        break;
865
866                     case CD_TRACK_MODE2_FORM2:
867                        outtoc.tracks[trknum].pgdatasize = 2324;
868                        break;
869                  }
847870               }
871               else   // pregap sectors not in file, but we're always using idx0ofs for track length calc now
872               {
873                  outinfo.track[trknum].idx0offs = frames;
874               }
848875            }
849876         }
850877         else if (!strcmp(token, "PREGAP"))
r22882r22883
923950            /* if we have the same filename as the next track, do it that way */
924951            if (outinfo.track[trknum].fname == outinfo.track[trknum+1].fname)
925952            {
926               outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx1offs - outinfo.track[trknum].idx1offs;
953               outtoc.tracks[trknum].frames = outinfo.track[trknum+1].idx0offs - outinfo.track[trknum].idx0offs;
927954
928955               if (trknum == 0)    // track 0 offset is 0
929956               {
r22882r22883
11481175
11491176   return CHDERR_NONE;
11501177}
1178
trunk/src/mess/machine/pce.c
r22882r22883
812812      {
813813         track = MAX( bcd_2_dec( pce_cd.command_buffer[2] ), 1 );
814814         frame = toc->tracks[track-1].logframeofs;
815         // PCE wants the start sector for data tracks to *not* include the pregap
816         if (toc->tracks[track-1].trktype != CD_TRACK_AUDIO)
817         {
818            frame += toc->tracks[track-1].pregap;
819         }
815820         pce_cd.data_buffer[3] = ( toc->tracks[track-1].trktype == CD_TRACK_AUDIO ) ? 0x00 : 0x04;
816821      }
817822      logerror("track = %d, frame = %d\n", track, frame );

Previous 199869 Revisions Next


© 1997-2024 The MAME Team