Merge branch 'master' of https://github.com/hrydgard/ppsspp into Assembler

This commit is contained in:
Kingcom committed 2013-07-28 15:16:18 +02:00
commit 961905cce8
24 files changed
+391 -198

No files matched your search

+11 -12
View File
@@ -30,19 +30,18 @@ const int SCE_ERROR_UTILITY_INVALID_STATUS = 0x80110001;
const int SCE_ERROR_UTILITY_INVALID_PARAM_SIZE = 0x80110004;
const int SCE_ERROR_UTILITY_WRONG_TYPE = 0x80110005;
typedef struct
struct pspUtilityDialogCommon
{
unsigned int size; /** Size of the structure */
int language; /** Language */
int buttonSwap; /** Set to 1 for X/O button swap */
int graphicsThread; /** Graphics thread priority */
int accessThread; /** Access/fileio thread priority (SceJobThread) */
int fontThread; /** Font thread priority (ScePafThread) */
int soundThread; /** Sound thread priority */
int result; /** Result */
int reserved[4]; /** Set to 0 */
} pspUtilityDialogCommon;
u32_le size; /** Size of the structure */
s32_le language; /** Language */
s32_le buttonSwap; /** Set to 1 for X/O button swap */
s32_le graphicsThread; /** Graphics thread priority */
s32_le accessThread; /** Access/fileio thread priority (SceJobThread) */
s32_le fontThread; /** Font thread priority (ScePafThread) */
s32_le soundThread; /** Sound thread priority */
s32_le result; /** Result */
s32_le reserved[4]; /** Set to 0 */
};
class PSPDialog
+6 -6
View File
@@ -39,15 +39,15 @@
struct pspMessageDialog
{
pspUtilityDialogCommon common;
int result;
int type;
unsigned int errorNum;
s32_le result;
s32_le type;
u32_le errorNum;
char string[512];
// End of request V1 (Size 572)
unsigned int options;
unsigned int buttonPressed;
u32_le options;
u32_le buttonPressed;
// End of request V2 (Size 580)
int unknown[32];
s32_le unknown[32];
// End of request V3 (Size 708)
};
+2 -2
View File
@@ -126,7 +126,7 @@ PSPOskDialog::PSPOskDialog() : PSPDialog() {
PSPOskDialog::~PSPOskDialog() {
}
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16> em_address)
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le> em_address)
{
if (!em_address.IsValid())
{
@@ -839,7 +839,7 @@ int PSPOskDialog::Update()
status = SCE_UTILITY_STATUS_SHUTDOWN;
}
u16 *outText = oskParams->fields[0].outtext;
u16_le *outText = oskParams->fields[0].outtext;
for (u32 i = 0, end = oskParams->fields[0].outtextlength; i < end; ++i)
{
u16 value = 0;
+28 -20
View File
@@ -17,9 +17,9 @@
#pragma once
#include "PSPDialog.h"
#include "../Core/MemMap.h"
#include "Core/Dialog/PSPDialog.h"
#include "Core/MemMap.h"
#include "Common/CommonTypes.h"
/**
@@ -91,37 +91,45 @@ enum SceUtilityOskInputType
PSP_UTILITY_OSK_INPUTTYPE_URL = 0x00080000
};
#if COMMON_LITTLE_ENDIAN
typedef SceUtilityOskState SceUtilityOskState_le;
typedef SceUtilityOskInputLanguage SceUtilityOskInputLanguage_le;
typedef SceUtilityOskResult SceUtilityOskResult_le;
#else
#error FIX ME
#endif
/**
* OSK Field data
*/
struct SceUtilityOskData
{
/** Unknown. Pass 0. */
int unk_00;
s32_le unk_00;
/** Unknown. Pass 0. */
int unk_04;
s32_le unk_04;
/** One of ::SceUtilityOskInputLanguage */
int language;
SceUtilityOskInputLanguage_le language;
/** Unknown. Pass 0. */
int unk_12;
s32_le unk_12;
/** One or more of ::SceUtilityOskInputType (types that are selectable by pressing SELECT) */
int inputtype;
s32_le inputtype;
/** Number of lines */
int lines;
s32_le lines;
/** Unknown. Pass 0. */
int unk_24;
s32_le unk_24;
/** Description text */
PSPPointer<u16> desc;
PSPPointer<u16_le> desc;
/** Initial text */
PSPPointer<u16> intext;
PSPPointer<u16_le> intext;
// Length, in unsigned shorts, including the terminator.
u32 outtextlength;
u32_le outtextlength;
/** Pointer to the output text */
PSPPointer<u16> outtext;
PSPPointer<u16_le> outtext;
/** Result. One of ::SceUtilityOskResult */
int result;
SceUtilityOskResult_le result;
// Number of characters to allow, not including terminator (if less than outtextlength - 1.)
u32 outtextlimit;
u32_le outtextlimit;
};
// Parameters to sceUtilityOskInitStart
@@ -129,12 +137,12 @@ struct SceUtilityOskParams
{
pspUtilityDialogCommon base;
// Number of fields.
int fieldCount;
s32_le fieldCount;
// Pointer to an array of fields (see SceUtilityOskData.)
PSPPointer<SceUtilityOskData> fields;
SceUtilityOskState state;
SceUtilityOskState_le state;
// Maybe just padding?
int unk_60;
s32_le unk_60;
};
@@ -165,7 +173,7 @@ public:
virtual pspUtilityDialogCommon *GetCommonParam();
private:
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16> em_address);
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le> em_address);
void ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input);
void RenderKeyboard();
+2 -2
View File
@@ -56,7 +56,7 @@ int PSPSaveDialog::Init(int paramAddr)
u32 retval = param.SetPspParam(&request);
INFO_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", paramAddr);
INFO_LOG(HLE,"Mode: %i", param.GetPspParam()->mode);
INFO_LOG(HLE,"Mode: %i", (SceUtilitySavedataType)param.GetPspParam()->mode);
yesnoChoice = 1;
switch (param.GetPspParam()->focus)
@@ -164,7 +164,7 @@ int PSPSaveDialog::Init(int paramAddr)
break;
default:
{
ERROR_LOG_REPORT(HLE, "Load/Save function %d not coded. Title: %s Save: %s File: %s", param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
ERROR_LOG_REPORT(HLE, "Load/Save function %d not coded. Title: %s Save: %s File: %s", (SceUtilitySavedataType)param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
param.GetPspParam()->common.result = 0;
status = SCE_UTILITY_STATUS_INITIALIZE;
display = DS_NONE;
+46 -37
View File
@@ -21,6 +21,8 @@
#include "Core/HLE/sceRtc.h"
#include "Core/System.h"
#include "Core/Dialog/PSPDialog.h"
#include "Common/CommonTypes.h"
#undef st_ctime
#undef st_atime
#undef st_mtime
@@ -65,6 +67,13 @@ enum SceUtilitySavedataFocus
SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY = 8, // last empty (what if no empty?)
};
#if COMMON_LITTLE_ENDIAN
typedef SceUtilitySavedataType SceUtilitySavedataType_le;
typedef SceUtilitySavedataFocus SceUtilitySavedataFocus_le;
#else
#error FIX ME
#endif
typedef char SceUtilitySavedataSaveName[20];
// title, savedataTitle, detail: parts of the unencrypted SFO
@@ -80,34 +89,34 @@ struct PspUtilitySavedataSFOParam
struct PspUtilitySavedataFileData {
PSPPointer<u8> buf;
SceSize bufSize; // Size of the buffer pointed to by buf
SceSize size; // Actual file size to write / was read
int unknown;
SceSize_le bufSize; // Size of the buffer pointed to by buf
SceSize_le size; // Actual file size to write / was read
s32_le unknown;
};
struct PspUtilitySavedataSizeEntry {
u64 size;
u64_le size;
char name[16];
};
struct PspUtilitySavedataSizeInfo {
int numSecureEntries;
int numNormalEntries;
s32_le numSecureEntries;
s32_le numNormalEntries;
PSPPointer<PspUtilitySavedataSizeEntry> secureEntries;
PSPPointer<PspUtilitySavedataSizeEntry> normalEntries;
int sectorSize;
int freeSectors;
int freeKB;
s32_le sectorSize;
s32_le freeSectors;
s32_le freeKB;
char freeString[8];
int neededKB;
s32_le neededKB;
char neededString[8];
int overwriteKB;
s32_le overwriteKB;
char overwriteString[8];
};
struct SceUtilitySavedataIdListEntry
{
int st_mode;
s32_le st_mode;
ScePspDateTime st_ctime;
ScePspDateTime st_atime;
ScePspDateTime st_mtime;
@@ -116,15 +125,15 @@ struct SceUtilitySavedataIdListEntry
struct SceUtilitySavedataIdListInfo
{
int maxCount;
int resultCount;
s32_le maxCount;
s32_le resultCount;
PSPPointer<SceUtilitySavedataIdListEntry> entries;
};
struct SceUtilitySavedataFileListEntry
{
int st_mode;
u64 st_size;
s32_le st_mode;
u64_le st_size;
ScePspDateTime st_ctime;
ScePspDateTime st_atime;
ScePspDateTime st_mtime;
@@ -133,12 +142,12 @@ struct SceUtilitySavedataFileListEntry
struct SceUtilitySavedataFileListInfo
{
u32 maxSecureEntries;
u32 maxNormalEntries;
u32 maxSystemEntries;
u32 resultNumSecureEntries;
u32 resultNumNormalEntries;
u32 resultNumSystemEntries;
u32_le maxSecureEntries;
u32_le maxNormalEntries;
u32_le maxSystemEntries;
u32_le resultNumSecureEntries;
u32_le resultNumNormalEntries;
u32_le resultNumSystemEntries;
PSPPointer<SceUtilitySavedataFileListEntry> secureEntries;
PSPPointer<SceUtilitySavedataFileListEntry> normalEntries;
PSPPointer<SceUtilitySavedataFileListEntry> systemEntries;
@@ -146,18 +155,18 @@ struct SceUtilitySavedataFileListInfo
struct SceUtilitySavedataMsFreeInfo
{
int clusterSize;
int freeClusters;
int freeSpaceKB;
s32_le clusterSize;
s32_le freeClusters;
s32_le freeSpaceKB;
char freeSpaceStr[8];
};
struct SceUtilitySavedataUsedDataInfo
{
int usedClusters;
int usedSpaceKB;
s32_le usedClusters;
s32_le usedSpaceKB;
char usedSpaceStr[8];
int usedSpace32KB;
s32_le usedSpace32KB;
char usedSpace32Str[8];
};
@@ -174,10 +183,10 @@ struct SceUtilitySavedataParam
{
pspUtilityDialogCommon common;
int mode; // 0 to load, 1 to save
int bind;
SceUtilitySavedataType_le mode; // 0 to load, 1 to save
s32_le bind;
int overwriteMode; // use 0x10 ?
s32_le overwriteMode; // use 0x10 ?
/** gameName: name used from the game for saves, equal for all saves */
char gameName[13];
@@ -192,8 +201,8 @@ struct SceUtilitySavedataParam
/** pointer to a buffer that will contain data file unencrypted data */
PSPPointer<u8> dataBuf;
/** size of allocated space to dataBuf */
SceSize dataBufSize;
SceSize dataSize; // Size of the actual save data
SceSize_le dataBufSize;
SceSize_le dataSize; // Size of the actual save data
PspUtilitySavedataSFOParam sfoParam;
@@ -203,8 +212,8 @@ struct SceUtilitySavedataParam
PspUtilitySavedataFileData snd0FileData;
PSPPointer<PspUtilitySavedataFileData> newData;
int focus;
int abortStatus;
SceUtilitySavedataFocus_le focus;
s32_le abortStatus;
// Function SCE_UTILITY_SAVEDATA_TYPE_SIZES
PSPPointer<SceUtilitySavedataMsFreeInfo> msFree;
@@ -213,8 +222,8 @@ struct SceUtilitySavedataParam
u8 key[16];
int secureVersion;
int multiStatus;
s32_le secureVersion;
s32_le multiStatus;
// Function 11 LIST
PSPPointer<SceUtilitySavedataIdListInfo> idList;
+22 -13
View File
@@ -70,23 +70,23 @@ bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
// compressed ISO(9660) header format
typedef struct ciso_header
{
unsigned char magic[4]; // +00 : 'C','I','S','O'
u32 header_size; // +04 : header size (==0x18)
u64 total_bytes; // +08 : number of original data size
u32 block_size; // +10 : number of compressed block size
unsigned char ver; // +14 : version 01
unsigned char align; // +15 : align of index value
unsigned char rsv_06[2]; // +16 : reserved
unsigned char magic[4]; // +00 : 'C','I','S','O'
u32_le header_size; // +04 : header size (==0x18)
u64_le total_bytes; // +08 : number of original data size
u32_le block_size; // +10 : number of compressed block size
unsigned char ver; // +14 : version 01
unsigned char align; // +15 : align of index value
unsigned char rsv_06[2]; // +16 : reserved
#if 0
// INDEX BLOCK
unsigned int index[0]; // +18 : block[0] index
unsigned int index[1]; // +1C : block[1] index
unsigned int index[0]; // +18 : block[0] index
unsigned int index[1]; // +1C : block[1] index
:
:
unsigned int index[last]; // +?? : block[last]
unsigned int index[last+1]; // +?? : end of last data point
unsigned int index[last]; // +?? : block[last]
unsigned int index[last+1]; // +?? : end of last data point
// DATA BLOCK
unsigned char data[]; // +?? : compressed or plain sector data
unsigned char data[]; // +?? : compressed or plain sector data
#endif
} CISO_H;
@@ -128,9 +128,18 @@ CISOFileBlockDevice::CISOFileBlockDevice(FILE *file)
u32 indexSize = numBlocks + 1;
#if COMMON_LITTLE_ENDIAN
index = new u32[indexSize];
if(fread(index, sizeof(u32), indexSize, f) != indexSize)
if (fread(index, sizeof(u32), indexSize, f) != indexSize)
memset(index, 0, indexSize * sizeof(u32));
#else
index = new u32[indexSize];
u32_le *indexTemp = new u32_le[indexSize];
if (fread(indexTemp, sizeof(u32), indexSize, f) != indexSize)
memset(indexTemp, 0, indexSize * sizeof(u32_le));
for (u32 i = 0; i < indexSize; i++)
index[i] = indexTemp[i];
#endif
}
CISOFileBlockDevice::~CISOFileBlockDevice()
+34 -6
View File
@@ -81,6 +81,34 @@ struct DirectoryEntry
u16 volSeqNumberBE;
u8 identifierLength; //identifier comes right after
u8 firstIdChar;
#if COMMON_LITTLE_ENDIAN
u32 firstDataSector() const
{
return firstDataSectorLE;
}
u32 dataLength() const
{
return dataLengthLE;
}
u32 volSeqNumber() const
{
return volSeqNumberLE;
}
#else
u32 firstDataSector() const
{
return firstDataSectorBE;
}
u32 dataLength() const
{
return dataLengthBE;
}
u32 volSeqNumber() const
{
return volSeqNumberBE;
}
#endif
};
struct DirectorySector
{
@@ -175,8 +203,8 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic
treeroot->flags = 0;
treeroot->parent = NULL;
u32 rootSector = desc.root.firstDataSectorLE;
u32 rootSize = desc.root.dataLengthLE;
u32 rootSector = desc.root.firstDataSector();
u32 rootSize = desc.root.dataLength();
ReadDirectory(rootSector, rootSize, treeroot, 0);
}
@@ -232,8 +260,8 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root,
relative = false;
}
e->size = dir.dataLengthLE;
e->startingPosition = dir.firstDataSectorLE * 2048;
e->size = dir.dataLength();
e->startingPosition = dir.firstDataSector() * 2048;
e->isDirectory = !isFile;
e->flags = dir.flags;
e->parent = root;
@@ -243,7 +271,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root,
if (e->isDirectory && !relative)
{
if (dir.firstDataSectorLE == startsector)
if (dir.firstDataSector() == startsector)
{
ERROR_LOG(FILESYS, "WARNING: Appear to have a recursive file system, breaking recursion");
}
@@ -254,7 +282,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root,
doRecurse = level < restrictTree.size() && restrictTree[level] == e->name;
if (doRecurse)
ReadDirectory(dir.firstDataSectorLE, dir.dataLengthLE, e, level + 1);
ReadDirectory(dir.firstDataSector(), dir.dataLength(), e, level + 1);
else
continue;
}
+8 -8
View File
@@ -47,19 +47,19 @@ enum
// Returned control data
struct _ctrl_data
{
u32 frame;
u32 buttons;
u32_le frame;
u32_le buttons;
// The PSP has only one stick, but has space for more info.
// The second stick is populated for HD remasters and possibly in the PSP emulator on PS3/Vita.
u8 analog[2][2];
u8 unused[4];
u8 analog[2][2];
u8 unused[4];
};
struct CtrlLatch {
u32 btnMake;
u32 btnBreak;
u32 btnPress;
u32 btnRelease;
u32_le btnMake;
u32_le btnBreak;
u32_le btnPress;
u32_le btnRelease;
};
+10 -10
View File
@@ -121,19 +121,19 @@ enum {
#endif
struct SceIoStat {
SceMode st_mode;
unsigned int st_attr;
SceOff st_size;
SceMode_le st_mode;
u32_le st_attr;
SceOff_le st_size;
ScePspDateTime st_ctime;
ScePspDateTime st_atime;
ScePspDateTime st_mtime;
unsigned int st_private[6];
u32_le st_private[6];
};
struct SceIoDirEnt {
SceIoStat d_stat;
char d_name[256];
u32 d_private;
u32_le d_private;
};
#ifndef __SYMBIAN32__
struct dirent {
@@ -892,11 +892,11 @@ u32 sceIoSync(const char *devicename, int flag) {
}
struct DeviceSize {
u32 maxClusters;
u32 freeClusters;
u32 maxSectors;
u32 sectorSize;
u32 sectorCount;
u32_le maxClusters;
u32_le freeClusters;
u32_le maxSectors;
u32_le sectorSize;
u32_le sectorCount;
};
u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 outPtr, int outLen) {
+11 -11
View File
@@ -78,17 +78,17 @@ struct SceMpegAu {
// As native in PSP ram
struct SceMpegRingBuffer {
// PSP info
int packets;
int packetsRead;
int packetsWritten;
int packetsFree; // pspsdk: unk2, noxa: iUnk0
int packetSize; // 2048
int data; // address, ring buffer
u32 callback_addr; // see sceMpegRingbufferPut
int callback_args;
int dataUpperBound;
int semaID; // unused?
u32 mpeg; // pointer to mpeg struct, fixed up in sceMpegCreate
s32_le packets;
s32_le packetsRead;
s32_le packetsWritten;
s32_le packetsFree; // pspsdk: unk2, noxa: iUnk0
s32_le packetSize; // 2048
s32_le data; // address, ring buffer
u32_le callback_addr; // see sceMpegRingbufferPut
s32_le callback_args;
s32_le dataUpperBound;
s32_le semaID; // unused?
u32_le mpeg; // pointer to mpeg struct, fixed up in sceMpegCreate
};
void __MpegInit();
+5 -5
View File
@@ -72,21 +72,21 @@ enum {
// These might come in handy in the future, if PPSSPP ever supports wifi/ad-hoc..
struct SceNetAdhocctlParams {
int channel; //which ad-hoc channel to connect to
s32_le channel; //which ad-hoc channel to connect to
char name[8]; //connection name
u8 bssid[6]; //BSSID of the connection?
char nickname[128]; //PSP's nickname?
};
struct ProductStruct {
int unknown; // Unknown, set to 0
s32_le unknown; // Unknown, set to 0
char product[9]; // Game ID (Example: ULUS10000)
};
struct SceNetMallocStat {
int pool; // Pointer to the pool?
int maximum; // Maximum size of the pool?
int free; // How much memory is free
s32_le pool; // Pointer to the pool?
s32_le maximum; // Maximum size of the pool?
s32_le free; // How much memory is free
};
static struct SceNetMallocStat netMallocStat;
+16 -15
View File
@@ -67,24 +67,25 @@ enum PsmfPlayerStatus {
};
struct PsmfData {
u32 version;
u32 headerSize;
u32 headerOffset;
u32 streamSize;
u32 streamOffset;
u32 streamNum;
u32 unk1;
u32 unk2;
u32_le version;
u32_le headerSize;
u32_le headerOffset;
u32_le streamSize;
u32_le streamOffset;
u32_le streamNum;
u32_le unk1;
u32_le unk2;
};
struct PsmfPlayerData {
int videoCodec;
int videoStreamNum;
int audioCodec;
int audioStreamNum;
int playMode;
int playSpeed;
long psmfPlayerLastTimestamp;
s32_le videoCodec;
s32_le videoStreamNum;
s32_le audioCodec;
s32_le audioStreamNum;
s32_le playMode;
s32_le playSpeed;
// TODO: Was "long", which is 32, but should this be 64? Not even used?
s32_le psmfPlayerLastTimestamp;
};
struct PsmfEntry {
+6 -7
View File
@@ -47,8 +47,8 @@ static int umdStatChangeEvent = -1;
static std::vector<UmdWaitingThread> umdWaitingThreads;
struct PspUmdInfo {
u32 size;
u32 type;
u32_le size;
u32_le type;
};
void __UmdStatTimeout(u64 userdata, int cyclesLate);
@@ -146,13 +146,12 @@ u32 sceUmdGetDiscInfo(u32 infoAddr)
DEBUG_LOG(HLE, "sceUmdGetDiscInfo(%08x)", infoAddr);
if (Memory::IsValidAddress(infoAddr)) {
PspUmdInfo info;
Memory::ReadStruct(infoAddr, &info);
if (info.size != 8)
PSPPointer<PspUmdInfo> info;
info = infoAddr;
if (info->size != 8)
return PSP_ERROR_UMD_INVALID_PARAM;
info.type = PSP_UMD_TYPE_GAME;
Memory::WriteStruct(infoAddr, &info);
info->type = PSP_UMD_TYPE_GAME;
return 0;
} else
return PSP_ERROR_UMD_INVALID_PARAM;
+1 -1
View File
@@ -74,7 +74,7 @@ EmuFileType Identify_File(std::string &filename)
}
u32 id;
u32_le id;
size_t readSize = fread(&id, 4, 1, f);
if (readSize != 1) {
+2
View File
@@ -91,6 +91,7 @@ void Jit::Comp_FPULS(u32 op)
switch(op >> 26)
{
case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1
fpr.SpillLock(ft);
fpr.MapReg(ft, MAP_NOINIT | MAP_DIRTY);
if (gpr.IsImm(rs)) {
u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF;
@@ -124,6 +125,7 @@ void Jit::Comp_FPULS(u32 op)
SetCC(CC_AL);
}
#endif
fpr.ReleaseSpillLock(ft);
break;
case 57: //Memory::Write_U32(FI(ft), addr); break; //swc1
+94 -3
View File
@@ -772,11 +772,77 @@ namespace MIPSComp
}
void Jit::Comp_VScl(u32 op) {
DISABLE;
DISABLE; // see todo below
CONDITIONAL_DISABLE;
if (js.HasUnknownPrefix())
DISABLE;
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
u8 sregs[4], dregs[4], scale;
GetVectorRegsPrefixS(sregs, sz, _VS);
// TODO: Prefixes seem strange...
GetVectorRegsPrefixT(&scale, V_Single, _VT);
GetVectorRegsPrefixD(dregs, sz, _VD);
// Move to XMM0 early, so we don't have to worry about overlap with scale.
fpr.SpillLockV(scale);
fpr.MapRegV(scale);
// TODO: need temp registers because of prefixD
for (int i = 0; i < n; ++i)
{
fpr.MapDirtyInV(dregs[i], sregs[i]);
VMUL(fpr.V(dregs[i]), fpr.V(sregs[i]), fpr.V(scale));
}
ApplyPrefixD(dregs, sz);
fpr.ReleaseSpillLocks();
}
void Jit::Comp_Vmmul(u32 op) {
DISABLE;
CONDITIONAL_DISABLE;
// TODO: This probably ignores prefixes?
if (js.MayHavePrefix()) {
DISABLE;
}
MatrixSize sz = GetMtxSize(op);
int n = GetMatrixSide(sz);
u8 sregs[16], tregs[16], dregs[16];
GetMatrixRegs(sregs, sz, _VS);
GetMatrixRegs(tregs, sz, _VT);
GetMatrixRegs(dregs, sz, _VD);
// Rough overlap check.
bool overlap = false;
if (GetMtx(_VS) == GetMtx(_VD) || GetMtx(_VT) == GetMtx(_VD)) {
// Potential overlap (guaranteed for 3x3 or more).
overlap = true;
}
if (overlap) {
DISABLE;
} else {
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
fpr.MapInInV(sregs[b * 4], tregs[a * 4]);
VMUL(S0, fpr.V(sregs[b * 4]), fpr.V(tregs[a * 4]));
for (int c = 1; c < n; c++) {
fpr.MapInInV(sregs[b * 4 + c], tregs[a * 4 + c]);
VMLA(S0, fpr.V(sregs[b * 4 + c]), fpr.V(tregs[a * 4 + c]));
}
fpr.MapRegV(dregs[a * 4 + b], MAP_DIRTY | MAP_NOINIT);
VMOV(fpr.V(dregs[a * 4 + b]), S0);
}
}
fpr.ReleaseSpillLocks();
}
}
void Jit::Comp_Vmscl(u32 op) {
@@ -816,7 +882,32 @@ namespace MIPSComp
}
void Jit::Comp_Vcst(u32 op) {
DISABLE;
CONDITIONAL_DISABLE;
if (js.HasUnknownPrefix())
DISABLE;
// TODO: support prefixes properly
if (js.MayHavePrefix())
DISABLE;
int conNum = (op >> 16) & 0x1f;
int vd = _VD;
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
u8 dregs[4];
GetVectorRegsPrefixD(dregs, sz, _VD);
fpr.MapRegsV(dregs, sz, MAP_NOINIT | MAP_DIRTY);
MOVI2R(R0, (u32)(void *)&cst_constants[conNum]);
VLDR(S0, R0, 0);
for (int i = 0; i < n; ++i)
VMOV(fpr.V(dregs[i]), S0);
ApplyPrefixD(dregs, sz);
fpr.ReleaseSpillLocks();
}
void Jit::Comp_Vhoriz(u32 op) {
+4
View File
@@ -290,6 +290,10 @@ void ArmRegCache::ReleaseSpillLocks() {
}
}
void ArmRegCache::ReleaseSpillLock(MIPSReg reg) {
mr[reg].spillLock = false;
}
ARMReg ArmRegCache::R(int mipsReg) {
if (mr[mipsReg].loc == ML_ARMREG) {
return (ARMReg)mr[mipsReg].reg;
+1
View File
@@ -84,6 +84,7 @@ public:
// Protect the arm register containing a MIPS register from spilling, to ensure that
// it's being kept allocated.
void SpillLock(MIPSReg reg, MIPSReg reg2 = -1, MIPSReg reg3 = -1, MIPSReg reg4 = -1);
void ReleaseSpillLock(MIPSReg reg);
void ReleaseSpillLocks();
void SetImm(MIPSReg reg, u32 immVal);
+20
View File
@@ -15,6 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "base/logging.h"
#include "Common/ArmEmitter.h"
#include "Common/CPUDetect.h"
#include "Core/MIPS/ARM/ArmRegCacheFPU.h"
@@ -182,6 +183,25 @@ void ArmRegCacheFPU::MapRegsV(const u8 *v, VectorSize sz, int flags) {
}
}
void ArmRegCacheFPU::MapInInV(int vs, int vt) {
SpillLockV(vs);
SpillLockV(vt);
MapRegV(vs);
MapRegV(vt);
ReleaseSpillLockV(vs);
ReleaseSpillLockV(vt);
}
void ArmRegCacheFPU::MapDirtyInV(int vd, int vs, bool avoidLoad) {
bool overlap = avoidLoad && (vd == vs);
SpillLockV(vd);
SpillLockV(vs);
MapRegV(vd, MAP_DIRTY | (overlap ? 0 : MAP_NOINIT));
MapRegV(vs);
ReleaseSpillLockV(vd);
ReleaseSpillLockV(vs);
}
void ArmRegCacheFPU::FlushArmReg(ARMReg r) {
int reg = r - S0;
if (ar[reg].mipsReg == -1) {
+2
View File
@@ -79,6 +79,8 @@ public:
// Returns an ARM register containing the requested MIPS register.
ARMReg MapReg(MIPSReg reg, int mapFlags = 0);
void MapInIn(MIPSReg rd, MIPSReg rs);
void MapInInV(int rt, int rs);
void MapDirtyInV(int rd, int rs, bool avoidLoad = true);
void MapDirty(MIPSReg rd);
void MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad = true);
void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad = true);
+5
View File
@@ -60,6 +60,11 @@ void ReadVector(float *rd, VectorSize N, int reg);
void GetVectorRegs(u8 regs[4], VectorSize N, int vectorReg);
void GetMatrixRegs(u8 regs[16], MatrixSize N, int matrixReg);
// Returns a number from 0-7, good for checking overlap for 4x4 matrices.
inline int GetMtx(int matrixReg) {
return (matrixReg >> 2) & 7;
}
VectorSize GetVecSize(u32 op);
MatrixSize GetMtxSize(u32 op);
VectorSize GetHalfVectorSize(VectorSize sz);
+44 -28
View File
@@ -935,36 +935,52 @@ void Jit::Comp_Vmmul(u32 op) {
GetMatrixRegs(tregs, sz, _VT);
GetMatrixRegs(dregs, sz, _VD);
// TODO: test overlap, fix non-optimal.
u8 tempregs[16];
for (int a = 0; a < n; a++)
{
for (int b = 0; b < n; b++)
{
XORPS(XMM0, R(XMM0));
for (int c = 0; c < n; c++)
{
MOVSS(XMM1, fpr.V(sregs[b * 4 + c]));
MULSS(XMM1, fpr.V(tregs[a * 4 + c]));
ADDSS(XMM0, R(XMM1));
}
u8 temp = (u8) fpr.GetTempV();
fpr.MapRegV(temp, MAP_NOINIT | MAP_DIRTY);
MOVSS(fpr.VX(temp), R(XMM0));
fpr.StoreFromRegisterV(temp);
tempregs[a * 4 + b] = temp;
}
}
for (int a = 0; a < n; a++)
{
for (int b = 0; b < n; b++)
{
u8 temp = tempregs[a * 4 + b];
fpr.MapRegV(temp, 0);
MOVSS(fpr.V(dregs[a * 4 + b]), fpr.VX(temp));
}
// Rough overlap check.
bool overlap = false;
if (GetMtx(_VS) == GetMtx(_VD) || GetMtx(_VT) == GetMtx(_VD)) {
// Potential overlap (guaranteed for 3x3 or more).
overlap = true;
}
if (overlap) {
u8 tempregs[16];
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
MOVSS(XMM0, fpr.V(sregs[b * 4]));
MULSS(XMM0, fpr.V(tregs[a * 4]));
for (int c = 1; c < n; c++) {
MOVSS(XMM1, fpr.V(sregs[b * 4 + c]));
MULSS(XMM1, fpr.V(tregs[a * 4 + c]));
ADDSS(XMM0, R(XMM1));
}
u8 temp = (u8) fpr.GetTempV();
fpr.MapRegV(temp, MAP_NOINIT | MAP_DIRTY);
MOVSS(fpr.VX(temp), R(XMM0));
fpr.StoreFromRegisterV(temp);
tempregs[a * 4 + b] = temp;
}
}
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
u8 temp = tempregs[a * 4 + b];
fpr.MapRegV(temp, 0);
MOVSS(fpr.V(dregs[a * 4 + b]), fpr.VX(temp));
}
}
} else {
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
MOVSS(XMM0, fpr.V(sregs[b * 4]));
MULSS(XMM0, fpr.V(tregs[a * 4]));
for (int c = 1; c < n; c++) {
MOVSS(XMM1, fpr.V(sregs[b * 4 + c]));
MULSS(XMM1, fpr.V(tregs[a * 4 + c]));
ADDSS(XMM0, R(XMM1));
}
MOVSS(fpr.V(dregs[a * 4 + b]), XMM0);
}
}
}
fpr.ReleaseSpillLocks();
}
+11 -12
View File
@@ -35,9 +35,9 @@ static int atlasWidth;
static int atlasHeight;
struct PPGeVertex {
u16 u, v;
u32 color;
float x, y, z;
u16_le u, v;
u32_le color;
float_le x, y, z;
};
static u32 savedContextPtr;
@@ -52,8 +52,8 @@ static u32 dataPtr;
static u32 dataWritePtr;
static u32 dataSize = 0x10000; // should be enough for a frame of gui...
static u32 palettePtr;
static u32 paletteSize = 2 * 16;
static PSPPointer<u16_le> palette;
static u32 paletteSize = sizeof(u16) * 16;
// Vertex collector
static u32 vertexStart;
@@ -160,10 +160,9 @@ void __PPGeInit()
dataPtr = __PPGeDoAlloc(dataSize, false, "PPGe Vertex Data");
savedContextPtr = __PPGeDoAlloc(savedContextSize, false, "PPGe Saved Context");
atlasPtr = __PPGeDoAlloc(atlasSize, false, "PPGe Atlas Texture");
palettePtr = __PPGeDoAlloc(paletteSize, false, "PPGe Texture Palette");
palette = __PPGeDoAlloc(paletteSize, false, "PPGe Texture Palette");
// Generate 16-greyscale palette. All PPGe graphics are greyscale so we can use a tiny paletted texture.
u16 *palette = (u16 *)Memory::GetPointer(palettePtr);
for (int i = 0; i < 16; i++) {
int val = i;
palette[i] = (val << 12) | 0xFFF;
@@ -193,7 +192,7 @@ void __PPGeDoState(PointerWrap &p)
p.Do(atlasPtr);
p.Do(atlasWidth);
p.Do(atlasHeight);
p.Do(palettePtr);
p.Do(palette);
p.Do(savedContextPtr);
p.Do(savedContextSize);
@@ -225,8 +224,8 @@ void __PPGeShutdown()
kernelMemory.Free(dlPtr);
if (savedContextPtr)
kernelMemory.Free(savedContextPtr);
if (palettePtr)
kernelMemory.Free(palettePtr);
if (palette)
kernelMemory.Free(palette.ptr);
atlasPtr = 0;
dataPtr = 0;
@@ -728,8 +727,8 @@ void PPGeSetDefaultTexture()
WriteCmd(GE_CMD_TEXTUREMAPENABLE, 1);
int wp2 = GetPow2(atlasWidth);
int hp2 = GetPow2(atlasHeight);
WriteCmd(GE_CMD_CLUTADDR, palettePtr & 0xFFFFF0);
WriteCmd(GE_CMD_CLUTADDRUPPER, (palettePtr & 0xFF000000) >> 8);
WriteCmd(GE_CMD_CLUTADDR, palette.ptr & 0xFFFFF0);
WriteCmd(GE_CMD_CLUTADDRUPPER, (palette.ptr & 0xFF000000) >> 8);
WriteCmd(GE_CMD_CLUTFORMAT, 0x00FF02);
WriteCmd(GE_CMD_LOADCLUT, 2);
WriteCmd(GE_CMD_TEXSIZE0, wp2 | (hp2 << 8));