Merge pull request #991 from LegendOfDragoon/master

Optimize CheckInterrupts, PI_DMA_WRITE, and UpdateTimers
This commit is contained in:
zilmar 2016-05-23 14:36:44 +10:00
commit f447e81248
3 changed files with 73 additions and 23 deletions

View File

@ -198,12 +198,8 @@ void CDMA::PI_DMA_READ()
void CDMA::PI_DMA_WRITE()
{
uint32_t PI_WR_LEN_REG = ((g_Reg->PI_WR_LEN_REG) & 0x00FFFFFFul) + 1;
if ((PI_WR_LEN_REG & 1) != 0)
{
PI_WR_LEN_REG += 1; /* fixes AI Shougi 3, Doraemon 3, etc. */
}
uint32_t PI_WR_LEN_REG = ((g_Reg->PI_WR_LEN_REG) & 0x00FFFFFEul) + 2;
/* rounding PI_WR_LEN_REG up to the nearest even number fixes AI Shougi 3, Doraemon 3, etc. */
g_Reg->PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
if (g_Reg->PI_DRAM_ADDR_REG + PI_WR_LEN_REG > g_MMU->RdramSize())
@ -365,10 +361,64 @@ void CDMA::PI_DMA_WRITE()
uint8_t * RDRAM = g_MMU->Rdram();
g_Reg->PI_CART_ADDR_REG -= 0x10000000;
if (g_Reg->PI_CART_ADDR_REG + PI_WR_LEN_REG < g_Rom->GetRomSize())
{
size_t alignment;
RDRAM += g_Reg->PI_DRAM_ADDR_REG;
ROM += g_Reg->PI_CART_ADDR_REG;
alignment = PI_WR_LEN_REG | (size_t)RDRAM | (size_t)ROM;
if ((alignment & 0x3) == 0)
{
for (i = 0; i < PI_WR_LEN_REG; i += 4)
{
*(uint32_t *)(RDRAM + i) = *(uint32_t *)(ROM + i);
}
}
else if ((alignment & 1) == 0)
{
if ((PI_WR_LEN_REG & 2) == 0)
{
if (((size_t)RDRAM & 2) == 0)
{
for (i = 0; i < PI_WR_LEN_REG; i += 4)
{
*(uint16_t *)(((size_t)RDRAM + i) + 2) = *(uint16_t *)(((size_t)ROM + i) - 2);
*(uint16_t *)(((size_t)RDRAM + i) + 0) = *(uint16_t *)(((size_t)ROM + i) + 4);
}
}
else
{
if (((size_t)ROM & 2) == 0)
{
for (i = 0; i < PI_WR_LEN_REG; i += 4)
{
*(uint16_t *)(((size_t)RDRAM + i) - 2) = *(uint16_t *)(((size_t)ROM + i) + 2);
*(uint16_t *)(((size_t)RDRAM + i) + 4) = *(uint16_t *)(((size_t)ROM + i) + 0);
}
}
else
{
for (i = 0; i < PI_WR_LEN_REG; i += 4)
{
*(uint16_t *)(((size_t)RDRAM + i) - 2) = *(uint16_t *)(((size_t)ROM + i) - 2);
*(uint16_t *)(((size_t)RDRAM + i) + 4) = *(uint16_t *)(((size_t)ROM + i) + 4);
}
}
}
}
else
{
for (i = 0; i < PI_WR_LEN_REG; i += 2)
{
*(uint16_t *)(((size_t)RDRAM + i) ^ 2) = *(uint16_t *)(((size_t)ROM + i) ^ 2);
}
}
}
else
{
for (i = 0; i < PI_WR_LEN_REG; i++)
{
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((g_Reg->PI_CART_ADDR_REG + i) ^ 3));
*(uint8_t *)(((size_t)RDRAM + i) ^ 3) = *(uint8_t *)(((size_t)ROM + i) ^ 3);
}
}
}
else if (g_Reg->PI_CART_ADDR_REG >= g_Rom->GetRomSize())

View File

@ -307,14 +307,15 @@ void CRegisters::SetAsCurrentSystem()
void CRegisters::CheckInterrupts()
{
uint32_t mi_intr_reg = MI_INTR_REG, status_register;
if (!m_System->bFixedAudio() && CpuType() != CPU_SyncCores)
{
MI_INTR_REG &= ~MI_INTR_AI;
MI_INTR_REG |= (m_AudioIntrReg & MI_INTR_AI);
mi_intr_reg &= ~MI_INTR_AI;
mi_intr_reg |= (m_AudioIntrReg & MI_INTR_AI);
}
MI_INTR_REG |= (m_RspIntrReg & MI_INTR_SP);
MI_INTR_REG |= (m_GfxIntrReg & MI_INTR_DP);
if ((MI_INTR_MASK_REG & MI_INTR_REG) != 0)
mi_intr_reg |= (m_RspIntrReg & MI_INTR_SP);
mi_intr_reg |= (m_GfxIntrReg & MI_INTR_DP);
if ((MI_INTR_MASK_REG & mi_intr_reg) != 0)
{
FAKE_CAUSE_REGISTER |= CAUSE_IP2;
}
@ -322,21 +323,23 @@ void CRegisters::CheckInterrupts()
{
FAKE_CAUSE_REGISTER &= ~CAUSE_IP2;
}
MI_INTR_REG = mi_intr_reg;
status_register = STATUS_REGISTER;
if ((STATUS_REGISTER & STATUS_IE) == 0)
if ((status_register & STATUS_IE) == 0)
{
return;
}
if ((STATUS_REGISTER & STATUS_EXL) != 0)
if ((status_register & STATUS_EXL) != 0)
{
return;
}
if ((STATUS_REGISTER & STATUS_ERL) != 0)
if ((status_register & STATUS_ERL) != 0)
{
return;
}
if ((STATUS_REGISTER & FAKE_CAUSE_REGISTER & 0xFF00) != 0)
if ((status_register & FAKE_CAUSE_REGISTER & 0xFF00) != 0)
{
if (m_FirstInterupt)
{

View File

@ -161,12 +161,12 @@ void CSystemTimer::UpdateTimers()
int TimeTaken = m_LastUpdate - m_NextTimer;
if (TimeTaken != 0)
{
uint32_t random, wired;
int32_t random, wired;
m_LastUpdate = m_NextTimer;
g_Reg->COUNT_REGISTER += TimeTaken;
random = g_Reg->RANDOM_REGISTER - (TimeTaken / g_System->CountPerOp());
wired = g_Reg->WIRED_REGISTER;
if ((int)random < (int)wired)
if (random < wired)
{
if (wired == 0)
{
@ -175,10 +175,7 @@ void CSystemTimer::UpdateTimers()
else
{
uint32_t increment = 32 - wired;
do
{
random += increment;
} while ((int)random < (int)wired);
random += ((wired - random + increment - 1) / increment) * increment;
}
}
g_Reg->RANDOM_REGISTER = random;