[Disk] Put Mecha Interrupt management in DiskCommand(), delay seek times
This commit is contained in:
parent
0512e7199a
commit
b428c14a27
|
@ -62,23 +62,28 @@ void DiskCommand()
|
||||||
uint8_t second = (uint8_t)(((result.tm_sec / 10) << 4) | (result.tm_sec % 10));
|
uint8_t second = (uint8_t)(((result.tm_sec / 10) << 4) | (result.tm_sec % 10));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Used for seek times
|
||||||
|
bool isSeek = false;
|
||||||
|
|
||||||
switch (cmd & 0xFFFF0000)
|
switch (cmd & 0xFFFF0000)
|
||||||
{
|
{
|
||||||
case 0x00010000:
|
case 0x00010000:
|
||||||
//Seek Read
|
//Seek Read
|
||||||
g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000;
|
g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000;
|
||||||
dd_write = false;
|
dd_write = false;
|
||||||
|
isSeek = true;
|
||||||
break;
|
break;
|
||||||
case 0x00020000:
|
case 0x00020000:
|
||||||
//Seek Write
|
//Seek Write
|
||||||
g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000;
|
g_Reg->ASIC_CUR_TK = g_Reg->ASIC_DATA | 0x60000000;
|
||||||
dd_write = true;
|
dd_write = true;
|
||||||
|
isSeek = true;
|
||||||
break;
|
break;
|
||||||
case 0x00080000:
|
case 0x00080000:
|
||||||
//Unset Disk Changed Bit
|
//Unset Disk Changed Bit
|
||||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; break;
|
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG; break;
|
||||||
case 0x00090000:
|
case 0x00090000:
|
||||||
//Unset Reset Bit
|
//Unset Reset & Disk Changed bit Bit
|
||||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE;
|
g_Reg->ASIC_STATUS &= ~DD_STATUS_RST_STATE;
|
||||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG;
|
g_Reg->ASIC_STATUS &= ~DD_STATUS_DISK_CHNG;
|
||||||
//F-Zero X + Expansion Kit fix so it doesn't enable "swapping" at boot
|
//F-Zero X + Expansion Kit fix so it doesn't enable "swapping" at boot
|
||||||
|
@ -99,6 +104,19 @@ void DiskCommand()
|
||||||
//Disk Inquiry
|
//Disk Inquiry
|
||||||
g_Reg->ASIC_DATA = 0x00000000; break;
|
g_Reg->ASIC_DATA = 0x00000000; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSeek)
|
||||||
|
{
|
||||||
|
//Emulate Seek Times, send interrupt later
|
||||||
|
g_SystemTimer->SetTimer(g_SystemTimer->DDSeekTimer, 0x400000, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Other commands are basically instant
|
||||||
|
g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT;
|
||||||
|
g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3;
|
||||||
|
g_Reg->CheckInterrupts();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskReset(void)
|
void DiskReset(void)
|
||||||
|
@ -157,6 +175,9 @@ void DiskBMControl(void)
|
||||||
|
|
||||||
void DiskGapSectorCheck()
|
void DiskGapSectorCheck()
|
||||||
{
|
{
|
||||||
|
//On 64DD Status Register Read
|
||||||
|
|
||||||
|
//Buffer Manager Interrupt, Gap Sector Check
|
||||||
if (g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)
|
if (g_Reg->ASIC_STATUS & DD_STATUS_BM_INT)
|
||||||
{
|
{
|
||||||
if (SECTORS_PER_BLOCK < dd_current)
|
if (SECTORS_PER_BLOCK < dd_current)
|
||||||
|
@ -168,6 +189,7 @@ void DiskGapSectorCheck()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Delay Disk Swapping by removing the disk for a certain amount of time, then insert the newly loaded disk (after 50 Status Register reads, here).
|
||||||
if (!(g_Reg->ASIC_STATUS & DD_STATUS_DISK_PRES) && g_Disk != NULL && g_Settings->LoadBool(GameRunning_LoadingInProgress) == false)
|
if (!(g_Reg->ASIC_STATUS & DD_STATUS_DISK_PRES) && g_Disk != NULL && g_Settings->LoadBool(GameRunning_LoadingInProgress) == false)
|
||||||
{
|
{
|
||||||
dd_swapdelay++;
|
dd_swapdelay++;
|
||||||
|
@ -190,12 +212,14 @@ void DiskBMUpdate()
|
||||||
//Write Data
|
//Write Data
|
||||||
if (dd_current < SECTORS_PER_BLOCK)
|
if (dd_current < SECTORS_PER_BLOCK)
|
||||||
{
|
{
|
||||||
|
//User Sector
|
||||||
if (!DiskBMReadWrite(true))
|
if (!DiskBMReadWrite(true))
|
||||||
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
|
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
|
||||||
dd_current += 1;
|
dd_current += 1;
|
||||||
}
|
}
|
||||||
else if (dd_current < SECTORS_PER_BLOCK + 1)
|
else if (dd_current < SECTORS_PER_BLOCK + 1)
|
||||||
{
|
{
|
||||||
|
//C2 Sector
|
||||||
if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK)
|
if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK)
|
||||||
{
|
{
|
||||||
dd_start_block = 1 - dd_start_block;
|
dd_start_block = 1 - dd_start_block;
|
||||||
|
@ -222,25 +246,27 @@ void DiskBMUpdate()
|
||||||
//Read Data
|
//Read Data
|
||||||
if (((g_Reg->ASIC_CUR_TK >> 16) & 0x1FFF) == 6 && g_Reg->ASIC_CUR_SECTOR == 0 && g_Disk->GetCountry() != Country::UnknownCountry)
|
if (((g_Reg->ASIC_CUR_TK >> 16) & 0x1FFF) == 6 && g_Reg->ASIC_CUR_SECTOR == 0 && g_Disk->GetCountry() != Country::UnknownCountry)
|
||||||
{
|
{
|
||||||
//Copy Protection
|
//Copy Protection if Retail Disk
|
||||||
g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ;
|
g_Reg->ASIC_STATUS &= ~DD_STATUS_DATA_RQ;
|
||||||
g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO;
|
g_Reg->ASIC_BM_STATUS |= DD_BM_STATUS_MICRO;
|
||||||
}
|
}
|
||||||
else if (dd_current < SECTORS_PER_BLOCK)
|
else if (dd_current < SECTORS_PER_BLOCK)
|
||||||
{
|
{
|
||||||
|
//User Sector
|
||||||
if (!DiskBMReadWrite(false))
|
if (!DiskBMReadWrite(false))
|
||||||
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
|
g_Reg->ASIC_STATUS |= DD_STATUS_DATA_RQ;
|
||||||
dd_current += 1;
|
dd_current += 1;
|
||||||
}
|
}
|
||||||
else if (dd_current < SECTORS_PER_BLOCK + 4)
|
else if (dd_current < SECTORS_PER_BLOCK + 4)
|
||||||
{
|
{
|
||||||
//READ C2 (00!)
|
//C2 sectors (All 00s)
|
||||||
dd_current += 1;
|
dd_current += 1;
|
||||||
if (dd_current == SECTORS_PER_BLOCK + 4)
|
if (dd_current == SECTORS_PER_BLOCK + 4)
|
||||||
g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER;
|
g_Reg->ASIC_STATUS |= DD_STATUS_C2_XFER;
|
||||||
}
|
}
|
||||||
else if (dd_current == SECTORS_PER_BLOCK + 4)
|
else if (dd_current == SECTORS_PER_BLOCK + 4)
|
||||||
{
|
{
|
||||||
|
//Gap Sector
|
||||||
if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK)
|
if (g_Reg->ASIC_BM_STATUS & DD_BM_STATUS_BLOCK)
|
||||||
{
|
{
|
||||||
dd_start_block = 1 - dd_start_block;
|
dd_start_block = 1 - dd_start_block;
|
||||||
|
|
|
@ -2157,9 +2157,6 @@ void CMipsMemoryVM::Write32CartridgeDomain2Address1(void)
|
||||||
case 0x05000508:
|
case 0x05000508:
|
||||||
g_Reg->ASIC_CMD = m_MemLookupValue.UW[0];
|
g_Reg->ASIC_CMD = m_MemLookupValue.UW[0];
|
||||||
DiskCommand();
|
DiskCommand();
|
||||||
g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT;
|
|
||||||
g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3;
|
|
||||||
g_Reg->CheckInterrupts();
|
|
||||||
break;
|
break;
|
||||||
case 0x05000510:
|
case 0x05000510:
|
||||||
//ASIC_BM_STATUS_CTL
|
//ASIC_BM_STATUS_CTL
|
||||||
|
|
|
@ -221,6 +221,16 @@ void CSystemTimer::TimerDone()
|
||||||
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
||||||
m_Reg.CheckInterrupts();
|
m_Reg.CheckInterrupts();
|
||||||
break;
|
break;
|
||||||
|
case CSystemTimer::DDSeekTimer:
|
||||||
|
g_SystemTimer->StopTimer(CSystemTimer::DDSeekTimer);
|
||||||
|
g_Reg->ASIC_STATUS |= DD_STATUS_MECHA_INT;
|
||||||
|
g_Reg->FAKE_CAUSE_REGISTER |= CAUSE_IP3;
|
||||||
|
g_Reg->CheckInterrupts();
|
||||||
|
break;
|
||||||
|
case CSystemTimer::DDMotorTimer:
|
||||||
|
g_SystemTimer->StopTimer(CSystemTimer::DDMotorTimer);
|
||||||
|
g_Reg->ASIC_STATUS &= ~DD_STATUS_MTR_N_SPIN;
|
||||||
|
break;
|
||||||
case CSystemTimer::ViTimer:
|
case CSystemTimer::ViTimer:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,8 @@ public:
|
||||||
RspTimer,
|
RspTimer,
|
||||||
RSPTimerDlist,
|
RSPTimerDlist,
|
||||||
DDPiTimer,
|
DDPiTimer,
|
||||||
|
DDSeekTimer,
|
||||||
|
DDMotorTimer,
|
||||||
MaxTimer
|
MaxTimer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11783,18 +11783,6 @@ void CX86RecompilerOps::SW_Register(x86Reg Reg, uint32_t VAddr)
|
||||||
MoveX86regToVariable(Reg, &g_Reg->ASIC_CMD, "ASIC_CMD");
|
MoveX86regToVariable(Reg, &g_Reg->ASIC_CMD, "ASIC_CMD");
|
||||||
m_RegWorkingSet.BeforeCallDirect();
|
m_RegWorkingSet.BeforeCallDirect();
|
||||||
Call_Direct(AddressOf(&DiskCommand), "DiskCommand");
|
Call_Direct(AddressOf(&DiskCommand), "DiskCommand");
|
||||||
m_RegWorkingSet.AfterCallDirect();
|
|
||||||
OrConstToVariable((uint32_t)DD_STATUS_MECHA_INT, &g_Reg->ASIC_STATUS, "ASIC_STATUS");
|
|
||||||
OrConstToVariable((uint32_t)CAUSE_IP3, &g_Reg->FAKE_CAUSE_REGISTER, "FAKE_CAUSE_REGISTER");
|
|
||||||
m_RegWorkingSet.BeforeCallDirect();
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
MoveConstToX86reg((uint32_t)g_Reg, x86_ECX);
|
|
||||||
Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts");
|
|
||||||
#else
|
|
||||||
PushImm32((uint32_t)g_Reg);
|
|
||||||
Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts");
|
|
||||||
AddConstToX86Reg(x86_ESP, 4);
|
|
||||||
#endif
|
|
||||||
m_RegWorkingSet.AfterCallDirect();
|
m_RegWorkingSet.AfterCallDirect();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue