mirror of https://github.com/PCSX2/pcsx2.git
DEV9: Set/Clear SEEK bit in all relevent commands (#11931)
* DEV9: Set SEEK on all successful seeks * DEV9: Complete HDD_Flush immediately when write queue is empty Also set SEEK when write queue isn't empty * DEV9: Lock reported value of SEEK when errored
This commit is contained in:
parent
8afd29e1a2
commit
a044b7cf6e
|
@ -94,7 +94,11 @@ private:
|
||||||
u8 regNsector;
|
u8 regNsector;
|
||||||
u8 regNsectorHOB;
|
u8 regNsectorHOB;
|
||||||
|
|
||||||
u8 regStatus; //ReadOnly. When read via AlternateStatus pending interrupts are not cleared
|
u8 regStatus; // ReadOnly. When read via AlternateStatus, pending interrupts are not cleared.
|
||||||
|
// When an error occurs, the SEEK bit shall not be changed until the Status Register is read,
|
||||||
|
// after which this bit again indicates Seek completed.
|
||||||
|
// A value of -1 is locked clear, a value of 1 is locked set, 0 is unlocked.
|
||||||
|
s8 regStatusSeekLock;
|
||||||
|
|
||||||
bool pendingInterrupt = false;
|
bool pendingInterrupt = false;
|
||||||
|
|
||||||
|
|
|
@ -317,6 +317,9 @@ void ATA::ResetEnd(bool hard)
|
||||||
mdmaMode = 2;
|
mdmaMode = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regStatus |= ATA_STAT_SEEK;
|
||||||
|
regStatusSeekLock = 0;
|
||||||
|
|
||||||
HDD_ExecuteDeviceDiag(false);
|
HDD_ExecuteDeviceDiag(false);
|
||||||
regControlEnableIRQ = false;
|
regControlEnableIRQ = false;
|
||||||
}
|
}
|
||||||
|
@ -391,6 +394,19 @@ u16 ATA::Read(u32 addr, int width)
|
||||||
|
|
||||||
if (GetSelectedDevice() != 0)
|
if (GetSelectedDevice() != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// When an error occurs, the seek bit shall not be changed until the Status Register is read, after which the bit then indicates the current Seek status.
|
||||||
|
// This handles reporting the locked value, and then unlocking if read form STATUS rather then ALT_STATUS.
|
||||||
|
// locking is performed where the errror occurs, by setting regStatusSeekLock to either 1 or -1 based on the locked SEEK value.
|
||||||
|
if (regStatusSeekLock != 0)
|
||||||
|
{
|
||||||
|
u8 hard = (regStatus & ~ATA_STAT_SEEK);
|
||||||
|
hard |= (regStatusSeekLock > 0) ? ATA_STAT_SEEK : static_cast<u8>(0);
|
||||||
|
if (addr == ATA_R_STATUS)
|
||||||
|
regStatusSeekLock = 0;
|
||||||
|
return hard;
|
||||||
|
}
|
||||||
|
|
||||||
return regStatus;
|
return regStatus;
|
||||||
default:
|
default:
|
||||||
Console.Error("DEV9: ATA: Unknown %dbit read at address %x", width, addr);
|
Console.Error("DEV9: ATA: Unknown %dbit read at address %x", width, addr);
|
||||||
|
|
|
@ -482,9 +482,12 @@ bool ATA::HDD_CanAssessOrSetError()
|
||||||
regError |= static_cast<u8>(ATA_ERR_ID);
|
regError |= static_cast<u8>(ATA_ERR_ID);
|
||||||
if (nsector == -1)
|
if (nsector == -1)
|
||||||
{
|
{
|
||||||
|
regStatus &= ~ATA_STAT_SEEK;
|
||||||
|
regStatusSeekLock = -1;
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
regStatusSeekLock = 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,15 +137,19 @@ void ATA::HDD_ReadDMA(bool isLBA48)
|
||||||
|
|
||||||
IDE_CmdLBA48Transform(isLBA48);
|
IDE_CmdLBA48Transform(isLBA48);
|
||||||
|
|
||||||
|
regStatus &= ~ATA_STAT_SEEK;
|
||||||
if (!HDD_CanSeek())
|
if (!HDD_CanSeek())
|
||||||
{
|
{
|
||||||
Console.Error("DEV9: ATA: Transfer from invalid LBA %lu", HDD_GetLBA());
|
Console.Error("DEV9: ATA: Transfer from invalid LBA %lu", HDD_GetLBA());
|
||||||
nsector = -1;
|
nsector = -1;
|
||||||
regStatus |= ATA_STAT_ERR;
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = -1;
|
||||||
regError |= ATA_ERR_ID;
|
regError |= ATA_ERR_ID;
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
regStatus |= ATA_STAT_SEEK;
|
||||||
|
|
||||||
//Do Sync Read
|
//Do Sync Read
|
||||||
HDD_ReadSync(&ATA::DRQCmdDMADataToHost);
|
HDD_ReadSync(&ATA::DRQCmdDMADataToHost);
|
||||||
|
@ -159,15 +163,19 @@ void ATA::HDD_WriteDMA(bool isLBA48)
|
||||||
|
|
||||||
IDE_CmdLBA48Transform(isLBA48);
|
IDE_CmdLBA48Transform(isLBA48);
|
||||||
|
|
||||||
|
regStatus &= ~ATA_STAT_SEEK;
|
||||||
if (!HDD_CanSeek())
|
if (!HDD_CanSeek())
|
||||||
{
|
{
|
||||||
Console.Error("DEV9: ATA: Transfer from invalid LBA %lu", HDD_GetLBA());
|
Console.Error("DEV9: ATA: Transfer from invalid LBA %lu", HDD_GetLBA());
|
||||||
nsector = -1;
|
nsector = -1;
|
||||||
regStatus |= ATA_STAT_ERR;
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = -1;
|
||||||
regError |= ATA_ERR_ID;
|
regError |= ATA_ERR_ID;
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
regStatus |= ATA_STAT_SEEK;
|
||||||
|
|
||||||
//Do Async write
|
//Do Async write
|
||||||
DRQCmdDMADataFromHost();
|
DRQCmdDMADataFromHost();
|
||||||
|
|
|
@ -19,6 +19,7 @@ void ATA::CmdNoDataAbort()
|
||||||
|
|
||||||
regError |= ATA_ERR_ABORT;
|
regError |= ATA_ERR_ABORT;
|
||||||
regStatus |= ATA_STAT_ERR;
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = (regStatus & ATA_STAT_SEEK) ? 1 : -1;
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +31,14 @@ void ATA::HDD_FlushCache() //Can't when DRQ set
|
||||||
return;
|
return;
|
||||||
DevCon.WriteLn("DEV9: HDD_FlushCache");
|
DevCon.WriteLn("DEV9: HDD_FlushCache");
|
||||||
|
|
||||||
awaitFlush = true;
|
if (!writeQueue.IsQueueEmpty())
|
||||||
Async(-1);
|
{
|
||||||
|
regStatus |= ATA_STAT_SEEK;
|
||||||
|
awaitFlush = true;
|
||||||
|
Async(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PostCmdNoData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ATA::HDD_InitDevParameters()
|
void ATA::HDD_InitDevParameters()
|
||||||
|
@ -52,6 +59,16 @@ void ATA::HDD_ReadVerifySectors(bool isLBA48)
|
||||||
|
|
||||||
IDE_CmdLBA48Transform(isLBA48);
|
IDE_CmdLBA48Transform(isLBA48);
|
||||||
|
|
||||||
|
regStatus &= ~ATA_STAT_SEEK;
|
||||||
|
if (!HDD_CanSeek())
|
||||||
|
{
|
||||||
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = -1;
|
||||||
|
regError |= ATA_ERR_TRACK0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
regStatus |= ATA_STAT_SEEK;
|
||||||
|
|
||||||
HDD_CanAssessOrSetError();
|
HDD_CanAssessOrSetError();
|
||||||
|
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
|
@ -84,12 +101,12 @@ void ATA::HDD_SeekCmd()
|
||||||
return;
|
return;
|
||||||
DevCon.WriteLn("DEV9: HDD_SeekCmd");
|
DevCon.WriteLn("DEV9: HDD_SeekCmd");
|
||||||
|
|
||||||
regStatus &= ~ATA_STAT_SEEK;
|
|
||||||
|
|
||||||
lba48 = false;
|
lba48 = false;
|
||||||
|
regStatus &= ~ATA_STAT_SEEK;
|
||||||
if (HDD_CanSeek())
|
if (HDD_CanSeek())
|
||||||
{
|
{
|
||||||
regStatus |= ATA_STAT_ERR;
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = -1;
|
||||||
regError |= ATA_ERR_ID;
|
regError |= ATA_ERR_ID;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -184,6 +201,7 @@ void ATA::HDD_Nop()
|
||||||
//Always ends in error
|
//Always ends in error
|
||||||
regError |= ATA_ERR_ABORT;
|
regError |= ATA_ERR_ABORT;
|
||||||
regStatus |= ATA_STAT_ERR;
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = (regStatus & ATA_STAT_SEEK) ? 1 : -1;
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,13 +97,17 @@ void ATA::HDD_ReadPIO(bool isLBA48)
|
||||||
|
|
||||||
IDE_CmdLBA48Transform(isLBA48);
|
IDE_CmdLBA48Transform(isLBA48);
|
||||||
|
|
||||||
|
regStatus &= ~ATA_STAT_SEEK;
|
||||||
if (!HDD_CanSeek())
|
if (!HDD_CanSeek())
|
||||||
{
|
{
|
||||||
regStatus |= ATA_STAT_ERR;
|
regStatus |= ATA_STAT_ERR;
|
||||||
|
regStatusSeekLock = -1;
|
||||||
regError |= ATA_ERR_ID;
|
regError |= ATA_ERR_ID;
|
||||||
PostCmdNoData();
|
PostCmdNoData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
regStatus |= ATA_STAT_SEEK;
|
||||||
|
|
||||||
HDD_ReadSync(&ATA::HDD_ReadPIOS2);
|
HDD_ReadSync(&ATA::HDD_ReadPIOS2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,8 +142,6 @@ bool ATA::PreCmd()
|
||||||
regStatus &= ~ATA_STAT_DRQ;
|
regStatus &= ~ATA_STAT_DRQ;
|
||||||
regStatus &= ~ATA_STAT_ERR;
|
regStatus &= ~ATA_STAT_ERR;
|
||||||
|
|
||||||
regStatus &= ~ATA_STAT_SEEK;
|
|
||||||
|
|
||||||
regError = 0;
|
regError = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue