diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index 86d7fde61..26d62defa 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -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()) @@ -366,9 +362,63 @@ void CDMA::PI_DMA_WRITE() g_Reg->PI_CART_ADDR_REG -= 0x10000000; if (g_Reg->PI_CART_ADDR_REG + PI_WR_LEN_REG < g_Rom->GetRomSize()) { - for (i = 0; i < PI_WR_LEN_REG; i++) + 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) { - *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((g_Reg->PI_CART_ADDR_REG + i) ^ 3)); + 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++) + { + *(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()) diff --git a/Source/Project64-core/N64System/Mips/RegisterClass.cpp b/Source/Project64-core/N64System/Mips/RegisterClass.cpp index f0283f6d3..aac7e23a9 100644 --- a/Source/Project64-core/N64System/Mips/RegisterClass.cpp +++ b/Source/Project64-core/N64System/Mips/RegisterClass.cpp @@ -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) { diff --git a/Source/Project64-core/N64System/Mips/SystemTiming.cpp b/Source/Project64-core/N64System/Mips/SystemTiming.cpp index 7a749bcc4..22db902b9 100644 --- a/Source/Project64-core/N64System/Mips/SystemTiming.cpp +++ b/Source/Project64-core/N64System/Mips/SystemTiming.cpp @@ -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;