diff --git a/Source/Core/Core/Src/HW/GPFifo.cpp b/Source/Core/Core/Src/HW/GPFifo.cpp index 61483a4dbc..ea3c612922 100644 --- a/Source/Core/Core/Src/HW/GPFifo.cpp +++ b/Source/Core/Core/Src/HW/GPFifo.cpp @@ -119,6 +119,13 @@ void Write32(const u32 _iValue, const u32 _iAddress) CheckGatherPipe(); } +void Write64(const u64 _iValue, const u32 _iAddress) +{ + *(u64*)(&m_gatherPipe[m_gatherPipeCount]) = Common::swap64(_iValue); + m_gatherPipeCount += 8; + CheckGatherPipe(); +} + void FastWrite8(const u8 _iValue) { m_gatherPipe[m_gatherPipeCount] = _iValue; @@ -137,6 +144,12 @@ void FastWrite32(const u32 _iValue) m_gatherPipeCount += 4; } +void FastWrite64(const u64 _iValue) +{ + *(u64*)(&m_gatherPipe[m_gatherPipeCount]) = Common::swap64(_iValue); + m_gatherPipeCount += 8; +} + void FastWriteEnd() { CheckGatherPipe(); diff --git a/Source/Core/Core/Src/HW/GPFifo.h b/Source/Core/Core/Src/HW/GPFifo.h index 248c941fdc..b282ccfad6 100644 --- a/Source/Core/Core/Src/HW/GPFifo.h +++ b/Source/Core/Core/Src/HW/GPFifo.h @@ -48,6 +48,7 @@ bool IsEmpty(); void HWCALL Write8(const u8 _iValue, const u32 _iAddress); void HWCALL Write16(const u16 _iValue, const u32 _iAddress); void HWCALL Write32(const u32 _iValue, const u32 _iAddress); +void HWCALL Write64(const u64 _iValue, const u32 _iAddress); // These expect pre-byteswapped values // Also there's an upper limit of about 512 per batch @@ -55,6 +56,7 @@ void HWCALL Write32(const u32 _iValue, const u32 _iAddress); void HWCALL FastWrite8(const u8 _iValue); void HWCALL FastWrite16(const u16 _iValue); void HWCALL FastWrite32(const u32 _iValue); +void HWCALL FastWrite64(const u64 _iValue); }; diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp index db7f9570cf..6b90a5e3d4 100644 --- a/Source/Core/Core/Src/HW/Memmap.cpp +++ b/Source/Core/Core/Src/HW/Memmap.cpp @@ -242,6 +242,7 @@ void InitHWMemFuncs() hwWrite8 [GP_START] = GPFifo::Write8; hwWrite16[GP_START] = GPFifo::Write16; hwWrite32[GP_START] = GPFifo::Write32; + hwWrite64[GP_START] = GPFifo::Write64; } @@ -300,6 +301,7 @@ void InitHWMemFuncsWii() hwWrite8 [GP_START] = GPFifo::Write8; hwWrite16[GP_START] = GPFifo::Write16; hwWrite32[GP_START] = GPFifo::Write32; + hwWrite64[GP_START] = GPFifo::Write64; for (int i = 0; i < BLOCKSIZE; i++) { @@ -813,6 +815,7 @@ u8 *GetPointer(const u32 _Address) case 0x7B: case 0xFF: break; + default: if (!PanicYesNo("Unknown pointer address prefix %02X, report this to the devs: 0x%08X \n Continue?", (_Address >> 24), _Address)) Crash(); diff --git a/Source/Core/Core/Src/HW/MemmapFunctions.cpp b/Source/Core/Core/Src/HW/MemmapFunctions.cpp index 81d29ec749..421de8bb30 100644 --- a/Source/Core/Core/Src/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/Src/HW/MemmapFunctions.cpp @@ -40,9 +40,13 @@ extern bool m_IsInitialized; extern bool bFakeVMEM; // Read and write shortcuts + +// It appears that some clever games use stfd to write 64 bits to the fifo. Hence the hwWrite64. + extern writeFn8 hwWrite8 [NUMHWMEMFUN]; extern writeFn16 hwWrite16[NUMHWMEMFUN]; extern writeFn32 hwWrite32[NUMHWMEMFUN]; +extern writeFn64 hwWrite64[NUMHWMEMFUN]; extern readFn8 hwRead8 [NUMHWMEMFUN]; extern readFn16 hwRead16[NUMHWMEMFUN]; @@ -51,6 +55,7 @@ extern readFn32 hwRead32[NUMHWMEMFUN]; extern writeFn8 hwWriteWii8 [NUMHWMEMFUN]; extern writeFn16 hwWriteWii16[NUMHWMEMFUN]; extern writeFn32 hwWriteWii32[NUMHWMEMFUN]; +extern writeFn64 hwWriteWii64[NUMHWMEMFUN]; extern readFn8 hwReadWii8 [NUMHWMEMFUN]; extern readFn16 hwReadWii16[NUMHWMEMFUN]; @@ -75,7 +80,7 @@ inline void hwRead(u64 &var, u32 addr) {PanicAlert("hwRead: There's no 64-bit HW inline void hwWrite(u8 var, u32 addr) {hwWrite8[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwWrite(u16 var, u32 addr) {hwWrite16[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwWrite(u32 var, u32 addr) {hwWrite32[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} -inline void hwWrite(u64 var, u32 addr) {PanicAlert("hwWrite: There's no 64-bit HW write. %08x", addr);} +inline void hwWrite(u64 var, u32 addr) {hwWrite64[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwReadWii(u8 &var, u32 addr) {hwReadWii8 [(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwReadWii(u16 &var, u32 addr) {hwReadWii16[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} @@ -85,7 +90,7 @@ inline void hwReadWii(u64 &var, u32 addr) {PanicAlert("hwReadWii: There's no 64- inline void hwWriteWii(u8 var, u32 addr) {hwWriteWii8[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwWriteWii(u16 var, u32 addr) {hwWriteWii16[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwWriteWii(u32 var, u32 addr) {hwWriteWii32[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} -inline void hwWriteWii(u64 var, u32 addr) {PanicAlert("hwWriteWii: There's no 64-bit HW write. %08x", addr);} +inline void hwWriteWii(u64 var, u32 addr) {hwWriteWii64[(addr>>HWSHIFT) & (NUMHWMEMFUN-1)](var, addr);} inline void hwReadIOBridge(u8 &var, u32 addr) {WII_IOBridge::Read8(var, addr);} inline void hwReadIOBridge(u16 &var, u32 addr) {WII_IOBridge::Read16(var, addr);}