PLEXTOR DVDR PX-760A subchannel problem

This commit is contained in:
chudov
2008-12-10 21:42:37 +00:00
parent 02b08c8d5b
commit 9628189d81
4 changed files with 66 additions and 26 deletions

View File

@@ -39,6 +39,20 @@ namespace CUERipper
private void frmCUERipper_Load(object sender, EventArgs e) private void frmCUERipper_Load(object sender, EventArgs e)
{ {
//byte[] _subchannelBuffer0 = { 0x1, 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x10, 0x75, 0x4E };
//byte[] _subchannelBuffer1 = { 0x21, 0x01, 0x01, 0x00, 0x00, 0x11, 0x00, 0x00, 0x02, 0x11, 0xCF, 0x3E };
//byte[] _subchannelBuffer2 = { 0x21, 0x01, 0x01, 0x00, 0x00, 0x12, 0x00, 0x00, 0x02, 0x12, 0x11, 0x8F };
//Crc16Ccitt _crc = new Crc16Ccitt(InitialCrcValue.Zeros);
//ushort crc0a = (ushort)(_crc.ComputeChecksum(_subchannelBuffer0, 0, 10) ^ 0xffff);
//ushort crc0b = (ushort)(_subchannelBuffer0[11] + (_subchannelBuffer0[10] << 8));
//ushort crc1a = (ushort)(_crc.ComputeChecksum(_subchannelBuffer1, 0, 10) ^ 0xffff);
//ushort crc1b = (ushort)(_subchannelBuffer1[11] + (_subchannelBuffer1[10] << 8));
//ushort crc2a = (ushort)(_crc.ComputeChecksum(_subchannelBuffer2, 0, 10) ^ 0xffff);
//ushort crc2b = (ushort)(_subchannelBuffer2[11] + (_subchannelBuffer2[10] << 8));
//if (crc0a != crc0b || crc1a != crc1b || crc2a != crc2b)
//{
//}
foreach(char drive in CDDriveReader.DrivesAvailable()) foreach(char drive in CDDriveReader.DrivesAvailable())
{ {
CDDriveReader reader = new CDDriveReader(); CDDriveReader reader = new CDDriveReader();

View File

@@ -6,7 +6,7 @@ namespace CUETools.Ripper.SCSI
{ {
public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F } public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }
class Crc16Ccitt public class Crc16Ccitt
{ {
const ushort poly = 4129; const ushort poly = 4129;
ushort[] table = new ushort[256]; ushort[] table = new ushort[256];

View File

@@ -76,6 +76,7 @@ namespace CUETools.Ripper.SCSI
string _autodetectResult; string _autodetectResult;
byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO]; byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO];
byte[] _subchannelBuffer = new byte[NSECTORS * 16]; byte[] _subchannelBuffer = new byte[NSECTORS * 16];
bool _qChannelInBCD = true;
public event EventHandler<ReadProgressArgs> ReadProgress; public event EventHandler<ReadProgressArgs> ReadProgress;
@@ -292,36 +293,47 @@ namespace CUETools.Ripper.SCSI
int adr = QData[_currentScan, q_pos, 0] & 7; int adr = QData[_currentScan, q_pos, 0] & 7;
bool preemph = (ctl & 1) == 1; bool preemph = (ctl & 1) == 1;
bool dcp = (ctl & 2) == 2; bool dcp = (ctl & 2) == 2;
for (int i = 0; i < 10; i++)
_subchannelBuffer[i] = QData[_currentScan, q_pos, i];
if (!_qChannelInBCD && adr == 1)
{
_subchannelBuffer[3] = toBCD(_subchannelBuffer[3]);
_subchannelBuffer[4] = toBCD(_subchannelBuffer[4]);
_subchannelBuffer[5] = toBCD(_subchannelBuffer[5]);
_subchannelBuffer[7] = toBCD(_subchannelBuffer[7]);
_subchannelBuffer[8] = toBCD(_subchannelBuffer[8]);
_subchannelBuffer[9] = toBCD(_subchannelBuffer[9]);
}
ushort crc = _crc.ComputeChecksum(_subchannelBuffer, 0, 10);
crc ^= 0xffff;
if ((QData[_currentScan, q_pos, 10] != 0 || QData[_currentScan, q_pos, 11] != 0) &&
((byte)(crc & 0xff) != QData[_currentScan, q_pos, 11] || (byte)(crc >> 8) != QData[_currentScan, q_pos, 10])
)
{
if (!updateMap)
continue;
_crcErrorsCount++;
if (_debugMessages && _crcErrorsCount < 4)
{
StringBuilder st = new StringBuilder();
for (int i = 0; i < 12; i++)
st.AppendFormat(",0x{0:X2}", QData[_currentScan, q_pos, i]);
System.Console.WriteLine("\nCRC error@{0}{1}", CDImageLayout.TimeToString((uint)(sector + iSector)), st.ToString());
}
continue;
}
switch (adr) switch (adr)
{ {
case 1: // current position case 1: // current position
{ {
int iTrack = fromBCD(QData[_currentScan, q_pos, 1]); int iTrack = fromBCD(QData[_currentScan, q_pos, 1]);
int iIndex = fromBCD(QData[_currentScan, q_pos, 2]); int iIndex = fromBCD(QData[_currentScan, q_pos, 2]);
int mm = fromBCD(QData[_currentScan, q_pos, 7]); int mm = _qChannelInBCD ? fromBCD(QData[_currentScan, q_pos, 7]) : QData[_currentScan, q_pos, 7];
int ss = fromBCD(QData[_currentScan, q_pos, 8]); int ss = _qChannelInBCD ? fromBCD(QData[_currentScan, q_pos, 8]) : QData[_currentScan, q_pos, 8];
int ff = fromBCD(QData[_currentScan, q_pos, 9]); int ff = _qChannelInBCD ? fromBCD(QData[_currentScan, q_pos, 9]) : QData[_currentScan, q_pos, 9];
int sec = ff + 75 * (ss + 60 * mm) - 150; // sector + iSector;
//if (sec != sector + iSector) //if (sec != sector + iSector)
// System.Console.WriteLine("\rLost sync: {0} vs {1} ({2:X} vs {3:X})", CDImageLayout.TimeToString((uint)(sector + iSector)), CDImageLayout.TimeToString((uint)sec), sector + iSector, sec); // System.Console.WriteLine("\rLost sync: {0} vs {1} ({2:X} vs {3:X})", CDImageLayout.TimeToString((uint)(sector + iSector)), CDImageLayout.TimeToString((uint)sec), sector + iSector, sec);
for (int i = 0; i < 10; i++)
_subchannelBuffer[i] = QData[_currentScan, q_pos, i];
ushort crc = _crc.ComputeChecksum(_subchannelBuffer, 0, 10);
crc ^= 0xffff;
if ((QData[_currentScan, q_pos, 10] != 0 || QData[_currentScan, q_pos, 11] != 0) &&
((byte)(crc & 0xff) != QData[_currentScan, q_pos, 11] || (byte)(crc >> 8) != QData[_currentScan, q_pos, 10])
)
{
_crcErrorsCount ++;
if (_debugMessages && _crcErrorsCount < 4)
{
StringBuilder st = new StringBuilder();
for (int i = 0; i < 12; i++)
st.AppendFormat(" 0x{0:X2}", QData[_currentScan, q_pos, i]);
System.Console.WriteLine("\nCRC error at {0}:{1}", CDImageLayout.TimeToString((uint)(sector + iSector)), st.ToString());
}
continue;
}
if (iTrack == 110) if (iTrack == 110)
{ {
if (sector + iSector + 75 < _toc.AudioLength) if (sector + iSector + 75 < _toc.AudioLength)
@@ -334,6 +346,7 @@ namespace CUETools.Ripper.SCSI
posCount++; posCount++;
if (!updateMap) if (!updateMap)
break; break;
int sec = ff + 75 * (ss + 60 * mm) - 150; // sector + iSector;
if (iTrack > _toc.AudioTracks) if (iTrack > _toc.AudioTracks)
throw new Exception("strange track number encountred"); throw new Exception("strange track number encountred");
if (iTrack != _currentTrack) if (iTrack != _currentTrack)
@@ -444,10 +457,18 @@ namespace CUETools.Ripper.SCSI
DateTime tm = DateTime.Now; DateTime tm = DateTime.Now;
Device.CommandStatus st = FetchSectors(sector, m_max_sectors, false, false); Device.CommandStatus st = FetchSectors(sector, m_max_sectors, false, false);
TimeSpan delay = DateTime.Now - tm; TimeSpan delay = DateTime.Now - tm;
if (st == Device.CommandStatus.Success && _subChannelMode == Device.SubChannelMode.QOnly && ProcessSubchannel(sector, m_max_sectors, false) == 0) if (st == Device.CommandStatus.Success && _subChannelMode == Device.SubChannelMode.QOnly)
{ {
_autodetectResult += string.Format("{0}: {1}\n", CurrentReadCommand, "Got no subchannel information"); _qChannelInBCD = false;
continue; int sub1 = ProcessSubchannel(sector, m_max_sectors, false);
_qChannelInBCD = true;
int sub2 = ProcessSubchannel(sector, m_max_sectors, false);
_qChannelInBCD = sub2 >= sub1;
if (sub1 == 0 && sub2 == 0)
{
_autodetectResult += string.Format("{0}: {1}\n", CurrentReadCommand, "Got no subchannel information");
continue;
}
} }
_autodetectResult += string.Format("{0}: {1} ({2}ms)\n", CurrentReadCommand, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), delay.TotalMilliseconds); _autodetectResult += string.Format("{0}: {1} ({2}ms)\n", CurrentReadCommand, (st == Device.CommandStatus.DeviceFailed ? Device.LookupSenseError(m_device.GetSenseAsc(), m_device.GetSenseAscq()) : st.ToString()), delay.TotalMilliseconds);
found = st == Device.CommandStatus.Success && _subChannelMode != Device.SubChannelMode.RWMode;// && _subChannelMode != Device.SubChannelMode.QOnly; found = st == Device.CommandStatus.Success && _subChannelMode != Device.SubChannelMode.RWMode;// && _subChannelMode != Device.SubChannelMode.QOnly;
@@ -1026,6 +1047,11 @@ namespace CUETools.Ripper.SCSI
return (hex >> 4) * 10 + (hex & 15); return (hex >> 4) * 10 + (hex & 15);
} }
private byte toBCD(int val)
{
return (byte) ((val / 10) << 4 + (val % 10));
}
private char from6bit(int bcd) private char from6bit(int bcd)
{ {
char[] ISRC6 = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '#', '#', '#', '#', '#', '#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; char[] ISRC6 = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '#', '#', '#', '#', '#', '#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };