saramibreak / DiscImageCreator

This is the disc (CD, GD, DVD, HD-DVD, BD, GC/Wii, XBOX, XBOX 360) and disk (Floppy, MO, USB etc) image creation tool
http://forum.redump.org/topic/10483/discimagecreator/
Apache License 2.0
530 stars 45 forks source link

Feature Request - Sample Level C2 error rereads (4 byte) #155

Open ehw opened 1 year ago

ehw commented 1 year ago

Is your feature request related to a problem? Please describe. DiscImageCreator currently reads the sectors off a disc and writes the bytes to a .scm file in one pass as they are returned by the drive, noting the C2 errors as the drive reads each sector on the disc. As the drive rereads each sector to fix corrupt sector reads caused by C2 errors, the drive will keep rereading the disc until the drive returns no bit errors for every byte for the 2352 byte sector. Each time the sector is reread, a checksum is calculated and provided in the log. When the drive returns no c2 errors for the sector, DiscImageCreator fills the entire $126 byte section of the .c2 file that correlates to the current LBA being retried with zeros, and moves on.

This is the current method DiscImageCreator uses to reread sectors with C2 errors. This method has some downsides, however. When the drive rereads the sector in succession, it's potentially reading the sector with less bit errors in comparison to the initial read done in the first pass at creating the .scm file. Because of this, good bits returned by the drive will basically be discarded even though these good bits were not present in the initial .scm pass. There might be reread attempt that might yield less bit errors in comparison to the initial .scm pass as well.

Describe the solution you'd like I propose a very simple "byte" level method of C2 error rereads that involves taking the bytes marked "good" when rereading the current sector, or alternatively, not taking the bytes marked "bad" by the c2 bit offsets (ofs), and storing them temporarily in memory until every c2 offset for the current sector has returned a "good" byte at least once by the drive. Once all 2352 bytes are correctly read, rewrite the .scm file with the corrections.

This is how I envision it would work with DIC itself: 1.) Initial pass of the .scm file is done, while DIC is marking sectors with C2 errors for rereads. 2.) Create a temporary, 2352 byte array to store C2 rereads in memory. 3,) When DIC attempts to reread the sector, have the drive return the result of the reread. Whatever bytes are confirmed "good" by the drive, write these bytes to the 2352 byte array in the location within the array that correlates to their offsets. Do not write the bytes that were confirmed "bad" to this array. 4.) Attempt to reread the sector again, does it return bytes marked good that weren't confirmed good before? Then write these values to the 2352 byte array. Again, don't write the bytes considered "bad" 5.) Do steps 3 and 4 in a loop according to the number of C2 reread attempts or until the array is completely filled with 2352 bytes. When the array is filled with 2352 bytes, it should be filled with only bytes that are confirmed good by the drive collected over several retries. 6.) Write the contents of the array to the .scm file for the current LBA. 7.) Move on to the next LBA and repeat steps 3-6 until all the sectors have been corrected.

Describe alternatives you've considered I can't think of an exact alternative, but any alternative should take the contents of the retries into consideration rather than the overall status of the sector on a reread by itself.

Additional context If the method I'm thinking of can work, there are benefits to utilizing it:

Note: I have no clue how C2 rereads work on a drive level, it's possible that maybe DIC can't take advantage of this method because of important data a drive might not provide. I'm sure this was thought of before, but I just want to write it down in case it ever needs to be referenced again.

ehw commented 1 year ago

Hey, an update.

So I've been looking at DICs C2 and SCM outputs for a long time now. One thing thats an issue is that when a drive reports that a byte contains a c2 error, its not always precise, especially if you're reading a data track. For instance, even if an error is 1 bit long according to the C2 log, it could actually affect at most 4 bytes around the general area of the reported error location. The reason for this is completely unknown, but might be due to factors because of the firmware that are unavoidably. Thus, the byte level correction is probably impossible to due without modifying the firmware.

However, as I said, for every 1 bit C2 error, there is at most 4 bytes affected in the scm at that location. Thus, maybe what can be done instead is anticipate a granularity of 4 bytes per c2 bit error. In other words, do sample size level correction, not byte sized. This should be safe enough to go after specific sample sizes instead.

saramibreak commented 1 year ago

Specifiacation MMC --- http://www.13thmonkey.org/documentation/SCSI/mmc3r10g.pdf p. 158

READ CD (BEh) command --- this command is used for non-plextor drive. DIC uses 01b.

Error Field | Definition
------------+------------
01b         | C2 error block data

Description
------------
The C2 error, Pointer bits (2 352 bits or 294 bytes) is included in the data stream. There is
one bit for each byte in error in the sector (2 352 total). The bit ordering is from the most
significant bit to the least significant bit in each byte.  The first bytes in the sector are the first
bits/bytes in the data stream.

Error Field | Definition
------------+------------
10b         | C2 and Block Error Bits

Description
------------
Both the C2 error bits (2 352 bits/294 bytes) and the Block Error Byte are included in the
data stream. The Block Error Byte is the logical or of all the C2 Error bit bytes. The Error
Byte shall be padded with a byte (undefined) to ensure an even number of bytes in the data
stream.  The Block error byte shall be first in the data stream followed by the pad byte.
ehw commented 1 year ago

Hey @saramibreak, not sure what you mean. Is "sample" based c2 correction possible with DIC like redumper can?

I was able to figure out the "c2 offset" for a few popular drives, in case this is what is needed to make something like this work.

https://github.com/saramibreak/DiscImageCreator/issues/154#issuecomment-1305142496