From a09a3e08f11e97a92f1d0608e2f8b02ede10e67a Mon Sep 17 00:00:00 2001
From: hrydgard <hrydgard@gmail.com>
Date: Mon, 23 Feb 2009 19:45:40 +0000
Subject: [PATCH] First step towards fixing star wars force unleashed : make
 64-bit hw writes possible

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2393 8ced0084-cf51-0410-be5f-012b33b47a6e
---
 Source/Core/Core/Src/HW/GPFifo.cpp          | 13 +++++++++++++
 Source/Core/Core/Src/HW/GPFifo.h            |  2 ++
 Source/Core/Core/Src/HW/Memmap.cpp          |  3 +++
 Source/Core/Core/Src/HW/MemmapFunctions.cpp |  9 +++++++--
 4 files changed, 25 insertions(+), 2 deletions(-)

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);}