@@ -541,29 +541,39 @@ bool CdRomMedia::ReadSector(u32 lba, u8* buffer)
541541 return false ;
542542 }
543543
544+ u32 file_offset = 0 ;
544545 for (size_t i = 0 ; i < m_tracks.size (); i++)
545546 {
546547 const Track& track = m_tracks[i];
548+ u32 sector_size = track.sector_size ;
547549 u32 start = track.start_lba ;
548550 u32 end = start + track.sector_count ;
549551
550552 if (lba >= start && lba < end)
551553 {
552554 u32 sector_offset = lba - start;
553- u32 sector_size = GetTrackSectorSize (track.type );
554555 ImgFile* img_file = track.img_file ;
555556
556557 if (img_file == NULL || img_file->file_size == 0 )
557558 return false ;
558559
559- u64 byte_offset = sector_offset * (u64 )sector_size;
560+ u64 byte_offset = file_offset + (sector_offset * sector_size);
561+
562+ if (sector_size == 2352 )
563+ {
564+ byte_offset += 16 ;
565+ sector_size = 2048 ;
566+ }
567+
560568 if (byte_offset + sector_size > img_file->file_size )
561569 return false ;
562570
563- Debug (" Reading sector %d from track %d (LBA: %d)" , lba, track. number , byte_offset);
571+ Debug (" Reading sector %d from track %d (LBA: %d)" , lba, i , byte_offset);
564572
565573 return ReadFromImgFile (img_file, byte_offset, buffer, sector_size);
566574 }
575+ else
576+ file_offset += (track.sector_size * track.sector_count );
567577 }
568578
569579 Debug (" ERROR: ReadSector failed - LBA %d not found in any track" , lba);
@@ -657,7 +667,6 @@ bool CdRomMedia::LoadChunk(ImgFile* img_file, u32 chunk_index)
657667 }
658668
659669 file.close ();
660- Debug (" Loaded chunk %d from %s" , chunk_index, img_file->file_path );
661670 return true ;
662671}
663672
@@ -714,4 +723,71 @@ bool CdRomMedia::PreloadTrackChunks(u32 track_number, u32 sectors)
714723 u32 chunks_needed = (total_bytes + track.img_file ->chunk_size - 1 ) / track.img_file ->chunk_size ;
715724
716725 return PreloadChunks (track.img_file , start_chunk, chunks_needed);
726+ }
727+
728+ // /////////////////////////////////////////////////////////////
729+ // Seek time, based on the work by Dave Shadoff
730+ // https://github.com/pce-devel/PCECD_seek
731+
732+ u32 CdRomMedia::SeekFindGroup (u32 lba)
733+ {
734+ for (u32 i = 0 ; i < GG_SEEK_NUM_SECTOR_GROUPS ; i++)
735+ if ((lba >= k_seek_sector_list[i].sec_start ) && (lba <= k_seek_sector_list[i].sec_end ))
736+ return i;
737+ return 0 ;
738+ }
739+
740+ u32 CdRomMedia::SeekTime (u32 start_lba, u32 end_lba)
741+ {
742+ u32 start_index = SeekFindGroup (start_lba);
743+ u32 target_index = SeekFindGroup (end_lba);
744+ u32 lba_difference = (u32 )std::abs ((int )end_lba - (int )start_lba);
745+ float track_difference = 0 .0f ;
746+
747+ // Now we find the track difference
748+ //
749+ // Note: except for the first and last sector groups, all groups are 1606.48 tracks per group.
750+ //
751+ if (target_index == start_index)
752+ {
753+ track_difference = (lba_difference / k_seek_sector_list[target_index].sec_per_revolution );
754+ }
755+ else if (target_index > start_index)
756+ {
757+ track_difference = (k_seek_sector_list[start_index].sec_end - start_lba) / k_seek_sector_list[start_index].sec_per_revolution ;
758+ track_difference += (end_lba - k_seek_sector_list[target_index].sec_start ) / k_seek_sector_list[target_index].sec_per_revolution ;
759+ track_difference += (1606.48 * (target_index - start_index - 1 ));
760+ }
761+ else // start_index > target_index
762+ {
763+ track_difference = (start_lba - k_seek_sector_list[start_index].sec_start ) / k_seek_sector_list[start_index].sec_per_revolution ;
764+ track_difference += (k_seek_sector_list[target_index].sec_end - end_lba) / k_seek_sector_list[target_index].sec_per_revolution ;
765+ track_difference += (1606.48 * (start_index - target_index - 1 ));
766+ }
767+
768+ // Now, we use the algorithm to determine how long to wait
769+ if (lba_difference < 2 )
770+ {
771+ return (3 * 1000 / 60 );
772+ }
773+ if (lba_difference < 5 )
774+ {
775+ return (9 * 1000 / 60 ) + (float )(k_seek_sector_list[target_index].rotation_ms / 2 );
776+ }
777+ else if (track_difference <= 80 )
778+ {
779+ return (16 * 1000 / 60 ) + (float )(k_seek_sector_list[target_index].rotation_ms / 2 );
780+ }
781+ else if (track_difference <= 160 )
782+ {
783+ return (22 * 1000 / 60 ) + (float )(k_seek_sector_list[target_index].rotation_ms / 2 );
784+ }
785+ else if (track_difference <= 644 )
786+ {
787+ return (22 * 1000 / 60 ) + (float )(k_seek_sector_list[target_index].rotation_ms / 2 ) + (float )((track_difference - 161 ) * 16.66 / 80 );
788+ }
789+ else
790+ {
791+ return (36 * 1000 / 60 ) + (float )((track_difference - 644 ) * 16.66 / 195 );
792+ }
717793}
0 commit comments