Merge pull request #5590 from unknownbrackets/xbox

Merge more parts of #4716
This commit is contained in:
Henrik Rydgård 2014-03-03 13:37:21 +07:00
commit 374e12afc3
37 changed files with 499 additions and 66 deletions

View File

@ -19,7 +19,11 @@
#define _ATOMIC_WIN32_H_
#include "Common.h"
#ifndef _XBOX
#include <intrin.h>
#else
#include <ppcintrinsics.h>
#endif
#include "CommonWindows.h"
// Atomic operations are performed in a single step by the CPU. It is

View File

@ -147,15 +147,21 @@ private:
# elif defined __SSE2__
# define _M_SSE 0x200
# endif
#elif ((_MSC_VER >= 1500) || __INTEL_COMPILER) // Visual Studio 2008
#elif ((_MSC_VER >= 1500) || __INTEL_COMPILER) && !defined(_XBOX) // Visual Studio 2008
# define _M_SSE 0x402
#endif
#ifdef _MSC_VER
#ifndef _XBOX
inline unsigned long long bswap64(unsigned long long x) { return _byteswap_uint64(x); }
inline unsigned int bswap32(unsigned int x) { return _byteswap_ulong(x); }
inline unsigned int bswap16(unsigned int x) { return _byteswap_ushort(x); }
inline unsigned short bswap16(unsigned short x) { return _byteswap_ushort(x); }
#else
inline unsigned long long bswap64(unsigned long long x) { return __loaddoublewordbytereverse(0, &x); }
inline unsigned int bswap32(unsigned int x) { return __loadwordbytereverse(0, &x); }
inline unsigned short bswap16(unsigned short x) { return __loadshortbytereverse(0, &x); }
#endif
#else
// TODO: speedup
inline unsigned short bswap16(unsigned short x) { return (x << 8) | (x >> 8); }

View File

@ -190,6 +190,7 @@
<ClInclude Include="MemArena.h" />
<ClInclude Include="MemoryUtil.h" />
<ClInclude Include="MsgHandler.h" />
<ClInclude Include="ppcEmitter.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="StdMutex.h" />
<ClInclude Include="StringUtils.h" />
@ -227,6 +228,12 @@
<ClCompile Include="MemoryUtil.cpp" />
<ClCompile Include="Misc.cpp" />
<ClCompile Include="MsgHandler.cpp" />
<ClCompile Include="ppcEmitter.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>

View File

@ -36,6 +36,7 @@
<ClInclude Include="Crypto\sha1.h">
<Filter>Crypto</Filter>
</ClInclude>
<ClInclude Include="ppcEmitter.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@ -65,6 +66,7 @@
</ClCompile>
<ClCompile Include="ChunkFile.cpp" />
<ClCompile Include="ArmThunk.cpp" />
<ClCompile Include="ppcEmitter.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View File

@ -84,7 +84,7 @@ inline u64 __rotr64(u64 x, unsigned int shift){
#define stat64 _stat64
#define fstat64 _fstat64
#define fileno _fileno
#ifndef _XBOX
#if _M_IX86
#define Crash() {__asm int 3}
#else
@ -93,6 +93,9 @@ extern "C" {
}
#define Crash() {DebugBreak();}
#endif // M_IX86
#else
#define Crash() {DebugBreak();}
#endif // _XBOX ndef
#endif // WIN32 ndef
// Generic function to get last error message.

View File

@ -10,6 +10,16 @@
#ifdef _XBOX
#include <xtl.h>
extern "C" void _ReadWriteBarrier();
#pragma intrinsic(_ReadWriteBarrier)
extern "C" void _WriteBarrier();
#pragma intrinsic(_WriteBarrier)
extern "C" void _ReadBarrier();
#pragma intrinsic(_ReadBarrier)
#else
#include <Windows.h>
#endif

View File

@ -32,7 +32,7 @@
#include "ConsoleListener.h" // Common
#include "Atomics.h"
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
const int LOG_PENDING_MAX = 120 * 10000;
const int LOG_LATENCY_DELAY_MS = 20;
const int LOG_SHUTDOWN_DELAY_MS = 250;
@ -50,7 +50,7 @@ volatile u32 ConsoleListener::logPendingWritePos = 0;
ConsoleListener::ConsoleListener() : bHidden(true)
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
hConsole = NULL;
bUseColor = true;
@ -61,6 +61,8 @@ ConsoleListener::ConsoleListener() : bHidden(true)
logPending = new char[LOG_PENDING_MAX];
}
++refCount;
#elif defined(_XBOX)
bUseColor = false;
#else
bUseColor = isatty(fileno(stdout));
#endif
@ -101,7 +103,7 @@ bool WINAPI ConsoleHandler(DWORD msgType)
// Name is the window title
void ConsoleListener::Init(bool AutoOpen, int Width, int Height, const char *Title)
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
openWidth_ = Width;
openHeight_ = Height;
title_ = ConvertUTF8ToWString(Title);
@ -113,7 +115,7 @@ void ConsoleListener::Init(bool AutoOpen, int Width, int Height, const char *Tit
void ConsoleListener::Open()
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
if (!GetConsoleWindow())
{
// Open the console window and create the window handle for GetStdHandle()
@ -147,7 +149,7 @@ void ConsoleListener::Open()
void ConsoleListener::Show(bool bShow)
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
if (bShow && bHidden)
{
if (!IsOpen())
@ -166,7 +168,7 @@ void ConsoleListener::Show(bool bShow)
void ConsoleListener::UpdateHandle()
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
#endif
}
@ -174,7 +176,7 @@ void ConsoleListener::UpdateHandle()
// Close the console window and close the eventual file handle
void ConsoleListener::Close()
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
if (hConsole == NULL)
return;
@ -212,7 +214,7 @@ void ConsoleListener::Close()
bool ConsoleListener::IsOpen()
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
return (hConsole != NULL);
#else
return true;
@ -226,7 +228,7 @@ bool ConsoleListener::IsOpen()
void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst)
{
_dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console.");
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
BOOL SB, SW;
if (BufferFirst)
{
@ -251,7 +253,7 @@ void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int S
void ConsoleListener::LetterSpace(int Width, int Height)
{
_dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console.");
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
// Get console info
CONSOLE_SCREEN_BUFFER_INFO ConInfo;
GetConsoleScreenBufferInfo(hConsole, &ConInfo);
@ -277,7 +279,7 @@ void ConsoleListener::LetterSpace(int Width, int Height)
#endif
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth)
{
COORD Ret = {0, 0};
@ -502,7 +504,7 @@ void ConsoleListener::WriteToConsole(LogTypes::LOG_LEVELS Level, const char *Tex
void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize)
{
_dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console.");
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
// Check size
if (Width < 8 || Height < 12) return;
@ -589,7 +591,7 @@ void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool
void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
{
#if defined(_WIN32)
#if defined(_WIN32) && !defined(_XBOX)
if (hThread == NULL && IsOpen())
WriteToConsole(Level, Text, strlen(Text));
else
@ -623,7 +625,7 @@ void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
void ConsoleListener::ClearScreen(bool Cursor)
{
_dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console.");
#if defined(_WIN32)
#if defined(_WIN32) && !defined(_XBOX)
COORD coordScreen = { 0, 0 };
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;

View File

@ -38,7 +38,7 @@ public:
void LetterSpace(int Width, int Height);
void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
void PixelSpace(int Left, int Top, int Width, int Height, bool);
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
COORD GetCoordinates(int BytesRead, int BufferWidth);
#endif
void Log(LogTypes::LOG_LEVELS, const char *Text);
@ -47,7 +47,7 @@ public:
void Show(bool bShow);
bool Hidden() const { return bHidden; }
private:
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
HWND GetHwnd(void);
HANDLE hConsole;

View File

@ -20,9 +20,11 @@
#ifdef _WIN32
#include "CommonWindows.h"
#ifndef _XBOX
#include <shlobj.h> // for SHGetFolderPath
#include <shellapi.h>
#include <commdlg.h> // for GetSaveFileName
#endif
#include <io.h>
#include <direct.h> // getcwd
#else
@ -638,6 +640,7 @@ void CopyDir(const std::string &source_path, const std::string &dest_path)
std::string GetCurrentDir()
{
char *dir;
#ifndef _XBOX
// Get the current working directory (getcwd uses malloc)
if (!(dir = __getcwd(NULL, 0))) {
@ -648,12 +651,19 @@ std::string GetCurrentDir()
std::string strDir = dir;
free(dir);
return strDir;
#else
return "game:\\";
#endif
}
// Sets the current directory to the given directory
bool SetCurrentDir(const std::string &directory)
{
#ifndef _XBOX
return __chdir(directory.c_str()) == 0;
#else
return false;
#endif
}
const std::string &GetExeDirectory()
@ -661,6 +671,7 @@ const std::string &GetExeDirectory()
static std::string ExePath;
if (ExePath.empty())
#ifndef _XBOX
{
#ifdef _WIN32
TCHAR program_path[4096] = {0};
@ -697,6 +708,10 @@ const std::string &GetExeDirectory()
}
return ExePath;
#else
static std::wstring ExePath = L"game:\\";
return ExePath;
#endif
}
@ -789,6 +804,7 @@ bool IOFile::Flush()
bool IOFile::Resize(u64 size)
{
#ifndef _XBOX
if (!IsOpen() || 0 !=
#ifdef _WIN32
// ector: _chsize sucks, not 64-bit safe
@ -802,6 +818,10 @@ bool IOFile::Resize(u64 size)
m_good = false;
return m_good;
#else
// TODO: Implement.
return false;
#endif
}
} // namespace

View File

@ -15,7 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
#include <windows.h>
#endif
@ -336,7 +336,7 @@ void SetDefaultKeyMap(DefaultMaps dmap, bool replace) {
{
bool azerty = false;
bool qwertz = false;
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
HKL localeId = GetKeyboardLayout(0);
// TODO: Is this list complete enough?
switch ((int)localeId & 0xFFFF) {

View File

@ -94,7 +94,7 @@ LogManager::LogManager() {
}
// Remove file logging on small devices
#if !defined(MOBILE_DEVICE) || defined(_DEBUG)
#if !(defined(MOBILE_DEVICE) || defined(_XBOX)) || defined(_DEBUG)
fileLog_ = new FileLogListener("");
consoleLog_ = new ConsoleListener();
debuggerLog_ = new DebuggerLogListener();
@ -106,10 +106,10 @@ LogManager::LogManager() {
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i) {
log_[i]->SetEnable(true);
#if !defined(MOBILE_DEVICE) || defined(_DEBUG)
#if !(defined(MOBILE_DEVICE) || defined(_XBOX)) || defined(_DEBUG)
log_[i]->AddListener(fileLog_);
log_[i]->AddListener(consoleLog_);
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(_XBOX)
if (IsDebuggerPresent() && debuggerLog_ != NULL && LOG_MSC_OUTPUTDEBUG)
log_[i]->AddListener(debuggerLog_);
#endif

View File

@ -108,7 +108,7 @@ std::string ram_temp_file = "/home/user/gc_mem.tmp";
#else
std::string ram_temp_file = "/tmp/gc_mem.tmp";
#endif
#else
#elif !defined(_XBOX)
SYSTEM_INFO sysInfo;
#endif
@ -116,7 +116,11 @@ SYSTEM_INFO sysInfo;
// Windows mappings need to be on 64K boundaries, due to Alpha legacy.
#ifdef _WIN32
size_t roundup(size_t x) {
#ifndef _XBOX
int gran = sysInfo.dwAllocationGranularity ? sysInfo.dwAllocationGranularity : 0x10000;
#else
int gran = 0x10000; // 64k in 360
#endif
return (x + gran - 1) & ~(gran - 1);
}
#else
@ -129,8 +133,10 @@ size_t roundup(size_t x) {
void MemArena::GrabLowMemSpace(size_t size)
{
#ifdef _WIN32
#ifndef _XBOX
hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL);
GetSystemInfo(&sysInfo);
#endif
#elif defined(ANDROID)
// Use ashmem so we don't have to allocate a file on disk!
fd = ashmem_create_region("PPSSPP_RAM", size);
@ -176,9 +182,16 @@ void MemArena::ReleaseSpace()
void *MemArena::CreateView(s64 offset, size_t size, void *base)
{
#ifdef _WIN32
#ifdef _XBOX
size = roundup(size);
// use 64kb pages
void * ptr = VirtualAlloc(NULL, size, MEM_COMMIT|MEM_LARGE_PAGES, PAGE_READWRITE);
return ptr;
#else
size = roundup(size);
void *ptr = MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base);
return ptr;
#endif
#else
void *retval = mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED |
// Do not sync memory to underlying file. Linux has this by default.
@ -202,7 +215,9 @@ void *MemArena::CreateView(s64 offset, size_t size, void *base)
void MemArena::ReleaseView(void* view, size_t size)
{
#ifdef _WIN32
#ifndef _XBOX
UnmapViewOfFile(view);
#endif
#elif defined(__SYMBIAN32__)
memmap->Decommit(((int)view - (int)memmap->Base()) & 0x3FFFFFFF, size);
#else
@ -276,6 +291,10 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32
size_t position = 0;
size_t last_position = 0;
#if defined(_XBOX)
void *ptr;
#endif
// Zero all the pointers to be sure.
for (int i = 0; i < num_views; i++)
{
@ -300,6 +319,12 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32
arena->memmap->Commit(view.virtual_address & 0x3FFFFFFF, view.size);
}
*(view.out_ptr) = (u8*)((int)arena->memmap->Base() + view.virtual_address & 0x3FFFFFFF);
#elif defined(_XBOX)
*(view.out_ptr_low) = (u8*)(base + view.virtual_address);
//arena->memmap->Commit(view.virtual_address & 0x3FFFFFFF, view.size);
ptr = VirtualAlloc(base + (view.virtual_address & 0x3FFFFFFF), view.size, MEM_COMMIT, PAGE_READWRITE);
}
*(view.out_ptr) = (u8*)base + (view.virtual_address & 0x3FFFFFFF);
#else
*(view.out_ptr_low) = (u8*)arena->CreateView(position, view.size);
if (!*view.out_ptr_low)
@ -383,8 +408,16 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena
PanicAlert("MemoryMap_Setup: Failed finding a memory base.");
return 0;
}
#else
#ifdef _WIN32
#elif defined(_XBOX)
// Reserve 256MB
u8 *base = (u8*)VirtualAlloc(0, 0x10000000, MEM_RESERVE|MEM_LARGE_PAGES, PAGE_READWRITE);
if (!Memory_TryBase(base, views, num_views, flags, arena))
{
PanicAlert("MemoryMap_Setup: Failed finding a memory base.");
exit(0);
return 0;
}
#elif defined(_WIN32)
// Try a whole range of possible bases. Return once we got a valid one.
u32 max_base_addr = 0x7FFF0000 - 0x10000000;
u8 *base = NULL;
@ -418,8 +451,6 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena
PanicAlert("MemoryMap_Setup: Failed finding a memory base.");
return 0;
}
#endif
#endif
if (base_attempts)
PanicAlert("No possible memory base pointer found!");

View File

@ -219,4 +219,3 @@ void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
#endif
}

View File

@ -33,7 +33,7 @@
const char* GetLastErrorMsg()
{
static const size_t buff_size = 255;
#ifndef _XBOX
#ifdef _WIN32
static __declspec(thread) char err_str[buff_size] = {};
@ -48,4 +48,7 @@ const char* GetLastErrorMsg()
#endif
return err_str;
#else
return "GetLastErrorMsg";
#endif
}

View File

@ -67,7 +67,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
// Default non library dependent panic alert
bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style)
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
int STYLE = MB_ICONINFORMATION;
if (Style == QUESTION) STYLE = MB_ICONQUESTION;
if (Style == WARNING) STYLE = MB_ICONWARNING;
@ -76,7 +76,6 @@ bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style)
std::wstring wcaption = ConvertUTF8ToWString(caption);
return IDYES == MessageBox(0, wtext.c_str(), wcaption.c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK));
#else
printf("%s\n", text);
return true;

View File

@ -85,6 +85,7 @@ public:
return *this;
}
operator unsigned long() const { return (unsigned long)swap(); }
operator long() const { return (long)swap(); }
operator s8() const { return (s8)swap(); }
operator u8() const { return (u8)swap(); }

View File

@ -19,7 +19,9 @@
#ifdef _WIN32
#include "CommonWindows.h"
#ifndef _XBOX
#include <mmsystem.h>
#endif
#include <sys/timeb.h>
#else
#include <sys/time.h>
@ -33,7 +35,9 @@ namespace Common
u32 Timer::GetTimeMs()
{
#ifdef _WIN32
#ifdef _XBOX
return GetTickCount();
#elif defined(_WIN32)
return timeGetTime();
#elif defined(BLACKBERRY)
struct timespec time;
@ -149,14 +153,14 @@ std::string Timer::GetTimeElapsedFormatted() const
// Get current time
void Timer::IncreaseResolution()
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
timeBeginPeriod(1);
#endif
}
void Timer::RestoreResolution()
{
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
timeEndPeriod(1);
#endif
}

68
Common/XboxCPUDetect.cpp Normal file
View File

@ -0,0 +1,68 @@
// Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <memory.h>
#include "base/logging.h"
#include "base/basictypes.h"
#include "Common.h"
#include "CPUDetect.h"
#include "StringUtils.h"
CPUInfo cpu_info;
CPUInfo::CPUInfo() {
Detect();
}
// Detects the various cpu features
void CPUInfo::Detect()
{
memset(this, 0, sizeof(*this));
num_cores = 3;
strcpy(cpu_string, "Xenon");
strcpy(brand_string, "Microsoft");
memset(cpu_string, 0, sizeof(cpu_string));
HTT = true;
logical_cpu_count = 2;
}
// Turn the cpu info into a string we can show
std::string CPUInfo::Summarize()
{
std::string sum;
if (num_cores == 1)
sum = StringFromFormat("%s, %i core", cpu_string, num_cores);
else
{
sum = StringFromFormat("%s, %i cores", cpu_string, num_cores);
if (HTT) sum += StringFromFormat(" (%i logical threads per physical core)", logical_cpu_count);
}
if (bSSE) sum += ", SSE";
if (bSSE2) sum += ", SSE2";
if (bSSE3) sum += ", SSE3";
if (bSSSE3) sum += ", SSSE3";
if (bSSE4_1) sum += ", SSE4.1";
if (bSSE4_2) sum += ", SSE4.2";
if (HTT) sum += ", HTT";
if (bAVX) sum += ", AVX";
if (bAES) sum += ", AES";
if (bLongMode) sum += ", 64-bit support";
return sum;
}

View File

@ -44,6 +44,13 @@
X_FORM(OPCD, crbD, crbA, crbB, XO, LK); \
}
// 0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
// | OPCD | S | A | SH | MB | ME |Rc|
#define M_FORM(OPCD, RS, RA, SH, MB, ME, Rc) { \
int rs = (RS), ra = (RA), sh = (SH); \
Write32((OPCD << 26) | (rs << 21) | (ra << 16) | (sh << 11) | ((MB) << 6) | ((ME) << 1) | (Rc)); \
}
namespace PpcGen {
// Mul stuff
@ -216,11 +223,18 @@ namespace PpcGen {
void PPCXEmitter::BEQ (const void *fnptr) {
CHECK_SMALL_JUMP
s32 func = (s32)fnptr - s32(code);
s32 func = (s32)fnptr - s32(code);
u32 instr = (0x41820000 | ( func & 0xfffc));
Write32(instr);
}
void PPCXEmitter::BNE (const void *fnptr) {
CHECK_SMALL_JUMP
s32 func = (s32)fnptr - s32(code);
u32 instr = (0x40820000 | ( func & 0xfffc));
Write32(instr);
}
void PPCXEmitter::BGT(const void *fnptr) {
CHECK_SMALL_JUMP
@ -465,6 +479,9 @@ namespace PpcGen {
void PPCXEmitter::SUBFC (PPCReg Rd, PPCReg Ra, PPCReg Rb) {
XO_FORM(31, Rd, Ra, Rb, 0, 8, 0);
}
void PPCXEmitter::SUBFIC(PPCReg Rt, PPCReg Ra, short imm) {
D_FORM(8, Rt, Ra, imm);
}
void PPCXEmitter::SUBFE(PPCReg Rd, PPCReg Ra, PPCReg Rb) {
@ -474,10 +491,10 @@ namespace PpcGen {
// Quick Call
// dest = LIS(imm) + ORI(+imm)
void PPCXEmitter::MOVI2R(PPCReg dest, unsigned int imm) {
/*if (imm == (unsigned short)imm) {
if ((s32) (s16) (imm) == (s32) (imm)) {
// 16bit
LI(dest, imm & 0xFFFF);
} else */{
} else {
// HI 16bit
LIS(dest, imm>>16);
if ((imm & 0xFFFF) != 0) {
@ -508,6 +525,10 @@ namespace PpcGen {
Write32(0x7C000734 | (src << 21) | (dest << 16));
}
void PPCXEmitter::EXTSW (PPCReg Rt, PPCReg Ra) {
X_FORM(31, Rt, Ra, 0, 986, 0);
}
void PPCXEmitter::EQV (PPCReg Ra, PPCReg Rs, PPCReg Rb) {
X_FORM(31, Rs, Ra, Rb, 284, 0);
}
@ -516,6 +537,10 @@ namespace PpcGen {
Write32((21<<26) | (src << 21) | (dest << 16) | (shift << 11) | (start << 6) | (end << 1));
}
void PPCXEmitter::RLDICL (PPCReg Rs, PPCReg Ra, int sh, int mb) {
Write32((30 << 26) | (Rs << 21) | (Ra << 16) | (sh << 11) | ((mb) << 6) | ((sh) << 1) | (0));
}
// Shift Instructions
void PPCXEmitter::SRAW (PPCReg dest, PPCReg src, PPCReg shift) {
X_FORM(31, src, dest, shift, 792, 0);
@ -559,14 +584,12 @@ namespace PpcGen {
D_FORM(48, FRt, Ra, offset);
}
void PPCXEmitter::LFD (PPCReg FRt, PPCReg Ra, unsigned short offset) {
Break();
D_FORM(50, FRt, Ra, offset);
}
void PPCXEmitter::SFS (PPCReg FRt, PPCReg Ra, unsigned short offset) {
D_FORM(52, FRt, Ra, offset);
}
void PPCXEmitter::SFD (PPCReg FRt, PPCReg Ra, unsigned short offset) {
Break();
D_FORM(54, FRt, Ra, offset);
}
@ -624,6 +647,24 @@ namespace PpcGen {
// Load the final value
LFS(FRt, R7, 0);
}
void PPCXEmitter::MTFSB0(int bt) {
X_FORM(63, bt, 0, 0, 70, 0);
}
void PPCXEmitter::FCTID (PPCReg FRt, PPCReg FRb) {
X_FORM(63, FRt, 0, FRb, 846, 0);
}
void PPCXEmitter::FCFID (PPCReg FRt, PPCReg FRb) {
X_FORM(63, FRt, 0, FRb, 846, 0);
}
void PPCXEmitter::FRSP (PPCReg FRt, PPCReg FRb) {
X_FORM(63, FRt, 0, FRb, 12, 0);
}
void PPCXEmitter::FCTIW (PPCReg FRt, PPCReg FRb) {
X_FORM(63, FRt, 0, FRb, 14, 0);
}
void PPCXEmitter::STFIWX(PPCReg FRt, PPCReg FRa, PPCReg FRb) {
X_FORM(31, FRt, FRa, FRb, 983, 0);
}
// Fpu move instruction
void PPCXEmitter::FMR (PPCReg FRt, PPCReg FRb) {
@ -731,37 +772,82 @@ namespace PpcGen {
X_FORM(63, Bf, FRa, FRb, 32, 0);
}
// fpu convert
void PPCXEmitter::FRIN (PPCReg FRt, PPCReg FRb) { // round
X_FORM(63, FRt, 0, FRb, 392, 0);
}
void PPCXEmitter::FRIZ (PPCReg FRt, PPCReg FRb) { // trunc
X_FORM(63, FRt, 0, FRb, 456, 0);
}
void PPCXEmitter::FRIP (PPCReg FRt, PPCReg FRb) { // ceil
X_FORM(63, FRt, 0, FRb, 424, 0);
}
void PPCXEmitter::FRIM (PPCReg FRt, PPCReg FRb) { // floor
X_FORM(63, FRt, 0, FRb, 488, 0);
}
// Prologue / epilogue
/** save/load fpr in a static buffer ... **/
static double _fprTmp[32];
void PPCXEmitter::Prologue() {
// Save regs
u32 regSize = 8; // 4 in 32bit system
u32 stackFrameSize = 32*32;//(35 - 12) * regSize;
u32 stackFrameSize = 0x1F0;
// Write Prologue (setup stack frame etc ...)
// Save Lr
MFLR(R12);
// Save gpr
for(int i = 14; i < 32; i ++) {
STD((PPCReg)i, R1, -((33 - i) * regSize));
}
// Save r12
STW(R12, R1, -0x8);
#if 0
// add fpr frame
ADDI(R12, R1, -0x98);
// Load fpr
for(int i = 14; i < 32; i ++) {
SFD((PPCReg)i, R1, -((32 - i) * regSize));
}
#endif
// allocate stack
STWU(R1, R1, -stackFrameSize);
#if 1
// load fpr buff
MOVI2R(R5, (u32)&_fprTmp);
// Save fpr
for(int i = 14; i < 32; i ++) {
SFD((PPCReg)i, R5, i * regSize);
}
#endif
}
void PPCXEmitter::Epilogue() {
u32 regSize = 8; // 4 in 32bit system
u32 stackFrameSize = 32*32;//(35 - 12) * regSize;
u32 stackFrameSize = 0x1F0;
//Break();
// Write Epilogue (restore stack frame, return)
// free stack
ADDI(R1, R1, stackFrameSize);
#if 0
ADDI(R12, R1, -0x98);
// Restore regs
// Restore fpr
for(int i = 14; i < 32; i ++) {
LFD((PPCReg)i, R1, -((32 - i) * regSize));
}
#endif
// Restore gpr
for(int i = 14; i < 32; i ++) {
LD((PPCReg)i, R1, -((33 - i) * regSize));
}
@ -771,6 +857,16 @@ namespace PpcGen {
// Restore Lr
MTLR(R12);
#if 1
// load fpr buff
MOVI2R(R5, (u32)&_fprTmp);
// Load fpr
for(int i = 14; i < 32; i ++) {
LFD((PPCReg)i, R5, i * regSize);
}
#endif
}
// Others ...

View File

@ -203,6 +203,7 @@ namespace PpcGen
void BA (const void *fnptr);
void BLA(const void *fnptr);
void BEQ(const void *fnptr);
void BNE(const void *fnptr);
void BLE(const void *fnptr);
void BLT(const void *fnptr);
void BGT(const void *fnptr);
@ -248,6 +249,7 @@ namespace PpcGen
}
// if RCFlags update CR0
void SUBF (PPCReg Rd, PPCReg Ra, PPCReg Rb, int RCFlags = 0);
void SUBFIC (PPCReg Rt, PPCReg Ra, short imm);
void SUBFC (PPCReg Rd, PPCReg Ra, PPCReg Rb);
void SUBFE (PPCReg Rd, PPCReg Ra, PPCReg Rb);
@ -293,10 +295,13 @@ namespace PpcGen
// sign
void EXTSB (PPCReg dest, PPCReg src);
void EXTSH (PPCReg dest, PPCReg src);
void EXTSW (PPCReg dest, PPCReg src);
//
void RLWINM (PPCReg dest, PPCReg src, int shift, int start, int end);
void RLDICL (PPCReg Rt, PPCReg Rs, int sh, int mb);
// Shift Instructions
void SRAW (PPCReg dest, PPCReg src, PPCReg shift);
void SRAWI (PPCReg dest, PPCReg src, unsigned short imm);
@ -359,6 +364,16 @@ namespace PpcGen
// Fpu move instruction
void FMR (PPCReg FRt, PPCReg FRb);
// fpu
void MTFSB0 (int bt);
void FCFID (PPCReg FRt, PPCReg FRb);
void FCTID (PPCReg FRt, PPCReg FRb);
void FRSP (PPCReg FRt, PPCReg FRb);
void FCTIW (PPCReg FRt, PPCReg FRb);
void STFIWX (PPCReg FRt, PPCReg FRa, PPCReg FRb);
// Fpu
void FNEG (PPCReg FRt, PPCReg FRb);
void FABS (PPCReg FRt, PPCReg FRb);
void FNABS (PPCReg FRt, PPCReg FRb);
@ -395,6 +410,12 @@ namespace PpcGen
void FCMPU (int Bf, PPCReg FRa, PPCReg FRb); // unordered
void FCMPO (int Bf, PPCReg FRa, PPCReg FRb); // ordered
// Fpu convert
void FRIN (PPCReg FRt, PPCReg FRb); // round
void FRIZ (PPCReg FRt, PPCReg FRb); // trunc
void FRIP (PPCReg FRt, PPCReg FRb); // ceil
void FRIM (PPCReg FRt, PPCReg FRb); // floor
// VPU - lvx128
void LoadVector(PPCReg Rd, PPCReg Ra, PPCReg Rb);

View File

@ -33,10 +33,6 @@
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
//#define _CRT_SECURE_NO_DEPRECATE 1
//#define _CRT_NONSTDC_NO_DEPRECATE 1
#include "CommonWindows.h"
#include <tchar.h>
#include <vector>

View File

@ -20,7 +20,9 @@
#include "ext/vjson/json.h"
#include "file/ini_file.h"
#include "i18n/i18n.h"
#ifndef _XBOX
#include "gfx_es2/gpu_features.h"
#endif
#include "net/http_client.h"
#include "util/text/parsers.h"
#include "net/url.h"

View File

@ -31,7 +31,9 @@
#include "Core/MIPS/MIPS.h"
#ifdef _WIN32
#ifndef _XBOX
#include "Windows/OpenGLBase.h"
#endif
#include "Windows/InputDevice.h"
#endif

View File

@ -23,7 +23,9 @@
#ifdef _WIN32
#include "Common/CommonWindows.h"
#ifndef _XBOX
#include <WindowsX.h>
#endif
#else
#include <unistd.h>
#endif
@ -910,7 +912,7 @@ DataType SymbolMap::GetDataType(u32 startAddress) const {
return it->second.type;
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
struct DefaultSymbol {
u32 address;

View File

@ -480,7 +480,9 @@ int getActivePeerCount(void) {
}
int getLocalIp(sockaddr_in * SocketAddress){
#ifdef _MSC_VER
#ifdef _XBOX
return -1;
#elif defined(_MSC_VER)
// Get local host name
char szHostName[128] = "";
@ -522,6 +524,9 @@ int getPTPSocketCount(void) {
}
int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
#ifdef _XBOX
return -1;
#else
int iResult = 0;
#ifdef _MSC_VER
WSADATA data;
@ -582,6 +587,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
}else{
return -1;
}
#endif
}
int isBroadcastMAC(const SceNetEtherAddr * addr) {

View File

@ -16,7 +16,10 @@
#include "Core/HLE/sceUtility.h"
// Net stuff
#ifdef _MSC_VER
#ifdef _XBOX
#include <winsockx.h>
typedef int socklen_t;
#elif defined(_MSC_VER)
#include <WS2tcpip.h>
#else
#include <sys/types.h>

View File

@ -475,6 +475,11 @@ void __IoInit() {
if (ioManagerThreadEnabled) {
Core_ListenShutdown(&__IoWakeManager);
ioManagerThread = new std::thread(&__IoManagerThread);
#ifdef _XBOX
SuspendThread(ioManagerThread->native_handle());
XSetThreadProcessor(ioManagerThread->native_handle(), 4);
ResumeThread(ioManagerThread->native_handle());
#endif
ioManagerThread->detach();
}

View File

@ -17,7 +17,10 @@
#ifdef _WIN32
#include "Common/CommonWindows.h"
#ifndef _XBOX
// timeval already defined in xtl.h
#include <Winsock2.h>
#endif
#else
#include <sys/time.h>
#endif

View File

@ -110,7 +110,8 @@ IdentifiedFileType Identify_File(std::string &filename)
}
u32 psar_offset = 0, psar_id = 0;
switch (id) {
u32 _id = id;
switch (_id) {
case 'PBP\x00':
fseek(f, 0x24, SEEK_SET);
fread(&psar_offset, 4, 1, f);

View File

@ -1,4 +1,5 @@
#include "Common/ChunkFile.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/MIPS/MIPS.h"
@ -67,6 +68,10 @@ void Jit::Comp_FPULS(MIPSOpcode op) {
// logBlocks = 1;
bool doCheck = false;
if (!g_Config.bFastMemory) {
DISABLE;
}
switch(op >> 26)
{
case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1
@ -333,6 +338,7 @@ void Jit::Comp_FPUComp(MIPSOpcode op) {
#endif
void Jit::Comp_FPU2op(MIPSOpcode op) {
DISABLE
CONDITIONAL_DISABLE;
int fs = _FS;
@ -356,6 +362,27 @@ void Jit::Comp_FPU2op(MIPSOpcode op) {
fpr.MapDirtyIn(fd, fs);
FNEG(fpr.R(fd), fpr.R(fs));
break;
case 13: // FsI(fd) = F(fs)>=0 ? (int)floorf(F(fs)) : (int)ceilf(F(fs)); break; //trunc.w.s
fpr.MapDirtyIn(fd, fs);
FRIZ(fpr.R(fd), fpr.R(fs));
break;
/*
case 12: // FsI(fd) = (int)floorf(F(fs)+0.5f); break; //round.w.s
case 14: // FsI(fd) = (int)ceilf (F(fs)); break; //ceil.w.s
case 15: // FsI(fd) = (int)floorf(F(fs)); break; //floor.w.s
case 32: // F(fd) = (float)FsI(fs); break; //cvt.s.w
case 36:
//switch (currentMIPS->fcr31 & 3)
//{
//case 0: FsI(fd) = (int)round_ieee_754(F(fs)); break; // RINT_0
//case 1: FsI(fd) = (int)F(fs); break; // CAST_1
//case 2: FsI(fd) = (int)ceilf(F(fs)); break; // CEIL_2
//case 3: FsI(fd) = (int)floorf(F(fs)); break; // FLOOR_3
//}
//break; //cvt.w.s
*/
default:
Comp_Generic(op);
break;
@ -399,11 +426,11 @@ void Jit::Comp_mxc1(MIPSOpcode op) {
// RT = RT | SREG
OR(_rt, _rt, SREG);
}
else if (fs == 0)
{
gpr.MapReg(rt, MAP_DIRTY | MAP_NOINIT);
LWZ(gpr.R(rt), CTXREG, offsetof(MIPSState, fcr0));
} else if (fs == 0) {
gpr.SetImm(rt, MIPSState::FCR0_VALUE);
} else {
// Unsupported regs are always 0.
gpr.SetImm(rt, 0);
}
return;

View File

@ -1,4 +1,5 @@
#include "Common/ChunkFile.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/MIPS/MIPS.h"
@ -43,6 +44,7 @@ void Jit::SetRegToEffectiveAddress(PpcGen::PPCReg r, int rs, s16 offset) {
}
void Jit::Comp_ITypeMem(MIPSOpcode op) {
CONDITIONAL_DISABLE;
int offset = (signed short)(op&0xFFFF);
bool load = false;
int rt = _RT;
@ -53,6 +55,10 @@ void Jit::Comp_ITypeMem(MIPSOpcode op) {
return;
}
if (!g_Config.bFastMemory) {
DISABLE;
}
u32 iaddr = gpr.IsImm(rs) ? offset + gpr.GetImm(rs) : 0xFFFFFFFF;
bool doCheck = false;
@ -139,10 +145,8 @@ void Jit::Comp_ITypeMem(MIPSOpcode op) {
return ;
}
}
}
void Jit::Comp_Cache(MIPSOpcode op) {
CONDITIONAL_DISABLE;
// TODO: Could use this as a hint, and technically required to handle icache, etc.
// But right now Int_Cache does nothing, so let's not even call it.
void Jit::Comp_Cache(MIPSOpcode op) {
DISABLE;
}
}

View File

@ -2,6 +2,7 @@
#include "math/math_util.h"
#include "Common/ChunkFile.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/MIPS/MIPS.h"
@ -173,6 +174,10 @@ namespace MIPSComp
int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5);
int rs = _RS;
if (!g_Config.bFastMemory) {
DISABLE;
}
bool doCheck = false;
switch (op >> 26)
{
@ -221,6 +226,10 @@ namespace MIPSComp
int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);
int rs = _RS;
if (!g_Config.bFastMemory) {
DISABLE;
}
bool doCheck = false;
switch (op >> 26)
{
@ -945,7 +954,75 @@ namespace MIPSComp
}
void Jit::Comp_Vi2f(MIPSOpcode op) {
DISABLE;
//DISABLE;
CONDITIONAL_DISABLE;
if (js.HasUnknownPrefix() || disablePrefixes)
DISABLE;
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
int imm = (op >> 16) & 0x1f;
const float mult = 1.0f / (float)(1UL << imm);
u8 sregs[4], dregs[4];
GetVectorRegsPrefixS(sregs, sz, _VS);
GetVectorRegsPrefixD(dregs, sz, _VD);
MIPSReg tempregs[4];
for (int i = 0; i < n; ++i) {
if (!IsOverlapSafe(dregs[i], i, n, sregs)) {
tempregs[i] = fpr.GetTempV();
} else {
tempregs[i] = dregs[i];
}
}
if (mult != 1.0f)
MOVI2F(FPR5, mult, false);
u64 tmp = 0;
MOVI2R(SREG, (u32)&tmp);
//Break();
for (int i = 0; i < n; i++) {
// Crappy code !!
fpr.MapDirtyInV(tempregs[i], sregs[i]);
// float => mem
SFS(fpr.V(sregs[i]), SREG, 0);
// int <= mem
LWZ(R6, SREG, 0);
//RLDICL(R6, R6, 0, 23);
EXTSW(R6, R6);
// int => mem
STD(R6, SREG, 0);
// float <= mem
LFD(fpr.V(tempregs[i]), SREG, 0);
FCFID(fpr.V(tempregs[i]), fpr.V(tempregs[i]));
FRSP(fpr.V(tempregs[i]), fpr.V(tempregs[i]));
if (mult != 1.0f)
FMULS(fpr.V(tempregs[i]), fpr.V(tempregs[i]), FPR5);
}
//Break();
for (int i = 0; i < n; ++i) {
if (dregs[i] != tempregs[i]) {
fpr.MapDirtyInV(dregs[i], tempregs[i]);
FMR(fpr.V(dregs[i]), fpr.V(tempregs[i]));
}
}
ApplyPrefixD(dregs, sz);
fpr.ReleaseSpillLocksAndDiscardTemps();
}
void Jit::Comp_Vh2f(MIPSOpcode op) {

View File

@ -234,7 +234,7 @@ Jit::Jit(MIPSState *mips) : blocks(mips, this), gpr(mips, &jo),fpr(mips),mips_(m
void Jit::RunLoopUntil(u64 globalticks) {
#ifdef _XBOX
// force stack alinement
_alloca(16*1024);
//_alloca(16*1024);
#endif
// Run the compiled code

View File

@ -95,7 +95,7 @@ enum
SCRATCHPAD_SIZE = 0x4000,
SCRATCHPAD_MASK = SCRATCHPAD_SIZE - 1,
#if defined(_M_IX86) || defined(_M_ARM32) || defined (_XBOX)
#if defined(_M_IX86) || defined(_M_ARM32) || defined(_XBOX)
// This wraparound should work for PSP too.
MEMVIEW32_MASK = 0x3FFFFFFF,
#endif

View File

@ -31,9 +31,11 @@
#include "GPU/GPUState.h"
#include "GPU/GLES/Framebuffer.h"
#ifndef _XBOX
#include "net/http_client.h"
#include "net/resolve.h"
#include "net/url.h"
#endif
#include "base/buffer.h"
#include "thread/thread.h"
@ -42,6 +44,13 @@
#include <stdlib.h>
#include <cstdarg>
#ifdef _XBOX
namespace Reporting
{
bool IsEnabled() { return false;}
void ReportMessage(const char *message, ...) { }
}
#else
namespace Reporting
{
const int DEFAULT_PORT = 80;
@ -381,3 +390,5 @@ namespace Reporting
}
}
#endif

View File

@ -17,7 +17,9 @@
#ifdef _WIN32
#include "Common/CommonWindows.h"
#ifndef _XBOX
#include <ShlObj.h>
#endif
#include <string>
#include <codecvt>
#endif
@ -324,6 +326,11 @@ bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
Core_ListenShutdown(System_Wake);
CPU_SetState(CPU_THREAD_PENDING);
cpuThread = new std::thread(&CPU_RunLoop);
#ifdef _XBOX
SuspendThread(cpuThread->native_handle());
XSetThreadProcessor(cpuThread->native_handle(), 2);
ResumeThread(cpuThread->native_handle());
#endif
cpuThread->detach();
} else {
CPU_Init();
@ -468,7 +475,7 @@ std::string GetSysDirectory(PSPDirectories directoryType) {
}
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(_XBOX)
// Run this at startup time. Please use GetSysDirectory if you need to query where folders are.
void InitSysDirectories() {
if (!g_Config.memCardDirectory.empty() && !g_Config.flash0Directory.empty())

11
Core/x360_compat.h Normal file
View File

@ -0,0 +1,11 @@
#include <xtl.h>
#undef min
#undef max
extern "C" void _ReadWriteBarrier();
#pragma intrinsic(_ReadWriteBarrier)
extern "C" void _WriteBarrier();
#pragma intrinsic(_WriteBarrier)