diff --git a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp index c821804aa..9ae617734 100644 --- a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp +++ b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.cpp @@ -102,7 +102,7 @@ bool SPRegistersHandler::Write32(uint32_t Address, uint32_t Value, uint32_t Mask case 0x04040004: SP_DRAM_ADDR_REG = (SP_DRAM_ADDR_REG & ~Mask) | (MaskedValue); break; case 0x04040008: SP_RD_LEN_REG = (SP_RD_LEN_REG & ~Mask) | (MaskedValue); - m_MMU.SP_DMA_READ(); + SP_DMA_READ(); break; case 0x0404000C: SP_WR_LEN_REG = (SP_WR_LEN_REG & ~Mask) | (MaskedValue); @@ -156,3 +156,47 @@ bool SPRegistersHandler::Write32(uint32_t Address, uint32_t Value, uint32_t Mask } return true; } + +void SPRegistersHandler::SP_DMA_READ() +{ + SP_DRAM_ADDR_REG &= 0x1FFFFFFF; + + if (SP_DRAM_ADDR_REG > m_MMU.RdramSize()) + { + if (HaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("%s\nSP_DRAM_ADDR_REG not in RDRAM space: % 08X", __FUNCTION__, g_Reg->SP_DRAM_ADDR_REG).c_str()); + } + SP_DMA_BUSY_REG = 0; + SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; + return; + } + + if (SP_RD_LEN_REG + 1 + (SP_MEM_ADDR_REG & 0xFFF) > 0x1000) + { + if (HaveDebugger()) + { + g_Notify->DisplayError(stdstr_f("%s\nCould not fit copy in memory segment", __FUNCTION__).c_str()); + } + return; + } + + if ((SP_MEM_ADDR_REG & 3) != 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if ((SP_DRAM_ADDR_REG & 3) != 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + if (((SP_RD_LEN_REG + 1) & 3) != 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + memcpy(m_MMU.Dmem() + (SP_MEM_ADDR_REG & 0x1FFF), m_MMU.Rdram() + SP_DRAM_ADDR_REG, SP_RD_LEN_REG + 1); + + SP_DMA_BUSY_REG = 0; + SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; +} + diff --git a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h index 23a4ea727..cb8eb74e5 100644 --- a/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h +++ b/Source/Project64-core/N64System/MemoryHandler/SPRegistersHandler.h @@ -49,6 +49,8 @@ private: SPRegistersHandler(const SPRegistersHandler &); SPRegistersHandler & operator=(const SPRegistersHandler &); + void SP_DMA_READ(); + CN64System & m_System; CMipsMemoryVM & m_MMU; CRegisters & m_Reg; diff --git a/Source/Project64-core/N64System/Mips/Dma.cpp b/Source/Project64-core/N64System/Mips/Dma.cpp index ac100a575..b96358b2e 100644 --- a/Source/Project64-core/N64System/Mips/Dma.cpp +++ b/Source/Project64-core/N64System/Mips/Dma.cpp @@ -477,50 +477,6 @@ void CDMA::PI_DMA_WRITE() g_Reg->CheckInterrupts(); } -void CDMA::SP_DMA_READ() -{ - g_Reg->SP_DRAM_ADDR_REG &= 0x1FFFFFFF; - - if (g_Reg->SP_DRAM_ADDR_REG > g_MMU->RdramSize()) - { - if (HaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("%s\nSP_DRAM_ADDR_REG not in RDRAM space: % 08X", __FUNCTION__, g_Reg->SP_DRAM_ADDR_REG).c_str()); - } - g_Reg->SP_DMA_BUSY_REG = 0; - g_Reg->SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; - return; - } - - if (g_Reg->SP_RD_LEN_REG + 1 + (g_Reg->SP_MEM_ADDR_REG & 0xFFF) > 0x1000) - { - if (HaveDebugger()) - { - g_Notify->DisplayError(stdstr_f("%s\nCould not fit copy in memory segment",__FUNCTION__).c_str()); - } - return; - } - - if ((g_Reg->SP_MEM_ADDR_REG & 3) != 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if ((g_Reg->SP_DRAM_ADDR_REG & 3) != 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - if (((g_Reg->SP_RD_LEN_REG + 1) & 3) != 0) - { - g_Notify->BreakPoint(__FILE__, __LINE__); - } - - memcpy(g_MMU->Dmem() + (g_Reg->SP_MEM_ADDR_REG & 0x1FFF), g_MMU->Rdram() + g_Reg->SP_DRAM_ADDR_REG, - g_Reg->SP_RD_LEN_REG + 1); - - g_Reg->SP_DMA_BUSY_REG = 0; - g_Reg->SP_STATUS_REG &= ~SP_STATUS_DMA_BUSY; -} - void CDMA::SP_DMA_WRITE() { if (g_Reg->SP_DRAM_ADDR_REG > g_MMU->RdramSize()) diff --git a/Source/Project64-core/N64System/Mips/Dma.h b/Source/Project64-core/N64System/Mips/Dma.h index 034db1bf2..feed998b4 100644 --- a/Source/Project64-core/N64System/Mips/Dma.h +++ b/Source/Project64-core/N64System/Mips/Dma.h @@ -9,7 +9,6 @@ class CDMA : CDMA(); public: - void SP_DMA_READ(); void SP_DMA_WRITE(); void PI_DMA_READ(); void PI_DMA_WRITE(); diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index 089bd73ce..f86732311 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -6072,10 +6072,12 @@ void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr) case 0x04040000: MoveConstToVariable(Value, &g_Reg->SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); break; case 0x04040004: MoveConstToVariable(Value, &g_Reg->SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); break; case 0x04040008: - MoveConstToVariable(Value, &g_Reg->SP_RD_LEN_REG, "SP_RD_LEN_REG"); m_RegWorkingSet.BeforeCallDirect(); - MoveConstToArmReg(Arm_R0, (uint32_t)((CDMA *)g_MMU), "(CDMA *)g_MMU"); - CallFunction(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); + PushImm32(0xFFFFFFFF); + PushImm32(Value); + PushImm32(PAddr & 0x1FFFFFFF); + MoveConstToArmReg(Arm_R0, (uint32_t)(MemoryHandler *)&g_MMU->m_SPRegistersHandler, "(MemoryHandler *)g_MMU->m_SPRegistersHandler"); + CallFunction((void *)((long**)(MemoryHandler *)&g_MMU->m_SPRegistersHandler)[0][1], "SPRegistersHandler::Write32"); m_RegWorkingSet.AfterCallDirect(); break; case 0x04040010: @@ -6573,10 +6575,12 @@ void CArmRecompilerOps::SW_Register(ArmReg Reg, uint32_t VAddr) case 0x04040000: MoveArmRegToVariable(Reg, &g_Reg->SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); break; case 0x04040004: MoveArmRegToVariable(Reg, &g_Reg->SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); break; case 0x04040008: - MoveArmRegToVariable(Reg, &g_Reg->SP_RD_LEN_REG, "SP_RD_LEN_REG"); m_RegWorkingSet.BeforeCallDirect(); - MoveConstToArmReg(Arm_R0, (uint32_t)((CDMA *)g_MMU), "(CDMA *)g_MMU"); - CallFunction(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); + PushImm32(0xFFFFFFFF); + Push(Reg); + PushImm32(PAddr & 0x1FFFFFFF); + MoveConstToArmReg(Arm_R0, (uint32_t)(MemoryHandler *)&g_MMU->m_SPRegistersHandler, "(MemoryHandler *)g_MMU->m_SPRegistersHandler"); + CallFunction((void *)((long**)(MemoryHandler *)&g_MMU->m_SPRegistersHandler)[0][1], "SPRegistersHandler::Write32"); m_RegWorkingSet.AfterCallDirect(); break; case 0x0404000C: diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp index badc7dd55..529498fe8 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp @@ -17,13 +17,13 @@ extern "C" void __clear_cache_android(uint8_t* begin, uint8_t *end); #endif CCodeBlock::CCodeBlock(uint32_t VAddrEnter, uint8_t * CompiledLocation) : -m_VAddrEnter(VAddrEnter), -m_VAddrFirst(VAddrEnter), -m_VAddrLast(VAddrEnter), -m_CompiledLocation(CompiledLocation), -m_EnterSection(nullptr), -m_RecompilerOps(nullptr), -m_Test(1) + m_VAddrEnter(VAddrEnter), + m_VAddrFirst(VAddrEnter), + m_VAddrLast(VAddrEnter), + m_CompiledLocation(CompiledLocation), + m_EnterSection(nullptr), + m_RecompilerOps(nullptr), + m_Test(1) { #if defined(__arm__) || defined(_M_ARM) // Make sure function starts at an odd address so that the system knows it is in thumb mode diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 49dd97607..fc0a04056 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -10465,15 +10465,17 @@ void CX86RecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr) case 0x04040000: MoveConstToVariable(Value, &g_Reg->SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); break; case 0x04040004: MoveConstToVariable(Value, &g_Reg->SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); break; case 0x04040008: - MoveConstToVariable(Value, &g_Reg->SP_RD_LEN_REG, "SP_RD_LEN_REG"); m_RegWorkingSet.BeforeCallDirect(); + PushImm32(0xFFFFFFFF); + PushImm32(Value); + PushImm32(PAddr & 0x1FFFFFFF); #ifdef _MSC_VER - MoveConstToX86reg((uint32_t)((CDMA *)g_MMU), x86_ECX); - Call_Direct(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); + MoveConstToX86reg((uint32_t)(MemoryHandler *)&g_MMU->m_SPRegistersHandler, x86_ECX); + Call_Direct((void *)((long**)(MemoryHandler *)&g_MMU->m_SPRegistersHandler)[0][1], "SPRegistersHandler::Write32"); #else - PushImm32((uint32_t)((CDMA *)g_MMU)); - Call_Direct(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); - AddConstToX86Reg(x86_ESP, 4); + PushImm32((uint32_t)&g_MMU->m_SPRegistersHandler); + Call_Direct(AddressOf(&SPRegistersHandler::Write32), "SPRegistersHandler::Write32"); + AddConstToX86Reg(x86_ESP, 16); #endif m_RegWorkingSet.AfterCallDirect(); break; @@ -11009,15 +11011,17 @@ void CX86RecompilerOps::SW_Register(x86Reg Reg, uint32_t VAddr) case 0x04040000: MoveX86regToVariable(Reg, &g_Reg->SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); break; case 0x04040004: MoveX86regToVariable(Reg, &g_Reg->SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); break; case 0x04040008: - MoveX86regToVariable(Reg, &g_Reg->SP_RD_LEN_REG, "SP_RD_LEN_REG"); m_RegWorkingSet.BeforeCallDirect(); + PushImm32(0xFFFFFFFF); + Push(Reg); + PushImm32(PAddr & 0x1FFFFFFF); #ifdef _MSC_VER - MoveConstToX86reg((uint32_t)((CDMA *)g_MMU), x86_ECX); - Call_Direct(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); + MoveConstToX86reg((uint32_t)(MemoryHandler *)&g_MMU->m_SPRegistersHandler, x86_ECX); + Call_Direct((void *)((long**)(MemoryHandler *)&g_MMU->m_SPRegistersHandler)[0][1], "SPRegistersHandler::Write32"); #else - PushImm32((uint32_t)((CDMA *)g_MMU)); - Call_Direct(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); - AddConstToX86Reg(x86_ESP, 4); + PushImm32((uint32_t)&g_MMU->m_SPRegistersHandler); + Call_Direct(AddressOf(&SPRegistersHandler::Write32), "SPRegistersHandler::Write32"); + AddConstToX86Reg(x86_ESP, 16); #endif m_RegWorkingSet.AfterCallDirect(); break;