diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
index e49e99926b..c41fb2cad6 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
@@ -17,6 +17,7 @@
 
 #include "Common.h"
 #include "FileUtil.h"
+#include "StringUtil.h"
 
 #include "WII_IPC_HLE_Device_FileIO.h"
 
@@ -39,19 +40,19 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
 }
 
 CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName ) 
-: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
-, m_pFileHandle(NULL)
-, m_FileLength(0)
+    : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
+    , m_pFileHandle(NULL)
+    , m_FileLength(0)
 {
 }
 
 CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
 {
-	if (m_pFileHandle != NULL)
-	{
-		fclose(m_pFileHandle);
-		m_pFileHandle = NULL;
-	}
+    if (m_pFileHandle != NULL)
+    {
+        fclose(m_pFileHandle);
+        m_pFileHandle = NULL;
+    }
 }
 
 bool 
@@ -62,7 +63,7 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
 
 	// Close always return 0 for success
 	Memory::Write_U32(0, _CommandAddress + 4);
-
+	
 	return true;
 }
 
@@ -75,7 +76,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
 		fclose(m_pFileHandle);
 		m_pFileHandle = NULL;
 	}
-
+	
 	const char Modes[][128] =
 	{
 		{ "Unk Mode" },
@@ -92,7 +93,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
 	{
 		switch(_Mode)
 		{
-			// Do "r+b" for all writing to avoid truncating the file
+		// Do "r+b" for all writing to avoid truncating the file
 		case 0x01:	m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
 		case 0x02:	//m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break;
 		case 0x03:	m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
@@ -101,19 +102,19 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
 	}
 
 	u32 ReturnValue = 0;
-	if (m_pFileHandle != NULL)
-	{
-		m_FileLength = File::GetSize(m_Filename.c_str());
-		ReturnValue = GetDeviceID();
-	}
-	else
-	{
-		LOG(WII_IPC_FILEIO, "    failed - File doesn't exist");
-		ReturnValue = -106;
-	}
+    if (m_pFileHandle != NULL)
+    {
+        m_FileLength = File::GetSize(m_Filename.c_str());
+        ReturnValue = GetDeviceID();
+    }
+    else
+    {
+        LOG(WII_IPC_FILEIO, "    failed - File doesn't exist");
+        ReturnValue = -106;
+    }
 
-	Memory::Write_U32(ReturnValue, _CommandAddress+4);
-	return true;
+    Memory::Write_U32(ReturnValue, _CommandAddress+4);
+    return true;
 }
 
 bool 
@@ -123,58 +124,79 @@ CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
 	u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
 	u32 Mode = Memory::Read_U32(_CommandAddress +0x10);  
 
-	LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: %i, Mode: %i (Device=%s)", SeekPosition, Mode, GetDeviceName().c_str());	
+	LOG(WII_IPC_FILEIO, "FileIO: Old Seek Pos: %s, Mode: %i (Device=%s, FileSize=%s)", ThS(SeekPosition).c_str(), Mode, GetDeviceName().c_str(), ThS(m_FileLength).c_str());	
 
+	/* Zelda - TP Fix: It doesn't make much sense but it works in Zelda - TP and
+	   it's probably better than trying to read outside the file (it seeks to 0x6000 instead
+	   of the correct 0x2000 for the second half of the file). Could this be right
+	   or has it misunderstood the filesize somehow? My guess is that the filesize is
+	   hardcoded in to the game, and it never checks the filesize, so I don't know.
+	   Maybe it's wrong to return the seekposition when it's zero? Perhaps it wants
+	   the filesize then? - No, that didn't work either, it seeks to 0x6000 even if I return
+	   0x4000 from the first seek. */
+	u32 NewSeekPosition = SeekPosition;
+	if (m_FileLength > 0 && SeekPosition > m_FileLength && Mode == 0)
+	{
+		NewSeekPosition = SeekPosition % m_FileLength;
+		LOG(WII_IPC_FILEIO, "***********************************:");
+	}
+
+	LOG(WII_IPC_FILEIO, "FileIO: New Seek Pos: %s, Mode: %i (Device=%s)", ThS(NewSeekPosition).c_str(), Mode, GetDeviceName().c_str());	
+
+	// Set seek mode
 	int seek_mode[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
 
-	if (Mode >= 0 && Mode <= 2) {
-		if (fseek(m_pFileHandle, SeekPosition, seek_mode[Mode]) == 0) {
+	if (Mode >= 0 && Mode <= 2)
+	{
+        if (fseek(m_pFileHandle, NewSeekPosition, seek_mode[Mode]) == 0)
+		{
 			// Seek always return the seek position for success
 			// Not sure if it's right in all modes though.
-			ReturnValue = SeekPosition;		
-		} else {
-			LOG(WII_IPC_FILEIO, "FILEIO: Seek failed");
-		}
+			// What should we return for Zelda, the new correct or old incorrect seek position?
+		    ReturnValue = SeekPosition;
+        } else {
+            LOG(WII_IPC_FILEIO, "FILEIO: Seek failed");
+        }
 	} else {
 		PanicAlert("CWII_IPC_HLE_Device_FileIO unsupported seek mode %i", Mode);
 	}
 
-	Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
+    Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
 
-	return true;
+    return true;
 }
 
 bool 
 CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) 
 {    
-	u32 ReturnValue = 0;
-	u32 Address = Memory::Read_U32(_CommandAddress +0xC);
-	u32 Size = Memory::Read_U32(_CommandAddress +0x10);
+    u32 ReturnValue = 0;
+    u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Read to this memory address
+    u32 Size = Memory::Read_U32(_CommandAddress +0x10);
 
-	if (m_pFileHandle != NULL)
-	{
-		size_t readItems = fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle);
-		ReturnValue = (u32)readItems;
-		LOG(WII_IPC_FILEIO, "FileIO reads from %s (Addr=0x%08x Size=0x%x)", GetDeviceName().c_str(), Address, Size);	
-	}
-	else
-	{
-		LOG(WII_IPC_FILEIO, "FileIO failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", GetDeviceName().c_str(), Address, Size);	
-	}
+    if (m_pFileHandle != NULL)
+    {
+		LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, GetDeviceName().c_str());	
+        size_t readItems = fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle);
+        ReturnValue = (u32)readItems;		
+    }
+    else
+    {
+        LOG(WII_IPC_FILEIO, "FileIO failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", GetDeviceName().c_str(), Address, Size);	
+    }
 
-	Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
+    Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
 
-	return true;
+    return true;
 }
 
 bool 
 CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) 
 {        
 	u32 ReturnValue = 0;
-	u32 Address = Memory::Read_U32(_CommandAddress +0xC);
+	u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Write data from this memory address
 	u32 Size = Memory::Read_U32(_CommandAddress +0x10);
 
-	LOG(WII_IPC_FILEIO, "FileIO: Write Addr: 0x%08x Size: %i (Device=%s)", Address, Size, GetDeviceName().c_str());	
+	LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes to 0x%08x from %s", Size, Address, GetDeviceName().c_str());	
 
 	if (m_pFileHandle)
 	{
@@ -184,52 +206,52 @@ CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
 		ReturnValue = Size;
 	}
 
-	Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
+    Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
 
-	return true;
+    return true;
 }
 
 bool 
 CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) 
 {
-	LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", GetDeviceName().c_str());	
-	DumpCommands(_CommandAddress);
+    LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", GetDeviceName().c_str());	
+    DumpCommands(_CommandAddress);
 
-	u32 Parameter =  Memory::Read_U32(_CommandAddress + 0xC);
+    u32 Parameter =  Memory::Read_U32(_CommandAddress + 0xC);
 
-	//    u32 BufferIn =  Memory::Read_U32(_CommandAddress + 0x10);
-	//    u32 BufferInSize =  Memory::Read_U32(_CommandAddress + 0x14);
-	//    u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
-	//    u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
+    //    u32 BufferIn =  Memory::Read_U32(_CommandAddress + 0x10);
+    //    u32 BufferInSize =  Memory::Read_U32(_CommandAddress + 0x14);
+    //    u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
+    //    u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
 
-	switch(Parameter)
-	{
-	case ISFS_IOCTL_GETFILESTATS:
-		{
-			u32 Position = (u32)ftell(m_pFileHandle);
+    switch(Parameter)
+    {
+    case ISFS_IOCTL_GETFILESTATS:
+        {
+            u32 Position = (u32)ftell(m_pFileHandle);
+            
+            u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
+            LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
+            LOG(WII_IPC_FILEIO, "    Length: %i   Seek: %i", m_FileLength, Position);
 
-			u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
-			LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
-			LOG(WII_IPC_FILEIO, "    Length: %i   Seek: %i", m_FileLength, Position);
+            Memory::Write_U32((u32)m_FileLength, BufferOut);
+            Memory::Write_U32(Position, BufferOut+4);
+        }
+        break;
 
-			Memory::Write_U32((u32)m_FileLength, BufferOut);
-			Memory::Write_U32(Position, BufferOut+4);
-		}
-		break;
+    default:
+        {
+            PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
+        }
+        break;
 
-	default:
-		{
-			PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
-		}
-		break;
+    }
 
-	}
+    // Return Value
+    u32 ReturnValue = 0;  // no error
+    Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
 
-	// Return Value
-	u32 ReturnValue = 0;  // no error
-	Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
-
-	return true;
+    return true;
 }
 
 bool