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 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;
|
||||
|
||||
|
|
|
@ -317,6 +317,9 @@ void ATA::ResetEnd(bool hard)
|
|||
mdmaMode = 2;
|
||||
}
|
||||
|
||||
regStatus |= ATA_STAT_SEEK;
|
||||
regStatusSeekLock = 0;
|
||||
|
||||
HDD_ExecuteDeviceDiag(false);
|
||||
regControlEnableIRQ = false;
|
||||
}
|
||||
|
@ -391,6 +394,19 @@ u16 ATA::Read(u32 addr, int width)
|
|||
|
||||
if (GetSelectedDevice() != 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;
|
||||
default:
|
||||
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);
|
||||
if (nsector == -1)
|
||||
{
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
regStatusSeekLock = -1;
|
||||
PostCmdNoData();
|
||||
return false;
|
||||
}
|
||||
regStatusSeekLock = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -137,15 +137,19 @@ void ATA::HDD_ReadDMA(bool isLBA48)
|
|||
|
||||
IDE_CmdLBA48Transform(isLBA48);
|
||||
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
if (!HDD_CanSeek())
|
||||
{
|
||||
Console.Error("DEV9: ATA: Transfer from invalid LBA %lu", HDD_GetLBA());
|
||||
nsector = -1;
|
||||
regStatus |= ATA_STAT_ERR;
|
||||
regStatusSeekLock = -1;
|
||||
regError |= ATA_ERR_ID;
|
||||
PostCmdNoData();
|
||||
return;
|
||||
}
|
||||
else
|
||||
regStatus |= ATA_STAT_SEEK;
|
||||
|
||||
//Do Sync Read
|
||||
HDD_ReadSync(&ATA::DRQCmdDMADataToHost);
|
||||
|
@ -159,15 +163,19 @@ void ATA::HDD_WriteDMA(bool isLBA48)
|
|||
|
||||
IDE_CmdLBA48Transform(isLBA48);
|
||||
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
if (!HDD_CanSeek())
|
||||
{
|
||||
Console.Error("DEV9: ATA: Transfer from invalid LBA %lu", HDD_GetLBA());
|
||||
nsector = -1;
|
||||
regStatus |= ATA_STAT_ERR;
|
||||
regStatusSeekLock = -1;
|
||||
regError |= ATA_ERR_ID;
|
||||
PostCmdNoData();
|
||||
return;
|
||||
}
|
||||
else
|
||||
regStatus |= ATA_STAT_SEEK;
|
||||
|
||||
//Do Async write
|
||||
DRQCmdDMADataFromHost();
|
||||
|
|
|
@ -19,6 +19,7 @@ void ATA::CmdNoDataAbort()
|
|||
|
||||
regError |= ATA_ERR_ABORT;
|
||||
regStatus |= ATA_STAT_ERR;
|
||||
regStatusSeekLock = (regStatus & ATA_STAT_SEEK) ? 1 : -1;
|
||||
PostCmdNoData();
|
||||
}
|
||||
|
||||
|
@ -30,8 +31,14 @@ void ATA::HDD_FlushCache() //Can't when DRQ set
|
|||
return;
|
||||
DevCon.WriteLn("DEV9: HDD_FlushCache");
|
||||
|
||||
awaitFlush = true;
|
||||
Async(-1);
|
||||
if (!writeQueue.IsQueueEmpty())
|
||||
{
|
||||
regStatus |= ATA_STAT_SEEK;
|
||||
awaitFlush = true;
|
||||
Async(-1);
|
||||
}
|
||||
else
|
||||
PostCmdNoData();
|
||||
}
|
||||
|
||||
void ATA::HDD_InitDevParameters()
|
||||
|
@ -52,6 +59,16 @@ void ATA::HDD_ReadVerifySectors(bool 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();
|
||||
|
||||
PostCmdNoData();
|
||||
|
@ -84,12 +101,12 @@ void ATA::HDD_SeekCmd()
|
|||
return;
|
||||
DevCon.WriteLn("DEV9: HDD_SeekCmd");
|
||||
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
|
||||
lba48 = false;
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
if (HDD_CanSeek())
|
||||
{
|
||||
regStatus |= ATA_STAT_ERR;
|
||||
regStatusSeekLock = -1;
|
||||
regError |= ATA_ERR_ID;
|
||||
}
|
||||
else
|
||||
|
@ -184,6 +201,7 @@ void ATA::HDD_Nop()
|
|||
//Always ends in error
|
||||
regError |= ATA_ERR_ABORT;
|
||||
regStatus |= ATA_STAT_ERR;
|
||||
regStatusSeekLock = (regStatus & ATA_STAT_SEEK) ? 1 : -1;
|
||||
PostCmdNoData();
|
||||
}
|
||||
|
||||
|
|
|
@ -97,13 +97,17 @@ void ATA::HDD_ReadPIO(bool isLBA48)
|
|||
|
||||
IDE_CmdLBA48Transform(isLBA48);
|
||||
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
if (!HDD_CanSeek())
|
||||
{
|
||||
regStatus |= ATA_STAT_ERR;
|
||||
regStatusSeekLock = -1;
|
||||
regError |= ATA_ERR_ID;
|
||||
PostCmdNoData();
|
||||
return;
|
||||
}
|
||||
else
|
||||
regStatus |= ATA_STAT_SEEK;
|
||||
|
||||
HDD_ReadSync(&ATA::HDD_ReadPIOS2);
|
||||
}
|
||||
|
|
|
@ -142,8 +142,6 @@ bool ATA::PreCmd()
|
|||
regStatus &= ~ATA_STAT_DRQ;
|
||||
regStatus &= ~ATA_STAT_ERR;
|
||||
|
||||
regStatus &= ~ATA_STAT_SEEK;
|
||||
|
||||
regError = 0;
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue