Plextor PX-W1210A workaround

This commit is contained in:
chudov
2012-01-07 00:17:00 +00:00
parent 4520762a72
commit 7e966f42d9
5 changed files with 49 additions and 23 deletions

View File

@@ -2011,6 +2011,10 @@ namespace Bwg.Scsi
/// </summary>
public enum MainChannelSelection
{
/// <summary>
///
/// </summary>
None,
/// <summary>
///
/// </summary>
@@ -2056,7 +2060,7 @@ namespace Bwg.Scsi
byte b = (byte)((exp & 0x07) << 2);
if (dap)
b |= 0x02;
byte byte9 = (byte) (mainmode == MainChannelSelection.UserData ? 0x10 : 0xF8);
byte byte9 = (byte)(mainmode == MainChannelSelection.UserData ? 0x10 : mainmode == MainChannelSelection.F8h ? 0xF8 : 0);
if (c2mode == C2ErrorMode.Mode294)
byte9 |= 0x02;
else if (c2mode == C2ErrorMode.Mode296)
@@ -2066,8 +2070,7 @@ namespace Bwg.Scsi
cmd.SetCDB24(6, length);
cmd.SetCDB8(9, byte9); // User data + possibly c2 errors
cmd.SetCDB8(10, mode); // Subchannel
CommandStatus st = SendCommand(cmd);
CommandStatus st = SendCommand(cmd);
if (st != CommandStatus.Success)
return st;
}
@@ -2095,7 +2098,7 @@ namespace Bwg.Scsi
byte mode = (byte)(submode == SubChannelMode.QOnly ? 1 : submode == SubChannelMode.RWMode ? 2 : 0);
int size = 4 * 588 + (submode == SubChannelMode.QOnly ? 16 : submode == SubChannelMode.RWMode ? 96 : 0);
using (Command cmd = new Command(ScsiCommandCode.ReadCDDA, 12, data, size, Command.CmdDirection.In, timeout))
using (Command cmd = new Command(ScsiCommandCode.ReadCDDA, 12, data, (int)length * size, Command.CmdDirection.In, timeout))
{
cmd.SetCDB8(1, 0 << 5); // lun
cmd.SetCDB32(2, start);
@@ -2205,6 +2208,8 @@ namespace Bwg.Scsi
using (Command cmd = new Command(ScsiCommandCode.ReadCd, 12, (int)(length * bytes_per_sector), Command.CmdDirection.In, timeout))
{
byte b = (byte)(1 << 2);
cmd.SetCDB8(1, b);
cmd.SetCDB32(2, sector); // The sector number to start with
cmd.SetCDB24(6, length); // The length in sectors
cmd.SetCDB8(10, mode); // Corrected, de-interleaved P - W data

View File

@@ -408,11 +408,10 @@ namespace CUETools.AccurateRip
{
int discLen = (int)_toc.AudioLength * 588;
int chunkLen = discLen - prefixSamples - suffixSamples;
crc = Crc32.Combine(
_CRC32[0, prefixSamples],
return 0xffffffff ^ Crc32.Combine(
0xffffffff ^ _CRC32[0, prefixSamples],
_CRC32[_toc.AudioTracks, 2 * maxOffset - suffixSamples],
chunkLen * 4);
return Crc32.Combine(0xffffffff, crc, chunkLen * 4) ^ 0xffffffff;
}
int posA = (int)_toc[iTrack + _toc.FirstAudio - 1].Start * 588 + (iTrack > 1 ? oi : prefixSamples);
int posB = iTrack < _toc.AudioTracks ?
@@ -437,10 +436,8 @@ namespace CUETools.AccurateRip
_CRC32[iTrack, maxOffset * 2 + oi] :
_CRC32[iTrack, maxOffset * 2 - suffixSamples];
}
crc = Crc32.Combine(crcA, crcB, (posB - posA) * 4);
// Use 0xffffffff as an initial state
crc = Crc32.Combine(0xffffffff, crc, (posB - posA) * 4) ^ 0xffffffff;
return crc;
// Use 0xffffffff as an initial state
return 0xffffffff ^ Crc32.Combine(0xffffffff ^ crcA, crcB, (posB - posA) * 4);
}
public uint CTDBCRC(int offset)

View File

@@ -36,7 +36,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>

View File

@@ -72,7 +72,7 @@ namespace CUETools.Ripper.SCSI
Device.C2ErrorMode _c2ErrorMode = Device.C2ErrorMode.Mode296;
string _autodetectResult;
byte[] _readBuffer = new byte[NSECTORS * CB_AUDIO];
byte[] _subchannelBuffer = new byte[CB_AUDIO];
byte[] _subchannelBuffer = new byte[NSECTORS * CB_AUDIO];
bool _qChannelInBCD = true;
private ReadProgressArgs progressArgs = new ReadProgressArgs();
@@ -474,7 +474,27 @@ namespace CUETools.Ripper.SCSI
if (_readCDCommand == ReadCDCommand.ReadCdBEh)
{
st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, ref _subchannelBuffer, _timeout);
// PLEXTOR PX-W1210A always returns data, even if asked only for subchannel.
// So we fill the buffer with magic data, give extra space for command so it won't hang the drive,
// request subchannel data and check if magic data was overwritten.
bool overwritten = false;
for (int i = 0; i < 16; i++)
{
_subchannelBuffer[m_max_sectors * (588 * 4 + 16) - 16 + i] = (byte)(13 + i);
}
fixed (byte* data = _subchannelBuffer)
{
st = m_device.ReadCDAndSubChannel(Device.MainChannelSelection.None, Device.SubChannelMode.QOnly, Device.C2ErrorMode.None, 1, false, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, (IntPtr)((void*)data), _timeout);
}
for (int i = 0; i < 16; i++)
{
if (_subchannelBuffer[m_max_sectors * (588 * 4 + 16) - 16 + i] != (byte)(13 + i))
overwritten = true;
}
if (overwritten)
st = Device.CommandStatus.NotSupported;
//else
// st = m_device.ReadSubChannel(2, (uint)sector + _toc[_toc.FirstAudio][0].Start, (uint)m_max_sectors, ref _subchannelBuffer, _timeout);
if (st == Device.CommandStatus.Success)
{
int[] goodsecs = new int[2];
@@ -712,7 +732,7 @@ namespace CUETools.Ripper.SCSI
return true;
//ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h };
ReadCDCommand[] readmode = { ReadCDCommand.ReadCdD8h, ReadCDCommand.ReadCdBEh };
ReadCDCommand[] readmode = { ReadCDCommand.ReadCdBEh, ReadCDCommand.ReadCdD8h };
Device.C2ErrorMode[] c2mode = { Device.C2ErrorMode.Mode294, Device.C2ErrorMode.Mode296, Device.C2ErrorMode.None };
Device.MainChannelSelection[] mainmode = { Device.MainChannelSelection.UserData, Device.MainChannelSelection.F8h };
bool found = false;
@@ -731,7 +751,7 @@ namespace CUETools.Ripper.SCSI
_mainChannelMode = mainmode[m];
if (_forceReadCommand != ReadCDCommand.Unknown && _readCDCommand != _forceReadCommand)
continue;
if (_readCDCommand == ReadCDCommand.ReadCdD8h) // && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData))
if (_readCDCommand == ReadCDCommand.ReadCdD8h && (_c2ErrorMode != Device.C2ErrorMode.None || _mainChannelMode != Device.MainChannelSelection.UserData))
continue;
Array.Clear(_readBuffer, 0, _readBuffer.Length); // fill with something nasty instead?
DateTime tm = DateTime.Now;
@@ -765,12 +785,16 @@ namespace CUETools.Ripper.SCSI
// break;
// }
// }
TestGaps();
if (found)
_autodetectResult += "Chosen " + CurrentReadCommand + "\n";
else
_readCDCommand = ReadCDCommand.Unknown;
if (found)
{
TestGaps();
_autodetectResult += "Chosen " + CurrentReadCommand + "\n";
}
else
{
_gapDetection = GapDetectionMethod.None;
_readCDCommand = ReadCDCommand.Unknown;
}
_currentStart = -1;
_currentEnd = -1;

View File

@@ -375,7 +375,7 @@ namespace CUETools.TestParity
///Verifying rip that has errors
///</summary>
[TestMethod()]
//[Ignore]
[Ignore]
public void CDRepairVerifyParitySpeedTest()
{
var generator1 = new TestImageGenerator("0 98011", seed, 32 * 588);