Previous 199869 Revisions Next

r20081 Saturday 5th January, 2013 at 17:43:12 UTC by R. Belmont
cdrom: Introduces concept of logical sector addresses so games see the disc with pregap/postgap sectors actually taking up sector numbers as in reality.  Fixes PC-Engine CDs with hardcoded sector numbers. [R. Belmont, Angelo Salese]
[src/lib/util]cdrom.c cdrom.h
[src/mame/machine]megacdcd.c
[src/mess/machine]pce.c
[src/tools]chdman.c

trunk/src/mame/machine/megacdcd.c
r20080r20081
236236   if(segacd.cd == NULL) // no cd is there, bail out
237237      return;
238238   CDD_STATUS |= SCD_STATUS;
239   elapsedlba = SCD_CURLBA - segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].physframeofs;
239   elapsedlba = SCD_CURLBA - segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) ].logframeofs;
240240   msf = lba_to_msf_alt (elapsedlba);
241   //popmessage("%08x %08x",SCD_CURLBA,segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].physframeofs);
241   //popmessage("%08x %08x",SCD_CURLBA,segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].logframeofs);
242242   CDD_MIN = to_bcd(((msf & 0x00ff0000)>>16),false);
243243   CDD_SEC = to_bcd(((msf & 0x0000ff00)>>8),false);
244244   CDD_FRAME = to_bcd(((msf & 0x000000ff)>>0),false);
r20080r20081
263263      return;
264264   CDD_STATUS |= SCD_STATUS;
265265
266   UINT32 startlba = (segacd.toc->tracks[cdrom_get_last_track(segacd.cd)].physframeofs);
266   UINT32 startlba = (segacd.toc->tracks[cdrom_get_last_track(segacd.cd)].logframeofs);
267267   UINT32 startmsf = lba_to_msf_alt( startlba );
268268
269269   CDD_MIN = to_bcd((startmsf&0x00ff0000)>>16,false);
r20080r20081
301301   if (track < 1)
302302      track = 1;
303303
304   UINT32 startlba = (segacd.toc->tracks[track-1].physframeofs);
304   UINT32 startlba = (segacd.toc->tracks[track-1].logframeofs);
305305   UINT32 startmsf = lba_to_msf_alt( startlba+150 );
306306
307307   CDD_MIN = to_bcd((startmsf&0x00ff0000)>>16,false);
r20080r20081
359359   CLEAR_CDD_RESULT
360360   UINT32 msf = getmsf_from_regs();
361361   SCD_CURLBA = msf_to_lba(msf)-150;
362   UINT32 end_msf = segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].physframeofs;
362   UINT32 end_msf = segacd.toc->tracks[ cdrom_get_track(segacd.cd, SCD_CURLBA) + 1 ].logframeofs;
363363   SCD_CURTRK = cdrom_get_track(segacd.cd, SCD_CURLBA)+1;
364364   LC8951UpdateHeader();
365365   SCD_STATUS = CDD_PLAYINGCDDA;
trunk/src/tools/chdman.c
r20080r20081
23662366            progress(false, "Extracting, %.1f%% complete... \r", 100.0 * double(outputoffs) / double(total_bytes));
23672367
23682368            // read the data
2369            cdrom_read_data(cdrom, cdrom_get_track_start(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype);
2369            cdrom_read_data(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype, true);
23702370
23712371            // for CDRWin, audio tracks must be reversed
23722372            if ((mode == MODE_CUEBIN) && (trackinfo.trktype == CD_TRACK_AUDIO))
r20080r20081
23822382            // read the subcode data
23832383            if (trackinfo.subtype != CD_SUB_NONE && (mode == MODE_NORMAL))
23842384            {
2385                    cdrom_read_subcode(cdrom, cdrom_get_track_start(cdrom, tracknum) + frame, &buffer[bufferoffs]);
2385                    cdrom_read_subcode(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], true);
23862386                    bufferoffs += trackinfo.subsize;
23872387            }
23882388
trunk/src/lib/util/cdrom.c
r20080r20081
124124   return physlba;
125125}
126126
127/*-------------------------------------------------
128    logical_to_chd_lba - find the CHD LBA
129    and the track number
130-------------------------------------------------*/
127131
132INLINE UINT32 logical_to_chd_lba(cdrom_file *file, UINT32 loglba, UINT32 &tracknum)
133{
134   UINT32 chdlba, physlba;
135   int track;
128136
137   /* loop until our current LBA is less than the start LBA of the next track */
138   for (track = 0; track < file->cdtoc.numtrks; track++)
139      if (loglba < file->cdtoc.tracks[track + 1].logframeofs)
140      {
141         // convert to physical and proceed
142         physlba = file->cdtoc.tracks[track].physframeofs + (loglba - file->cdtoc.tracks[track].logframeofs);
143         chdlba = physlba - file->cdtoc.tracks[track].physframeofs + file->cdtoc.tracks[track].chdframeofs;
144         tracknum = track;
145         return chdlba;
146      }
147
148   return loglba;
149}
150
151
129152/***************************************************************************
130153    BASE FUNCTIONALITY
131154***************************************************************************/
r20080r20081
134157{
135158   int i;
136159   cdrom_file *file;
137   UINT32 physofs;
160   UINT32 physofs, logofs;
138161
139162   /* allocate memory for the CD-ROM file */
140163   file = new cdrom_file();
r20080r20081
168191   /* calculate the starting frame for each track, keeping in mind that CHDMAN
169192       pads tracks out with extra frames to fit 4-frame size boundries
170193    */
171   physofs = 0;
194   physofs = logofs = 0;
172195   for (i = 0; i < file->cdtoc.numtrks; i++)
173196   {
174197      file->cdtoc.tracks[i].physframeofs = physofs;
175198      file->cdtoc.tracks[i].chdframeofs = 0;
176199
200      // pregap counts against this track
201      logofs += file->cdtoc.tracks[i].pregap;
202      file->cdtoc.tracks[i].logframeofs = logofs;
203
204      // postgap counts against the next track
205      logofs += file->cdtoc.tracks[i].postgap;
206
177207      physofs += file->cdtoc.tracks[i].frames;
208      logofs  += file->cdtoc.tracks[i].frames;
178209
179      LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d physofs %d chdofs %d\n", i+1,
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,
180211         file->cdtoc.tracks[i].trktype,
181212         file->cdtoc.tracks[i].subtype,
182213         file->cdtoc.tracks[i].datasize,
183214         file->cdtoc.tracks[i].subsize,
184215         file->cdtoc.tracks[i].frames,
185         file->cdtoc.tracks[i].extraframes,
216           file->cdtoc.tracks[i].extraframes,
217             file->cdtoc.tracks[i].pregap,
218         file->cdtoc.tracks[i].postgap,
219           file->cdtoc.tracks[i].logframeofs,
186220         file->cdtoc.tracks[i].physframeofs,
187221         file->cdtoc.tracks[i].chdframeofs));
188222   }
r20080r20081
203237{
204238   int i;
205239   cdrom_file *file;
206   UINT32 physofs, chdofs;
240   UINT32 physofs, chdofs, logofs;
207241   chd_error err;
208242
209243   /* punt if no CHD */
r20080r20081
237271   /* calculate the starting frame for each track, keeping in mind that CHDMAN
238272       pads tracks out with extra frames to fit 4-frame size boundries
239273    */
240   physofs = chdofs = 0;
274   physofs = chdofs = logofs = 0;
241275   for (i = 0; i < file->cdtoc.numtrks; i++)
242276   {
243277      file->cdtoc.tracks[i].physframeofs = physofs;
244278      file->cdtoc.tracks[i].chdframeofs = chdofs;
245279
280      // pregap counts against this track
281      logofs += file->cdtoc.tracks[i].pregap;
282      file->cdtoc.tracks[i].logframeofs = logofs;
283
284      // postgap counts against the next track
285      logofs += file->cdtoc.tracks[i].postgap;
286
246287      physofs += file->cdtoc.tracks[i].frames;
247288      chdofs  += file->cdtoc.tracks[i].frames;
248289      chdofs  += file->cdtoc.tracks[i].extraframes;
290      logofs  += file->cdtoc.tracks[i].frames;
249291
250      LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d physofs %d chdofs %d\n", i+1,
292      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,
251293         file->cdtoc.tracks[i].trktype,
252294         file->cdtoc.tracks[i].subtype,
253295         file->cdtoc.tracks[i].datasize,
254296         file->cdtoc.tracks[i].subsize,
255297         file->cdtoc.tracks[i].frames,
256         file->cdtoc.tracks[i].extraframes,
298           file->cdtoc.tracks[i].extraframes,
299             file->cdtoc.tracks[i].pregap,
300         file->cdtoc.tracks[i].postgap,
301           file->cdtoc.tracks[i].logframeofs,
257302         file->cdtoc.tracks[i].physframeofs,
258303         file->cdtoc.tracks[i].chdframeofs));
259304   }
r20080r20081
328373    from a CD-ROM
329374-------------------------------------------------*/
330375
331UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype)
376UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype, bool phys)
332377{
333378   if (file == NULL)
334379      return 0;
335380
336381   // compute CHD sector and tracknumber
337382   UINT32 tracknum = 0;
338   UINT32 chdsector = physical_to_chd_lba(file, lbasector, tracknum);
383   UINT32 chdsector;
339384
385   if (phys)
386   {
387      chdsector = physical_to_chd_lba(file, lbasector, tracknum);
388   }
389   else
390   {
391      chdsector = logical_to_chd_lba(file, lbasector, tracknum);
392   }
393
340394   /* copy out the requested sector */
341395   UINT32 tracktype = file->cdtoc.tracks[tracknum].trktype;
342396   if ((datatype == tracktype) || (datatype == CD_TRACK_RAW_DONTCARE))
r20080r20081
390444    a sector
391445-------------------------------------------------*/
392446
393UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer)
447UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer, bool phys)
394448{
395449   if (file == NULL)
396450      return ~0;
397451
398452   // compute CHD sector and tracknumber
399453   UINT32 tracknum = 0;
400   UINT32 chdsector = physical_to_chd_lba(file, lbasector, tracknum);
454   UINT32 chdsector;
455
456   if (phys)
457   {
458      chdsector = physical_to_chd_lba(file, lbasector, tracknum);
459   }
460   else
461   {
462      chdsector = logical_to_chd_lba(file, lbasector, tracknum);
463   }
464
401465   if (file->cdtoc.tracks[tracknum].subsize == 0)
402466      return 1;
403467
r20080r20081
425489      return ~0;
426490
427491   /* convert to a CHD sector offset and get track information */
428   physical_to_chd_lba(file, frame, track);
492   logical_to_chd_lba(file, frame, track);
429493   return track;
430494}
431495
r20080r20081
444508   if (track == 0xaa)
445509      track = file->cdtoc.numtrks;
446510
447   return file->cdtoc.tracks[track].physframeofs;
511   return file->cdtoc.tracks[track].logframeofs;
448512}
449513
514/*-------------------------------------------------
515    cdrom_get_track_start_phys - get the
516   physical frame number that a track starts at
517-------------------------------------------------*/
450518
519UINT32 cdrom_get_track_start_phys(cdrom_file *file, UINT32 track)
520{
521   if (file == NULL)
522      return ~0;
451523
524   /* handle lead-out specially */
525   if (track == 0xaa)
526      track = file->cdtoc.numtrks;
527
528   return file->cdtoc.tracks[track].physframeofs;
529}
530
452531/***************************************************************************
453532    TOC UTILITIES
454533***************************************************************************/
trunk/src/lib/util/cdrom.h
r20080r20081
112112   UINT32 padframes;   /* number of frames of padding to add to the end of the track; needed for GDI */
113113
114114   /* fields used in MAME only */
115   UINT32 physframeofs;   /* frame number on the real CD this track starts at */
115   UINT32 logframeofs;   /* logical frame offset: offset including pre/postgaps */
116   UINT32 physframeofs; /* physical frame offset: offset ignoring pre/postgaps */
116117   UINT32 chdframeofs;   /* frame number this track starts at on the CHD */
117118};
118119
r20080r20081
137138cdrom_file *cdrom_open(const char *inputfile);
138139
139140/* core read access */
140UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype);
141UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer);
141UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype, bool phys=false);
142UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer, bool phys=false);
142143
143144/* handy utilities */
144145UINT32 cdrom_get_track(cdrom_file *file, UINT32 frame);
145146UINT32 cdrom_get_track_start(cdrom_file *file, UINT32 track);
147UINT32 cdrom_get_track_start_phys(cdrom_file *file, UINT32 track);
146148
147149/* TOC utilities */
148150int cdrom_get_last_track(cdrom_file *file);
trunk/src/mess/machine/pce.c
r20080r20081
600600      f = bcd_2_dec( pce_cd.command_buffer[4]);
601601
602602      frame = f + 75 * (s + m * 60);
603      if(frame >= 525) // TODO: seven seconds gap? O_o
604         frame -= 525;
603      // PCE tries to be clever here and set (start of track + track pregap size) to skip the pregap
604      // (I guess it wants the TOC to have the real start sector for data tracks and the start of the pregap for audio?)
605      frame -= pce_cd.toc->tracks[cdrom_get_track(pce_cd.cd, frame)].pregap;
605606      break;
606607   }
607608   case 0x80:
608      frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].physframeofs;
609      frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].logframeofs;
609610      break;
610611   default:
611612      popmessage("CD-DA set start mode 0xc0, contact MESSdev");
r20080r20081
635636      else
636637      {
637638         pce_cd.cdda_status = PCE_CD_CDDA_PLAYING;
638         pce_cd.end_frame = pce_cd.toc->tracks[ cdrom_get_track(pce_cd.cd, pce_cd.current_frame) + 1 ].physframeofs; //get the end of THIS track
639         pce_cd.end_frame = pce_cd.toc->tracks[ cdrom_get_track(pce_cd.cd, pce_cd.current_frame) + 1 ].logframeofs; //get the end of THIS track
639640         cdda_start_audio( machine.device( "cdda" ), pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame );
640641         pce_cd.end_mark = 0;
641642         pce_cd.cdda_play_mode = 3;
r20080r20081
680681      break;
681682   }
682683   case 0x80:
683      frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].physframeofs;
684      frame = pce_cd.toc->tracks[ bcd_2_dec( pce_cd.command_buffer[2] ) - 1 ].logframeofs;
684685      break;
685686   default:
686687      popmessage("CD-DA set end mode 0xc0, contact MESSdev");
r20080r20081
822823      pce_cd.data_buffer_size = 2;
823824      break;
824825   case 0x01:      /* Get total disk size in MSF format */
825      frame = toc->tracks[toc->numtrks-1].physframeofs;
826      frame = toc->tracks[toc->numtrks-1].logframeofs;
826827      frame += toc->tracks[toc->numtrks-1].frames;
827828      msf = lba_to_msf( frame + 150 );
828829
r20080r20081
834835   case 0x02:      /* Get track information */
835836      if ( pce_cd.command_buffer[2] == 0xAA )
836837      {
837         frame = toc->tracks[toc->numtrks-1].physframeofs;
838         frame = toc->tracks[toc->numtrks-1].logframeofs;
838839         frame += toc->tracks[toc->numtrks-1].frames;
839840         pce_cd.data_buffer[3] = 0x04;   /* correct? */
840841      } else
841842      {
842843         track = MAX( bcd_2_dec( pce_cd.command_buffer[2] ), 1 );
843         frame = toc->tracks[track-1].physframeofs;
844         frame = toc->tracks[track-1].logframeofs;
844845         pce_cd.data_buffer[3] = ( toc->tracks[track-1].trktype == CD_TRACK_AUDIO ) ? 0x00 : 0x04;
845846      }
846847      logerror("track = %d, frame = %d\n", track, frame );

Previous 199869 Revisions Next


© 1997-2024 The MAME Team