Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved debugger, modules and the SPU interpreter #5

Merged
merged 7 commits into from Sep 23, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions rpcs3/Emu/Cell/PPCThread.h
Expand Up @@ -159,6 +159,8 @@ class PPCThread : public ThreadBase
void Stop();

virtual wxString RegsToString() { return wxEmptyString; }
virtual wxString ReadRegString(wxString reg) { return wxEmptyString; }
virtual bool WriteRegString(wxString reg, wxString value) { return false; }

virtual void Exec();
void ExecOnce();
Expand Down
63 changes: 63 additions & 0 deletions rpcs3/Emu/Cell/PPUThread.h
Expand Up @@ -753,6 +753,69 @@ class PPUThread
return ret;
}

virtual wxString ReadRegString(wxString reg)
{
if (reg.Contains("["))
{
long reg_index;
reg.AfterFirst('[').RemoveLast().ToLong(&reg_index);
if (reg.StartsWith("GPR")) return wxString::Format("%016llx", GPR[reg_index]);
if (reg.StartsWith("FPR")) return wxString::Format("%016llx", FPR[reg_index]);
if (reg.StartsWith("VPR")) return wxString::Format("%016llx%016llx", VPR[reg_index]._u64[1], VPR[reg_index]._u64[0]);
}
if (reg == "CR") return wxString::Format("%08x", CR);
if (reg == "LR") return wxString::Format("%016llx", LR);
if (reg == "CTR") return wxString::Format("%016llx", CTR);
if (reg == "XER") return wxString::Format("%016llx", XER);
if (reg == "FPSCR") return wxString::Format("%08x", FPSCR);
return wxEmptyString;
}

bool WriteRegString(wxString reg, wxString value) {
while (value.Len() < 32) value = "0"+value;
if (reg.Contains("["))
{
long reg_index;
reg.AfterFirst('[').RemoveLast().ToLong(&reg_index);
if (reg.StartsWith("GPR") || (reg.StartsWith("FPR")))
{
unsigned long long reg_value;
if (!value.SubString(16,31).ToULongLong(&reg_value, 16)) return false;
if (reg.StartsWith("GPR")) GPR[reg_index] = (u64)reg_value;
if (reg.StartsWith("FPR")) FPR[reg_index] = (u64)reg_value;
return true;
}
if (reg.StartsWith("VPR"))
{
unsigned long long reg_value0;
unsigned long long reg_value1;
if (!value.SubString(16,31).ToULongLong(&reg_value0, 16)) return false;
if (!value.SubString(0,15).ToULongLong(&reg_value1, 16)) return false;
VPR[reg_index]._u64[0] = (u64)reg_value0;
VPR[reg_index]._u64[1] = (u64)reg_value1;
return true;
}
}
if (reg == "LR" || reg == "CTR" || reg == "XER")
{
unsigned long long reg_value;
if (!value.SubString(16,31).ToULongLong(&reg_value, 16)) return false;
if (reg == "LR") LR = (u64)reg_value;
if (reg == "CTR") CTR = (u64)reg_value;
if (reg == "XER") XER.XER = (u64)reg_value;
return true;
}
if (reg == "CR" || reg == "FPSCR")
{
unsigned long reg_value;
if (!value.SubString(24,31).ToULong(&reg_value, 16)) return false;
if (reg == "CR") CR.CR = (u32)reg_value;
if (reg == "FPSCR") FPSCR.FPSCR = (u32)reg_value;
return true;
}
return false;
}

virtual void AddArgv(const wxString& arg);

public:
Expand Down
91 changes: 68 additions & 23 deletions rpcs3/Emu/Cell/SPUInterpreter.h
Expand Up @@ -674,23 +674,36 @@ class SPU_Interpreter : public SPU_Opcodes
}
void FCGT(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u32[0] = CPU.GPR[ra]._f[0] > CPU.GPR[rb]._f[0] ? 0xffffffff : 0;
CPU.GPR[rt]._u32[1] = CPU.GPR[ra]._f[1] > CPU.GPR[rb]._f[1] ? 0xffffffff : 0;
CPU.GPR[rt]._u32[2] = CPU.GPR[ra]._f[2] > CPU.GPR[rb]._f[2] ? 0xffffffff : 0;
CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._f[3] > CPU.GPR[rb]._f[3] ? 0xffffffff : 0;
}
void DFCGT(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u64[0] = CPU.GPR[ra]._d[0] > CPU.GPR[rb]._d[0] ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = CPU.GPR[ra]._d[1] > CPU.GPR[rb]._d[1] ? 0xffffffffffffffff : 0;
}
void FA(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] + CPU.GPR[rb]._f[0];
CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] + CPU.GPR[rb]._f[1];
CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] + CPU.GPR[rb]._f[2];
CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] + CPU.GPR[rb]._f[3];
}
void FS(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] - CPU.GPR[rb]._f[0];
CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] - CPU.GPR[rb]._f[1];
CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] - CPU.GPR[rb]._f[2];
CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] - CPU.GPR[rb]._f[3];
}
void FM(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0];
CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1];
CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2];
CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3];
}
void CLGTH(u32 rt, u32 ra, u32 rb)
{
Expand All @@ -704,23 +717,30 @@ class SPU_Interpreter : public SPU_Opcodes
}
void FCMGT(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u32[0] = fabs(CPU.GPR[ra]._f[0]) > fabs(CPU.GPR[rb]._f[0]) ? 0xffffffff : 0;
CPU.GPR[rt]._u32[1] = fabs(CPU.GPR[ra]._f[1]) > fabs(CPU.GPR[rb]._f[1]) ? 0xffffffff : 0;
CPU.GPR[rt]._u32[2] = fabs(CPU.GPR[ra]._f[2]) > fabs(CPU.GPR[rb]._f[2]) ? 0xffffffff : 0;
CPU.GPR[rt]._u32[3] = fabs(CPU.GPR[ra]._f[3]) > fabs(CPU.GPR[rb]._f[3]) ? 0xffffffff : 0;
}
void DFCMGT(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u64[0] = fabs(CPU.GPR[ra]._d[0]) > fabs(CPU.GPR[rb]._d[0]) ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = fabs(CPU.GPR[ra]._d[1]) > fabs(CPU.GPR[rb]._d[1]) ? 0xffffffffffffffff : 0;
}
void DFA(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] = CPU.GPR[ra]._d[0] + CPU.GPR[rb]._d[0];
CPU.GPR[rt]._d[1] = CPU.GPR[ra]._d[1] + CPU.GPR[rb]._d[1];
}
void DFS(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] = CPU.GPR[ra]._d[0] - CPU.GPR[rb]._d[0];
CPU.GPR[rt]._d[1] = CPU.GPR[ra]._d[1] - CPU.GPR[rb]._d[1];
}
void DFM(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] = CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0];
CPU.GPR[rt]._d[1] = CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1];
}
void CLGTB(u32 rt, u32 ra, u32 rb)
{
Expand All @@ -733,19 +753,23 @@ class SPU_Interpreter : public SPU_Opcodes
}
void DFMA(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] += CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0];
CPU.GPR[rt]._d[1] += CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1];
}
void DFMS(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] = CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0] - CPU.GPR[rt]._d[0];
CPU.GPR[rt]._d[1] = CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1] - CPU.GPR[rt]._d[1];
}
void DFNMS(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] -= CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0];
CPU.GPR[rt]._d[1] -= CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1];
}
void DFNMA(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] = - CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0] - CPU.GPR[rt]._d[0] ;
CPU.GPR[rt]._d[1] = - CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1] - CPU.GPR[rt]._d[1] ;
}
void CEQ(u32 rt, u32 ra, u32 rb)
{
Expand Down Expand Up @@ -798,11 +822,15 @@ class SPU_Interpreter : public SPU_Opcodes
}
void FESD(u32 rt, u32 ra)
{
UNIMPLEMENTED();
CPU.GPR[rt]._d[0] = (double)CPU.GPR[ra]._f[0];
CPU.GPR[rt]._d[1] = (double)CPU.GPR[ra]._f[2];
}
void FRDS(u32 rt, u32 ra)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] = (float)CPU.GPR[ra]._d[0];
CPU.GPR[rt]._f[1] = 0x00000000;
CPU.GPR[rt]._f[2] = (float)CPU.GPR[ra]._d[1];
CPU.GPR[rt]._f[3] = 0x00000000;
}
void FSCRWR(u32 rt, u32 ra)
{
Expand All @@ -814,11 +842,15 @@ class SPU_Interpreter : public SPU_Opcodes
}
void FCEQ(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u32[0] = CPU.GPR[ra]._f[0] == CPU.GPR[rb]._f[0] ? 0xffffffff : 0;
CPU.GPR[rt]._u32[1] = CPU.GPR[ra]._f[1] == CPU.GPR[rb]._f[1] ? 0xffffffff : 0;
CPU.GPR[rt]._u32[2] = CPU.GPR[ra]._f[2] == CPU.GPR[rb]._f[2] ? 0xffffffff : 0;
CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._f[3] == CPU.GPR[rb]._f[3] ? 0xffffffff : 0;
}
void DFCEQ(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u64[0] = CPU.GPR[ra]._d[0] == CPU.GPR[rb]._d[0] ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = CPU.GPR[ra]._d[1] == CPU.GPR[rb]._d[1] ? 0xffffffffffffffff : 0;
}
void MPY(u32 rt, u32 ra, u32 rb)
{
Expand Down Expand Up @@ -847,11 +879,15 @@ class SPU_Interpreter : public SPU_Opcodes
}
void FCMEQ(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u32[0] = fabs(CPU.GPR[ra]._f[0]) == fabs(CPU.GPR[rb]._f[0]) ? 0xffffffff : 0;
CPU.GPR[rt]._u32[1] = fabs(CPU.GPR[ra]._f[1]) == fabs(CPU.GPR[rb]._f[1]) ? 0xffffffff : 0;
CPU.GPR[rt]._u32[2] = fabs(CPU.GPR[ra]._f[2]) == fabs(CPU.GPR[rb]._f[2]) ? 0xffffffff : 0;
CPU.GPR[rt]._u32[3] = fabs(CPU.GPR[ra]._f[3]) == fabs(CPU.GPR[rb]._f[3]) ? 0xffffffff : 0;
}
void DFCMEQ(u32 rt, u32 ra, u32 rb)
{
UNIMPLEMENTED();
CPU.GPR[rt]._u64[0] = fabs(CPU.GPR[ra]._d[0]) == fabs(CPU.GPR[rb]._d[0]) ? 0xffffffffffffffff : 0;
CPU.GPR[rt]._u64[1] = fabs(CPU.GPR[ra]._d[1]) == fabs(CPU.GPR[rb]._d[1]) ? 0xffffffffffffffff : 0;
}
void MPYU(u32 rt, u32 ra, u32 rb)
{
Expand Down Expand Up @@ -1177,15 +1213,24 @@ class SPU_Interpreter : public SPU_Opcodes
}
void FNMS(u32 rt, u32 ra, u32 rb, u32 rc)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] -= CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0];
CPU.GPR[rt]._f[1] -= CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1];
CPU.GPR[rt]._f[2] -= CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2];
CPU.GPR[rt]._f[3] -= CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3];
}
void FMA(u32 rc, u32 ra, u32 rb, u32 rt)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] += CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0];
CPU.GPR[rt]._f[1] += CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1];
CPU.GPR[rt]._f[2] += CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2];
CPU.GPR[rt]._f[3] += CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3];
}
void FMS(u32 rc, u32 ra, u32 rb, u32 rt)
{
UNIMPLEMENTED();
CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0] - CPU.GPR[rt]._f[0];
CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1] - CPU.GPR[rt]._f[1];
CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2] - CPU.GPR[rt]._f[2];
CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3] - CPU.GPR[rt]._f[3];
}

void UNK(u32 code, u32 opcode, u32 gcode)
Expand Down
33 changes: 33 additions & 0 deletions rpcs3/Emu/Cell/SPUThread.h
Expand Up @@ -110,6 +110,8 @@ union SPU_GPR_hdr
s16 _i16[8];
u8 _u8[16];
s8 _i8[16];
double _d[2];
float _f[4];

SPU_GPR_hdr() {}

Expand Down Expand Up @@ -249,6 +251,37 @@ class SPUThread : public PPCThread
return ret;
}

virtual wxString ReadRegString(wxString reg)
{
if (reg.Contains("["))
{
long reg_index;
reg.AfterFirst('[').RemoveLast().ToLong(&reg_index);
if (reg.StartsWith("GPR")) return wxString::Format("%016llx%016llx", GPR[reg_index]._u64[1], GPR[reg_index]._u64[0]);
}
return wxEmptyString;
}

bool WriteRegString(wxString reg, wxString value) {
while (value.Len() < 32) value = "0"+value;
if (reg.Contains("["))
{
long reg_index;
reg.AfterFirst('[').RemoveLast().ToLong(&reg_index);
if (reg.StartsWith("GPR"))
{
unsigned long long reg_value0;
unsigned long long reg_value1;
if (!value.SubString(16,31).ToULongLong(&reg_value0, 16)) return false;
if (!value.SubString(0,15).ToULongLong(&reg_value1, 16)) return false;
GPR[reg_index]._u64[0] = (u64)reg_value0;
GPR[reg_index]._u64[1] = (u64)reg_value1;
return true;
}
}
return false;
}

public:
virtual void InitRegs();
virtual u64 GetFreeStackSize() const;
Expand Down
9 changes: 2 additions & 7 deletions rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp
Expand Up @@ -193,14 +193,9 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, u32 data_addr, u32 dataC

//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
int width, height, actual_components;
unsigned char *gif = new unsigned char [fileSize];
for(u32 i = 0; i < fileSize; i++){
gif[i] = Memory.Read8(buffer+i);
}
unsigned char *gif = (unsigned char*)Memory.VirtualToRealAddr(buffer);
unsigned char *image = stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4);
Memory.Free(buffer);

unsigned char *image = stbi_load_from_memory((const unsigned char*)gif, fileSize, &width, &height, &actual_components, 4);
delete[] gif;
if (!image) return CELL_GIFDEC_ERROR_STREAM_FORMAT;

u32 image_size = width * height * 4;
Expand Down
9 changes: 2 additions & 7 deletions rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp
Expand Up @@ -213,14 +213,9 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, u32 data_addr, u32 dataC

//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
int width, height, actual_components;
unsigned char *jpg = new unsigned char [fileSize];
for(u32 i = 0; i < fileSize; i++){
jpg[i] = Memory.Read8(buffer+i);
}
unsigned char *jpg = (unsigned char*)Memory.VirtualToRealAddr(buffer);
unsigned char *image = stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4);
Memory.Free(buffer);

unsigned char *image = stbi_load_from_memory((const unsigned char*)jpg, fileSize, &width, &height, &actual_components, 4);
delete[] jpg;
if (!image) return CELL_JPGDEC_ERROR_STREAM_FORMAT;

u32 image_size = width * height * 4;
Expand Down
9 changes: 2 additions & 7 deletions rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp
Expand Up @@ -198,14 +198,9 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, u32 data_addr, u32 dataC

//Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
int width, height, actual_components;
unsigned char *png = new unsigned char [fileSize];
for(u32 i = 0; i < fileSize; i++){
png[i] = Memory.Read8(buffer+i);
}
unsigned char *png = (unsigned char*)Memory.VirtualToRealAddr(buffer);
unsigned char *image = stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4);
Memory.Free(buffer);

unsigned char *image = stbi_load_from_memory((const unsigned char*)png, fileSize, &width, &height, &actual_components, 4);
delete[] png;
if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT;

u32 image_size = width * height * 4;
Expand Down
3 changes: 3 additions & 0 deletions rpcs3/Emu/SysCalls/Modules/sys_fs.cpp
Expand Up @@ -21,4 +21,7 @@ void sys_fs_init()
sys_fs.AddFunc(0x2796fdf3, cellFsRmdir);
sys_fs.AddFunc(0x7f4677a8, cellFsUnlink);
sys_fs.AddFunc(0xa397d042, cellFsLseek);
sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate);
sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate);
sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize);
}
3 changes: 3 additions & 0 deletions rpcs3/Emu/SysCalls/SysCalls.h
Expand Up @@ -189,6 +189,9 @@ extern int cellFsRename(u32 from_addr, u32 to_addr);
extern int cellFsRmdir(u32 path_addr);
extern int cellFsUnlink(u32 path_addr);
extern int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_addr);
extern int cellFsFtruncate(u32 fd, u64 size);
extern int cellFsTruncate(u32 path_addr, u64 size);
extern int cellFsFGetBlockSize(u32 fd, u32 sector_size_addr, u32 block_size_addr);

//cellVideo
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
Expand Down