mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
Merge pull request #5 from AlexAltea/master
Improved debugger, modules and the SPU interpreter
This commit is contained in:
commit
e655999a23
@ -159,6 +159,8 @@ public:
|
||||
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();
|
||||
|
@ -753,6 +753,69 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual wxString ReadRegString(wxString reg)
|
||||
{
|
||||
if (reg.Contains("["))
|
||||
{
|
||||
long reg_index;
|
||||
reg.AfterFirst('[').RemoveLast().ToLong(®_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(®_index);
|
||||
if (reg.StartsWith("GPR") || (reg.StartsWith("FPR")))
|
||||
{
|
||||
unsigned long long reg_value;
|
||||
if (!value.SubString(16,31).ToULongLong(®_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(®_value0, 16)) return false;
|
||||
if (!value.SubString(0,15).ToULongLong(®_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(®_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(®_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:
|
||||
|
@ -674,23 +674,36 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -704,23 +717,30 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -733,19 +753,23 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -798,11 +822,15 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -814,11 +842,15 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -847,11 +879,15 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -1177,15 +1213,24 @@ private:
|
||||
}
|
||||
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)
|
||||
|
@ -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() {}
|
||||
|
||||
@ -249,6 +251,37 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual wxString ReadRegString(wxString reg)
|
||||
{
|
||||
if (reg.Contains("["))
|
||||
{
|
||||
long reg_index;
|
||||
reg.AfterFirst('[').RemoveLast().ToLong(®_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(®_index);
|
||||
if (reg.StartsWith("GPR"))
|
||||
{
|
||||
unsigned long long reg_value0;
|
||||
unsigned long long reg_value1;
|
||||
if (!value.SubString(16,31).ToULongLong(®_value0, 16)) return false;
|
||||
if (!value.SubString(0,15).ToULongLong(®_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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -247,6 +247,16 @@ int cellFsStat(const u32 path_addr, const u32 sb_addr)
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb_addr);
|
||||
|
||||
// Check if path is a mount point. (TODO: Add information in sb_addr)
|
||||
for(u32 i=0; i<Emu.GetVFS().m_devices.GetCount(); ++i)
|
||||
{
|
||||
if (path == Emu.GetVFS().m_devices[i].GetPs3Path().RemoveLast(1))
|
||||
{
|
||||
sys_fs.Log("cellFsFstat: '%s' is a mount point.", path);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
vfsStream* f = Emu.GetVFS().Open(path, vfsRead);
|
||||
if(!f || !f->IsOpened())
|
||||
{
|
||||
@ -322,7 +332,9 @@ int cellFsFstat(u32 fd, u32 sb_addr)
|
||||
|
||||
int cellFsMkdir(u32 path_addr, u32 mode)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
const wxString& ps3_path = Memory.ReadString(path_addr);
|
||||
wxString path;
|
||||
Emu.GetVFS().GetDevice(ps3_path, path);
|
||||
sys_fs.Log("cellFsMkdir(path: %s, mode: 0x%x)", path, mode);
|
||||
if(wxDirExists(path)) return CELL_EEXIST;
|
||||
if(!wxMkdir(path)) return CELL_EBUSY;
|
||||
@ -331,27 +343,36 @@ int cellFsMkdir(u32 path_addr, u32 mode)
|
||||
|
||||
int cellFsRename(u32 from_addr, u32 to_addr)
|
||||
{
|
||||
const wxString& from = Memory.ReadString(from_addr);
|
||||
const wxString& to = Memory.ReadString(to_addr);
|
||||
const wxString& ps3_from = Memory.ReadString(from_addr);
|
||||
const wxString& ps3_to = Memory.ReadString(to_addr);
|
||||
wxString from;
|
||||
wxString to;
|
||||
Emu.GetVFS().GetDevice(ps3_from, from);
|
||||
Emu.GetVFS().GetDevice(ps3_to, to);
|
||||
|
||||
sys_fs.Log("cellFsRename(from: %s, to: %s)", from, to);
|
||||
if(!wxFileExists(from)) return CELL_ENOENT;
|
||||
if(wxFileExists(to)) return CELL_EEXIST;
|
||||
if(!wxRenameFile(from, to)) return CELL_EBUSY;
|
||||
if(!wxRenameFile(from, to)) return CELL_EBUSY; // (TODO: RenameFile(a,b) = CopyFile(a,b) + RemoveFile(a), therefore file "a" will not be removed if it is opened)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsRmdir(u32 path_addr)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
const wxString& ps3_path = Memory.ReadString(path_addr);
|
||||
wxString path;
|
||||
Emu.GetVFS().GetDevice(ps3_path, path);
|
||||
sys_fs.Log("cellFsRmdir(path: %s)", path);
|
||||
if(!wxDirExists(path)) return CELL_ENOENT;
|
||||
if(!wxRmdir(path)) return CELL_EBUSY;
|
||||
if(!wxRmdir(path)) return CELL_EBUSY; // (TODO: Under certain conditions it is not able to delete the folder)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsUnlink(u32 path_addr)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
const wxString& ps3_path = Memory.ReadString(path_addr);
|
||||
wxString path;
|
||||
Emu.GetVFS().GetDevice(ps3_path, path);
|
||||
sys_fs.Error("cellFsUnlink(path: %s)", path);
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -375,3 +396,84 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_addr)
|
||||
Memory.Write64(pos_addr, file.Seek(offset, seek_mode));
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsFtruncate(u32 fd, u64 size)
|
||||
{
|
||||
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
|
||||
ID id;
|
||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
vfsStream& file = *(vfsStream*)id.m_data;
|
||||
u64 initialSize = file.GetSize();
|
||||
|
||||
if (initialSize < size) // Is there any better way to fill the remaining bytes with 0, without allocating huge buffers in memory, or writing such a spaghetti code?
|
||||
{
|
||||
u64 last_pos = file.Tell();
|
||||
file.Seek(0, vfsSeekEnd);
|
||||
char* nullblock = (char*)calloc(4096, sizeof(char));
|
||||
for(u64 i = (size-initialSize)/4096; i > 0; i--){
|
||||
file.Write(nullblock, 4096);
|
||||
}
|
||||
free(nullblock);
|
||||
char nullbyte = 0;
|
||||
for(u64 i = (size-initialSize)%4096; i > 0; i--){
|
||||
file.Write(&nullbyte, 1);
|
||||
}
|
||||
file.Seek(last_pos, vfsSeekSet);
|
||||
}
|
||||
|
||||
if (initialSize > size)
|
||||
{
|
||||
// (TODO)
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsTruncate(u32 path_addr, u64 size)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsTruncate(path_addr: %s, size: %lld)", path, size);
|
||||
|
||||
vfsStream* f = Emu.GetVFS().Open(path, vfsRead);
|
||||
if(!f || !f->IsOpened())
|
||||
{
|
||||
sys_fs.Warning("cellFsTruncate: '%s' not found.", path);
|
||||
Emu.GetVFS().Close(f);
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
u64 initialSize = f->GetSize();
|
||||
|
||||
if (initialSize < size) // Is there any better way to fill the remaining bytes with 0, without allocating huge buffers in memory, or writing such a spaghetti code?
|
||||
{
|
||||
u64 last_pos = f->Tell();
|
||||
f->Seek(0, vfsSeekEnd);
|
||||
char* nullblock = (char*)calloc(4096, sizeof(char));
|
||||
for(u64 i = (size-initialSize)/4096; i > 0; i--){
|
||||
f->Write(nullblock, 4096);
|
||||
}
|
||||
free(nullblock);
|
||||
char nullbyte = 0;
|
||||
for(u64 i = (size-initialSize)%4096; i > 0; i--){
|
||||
f->Write(&nullbyte, 1);
|
||||
}
|
||||
f->Seek(last_pos, vfsSeekSet);
|
||||
}
|
||||
|
||||
if (initialSize > size)
|
||||
{
|
||||
// (TODO)
|
||||
}
|
||||
|
||||
Emu.GetVFS().Close(f);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsFGetBlockSize(u32 fd, u32 sector_size_addr, u32 block_size_addr)
|
||||
{
|
||||
sys_fs.Log("cellFsFGetBlockSize(fd: %d, sector_size_addr: 0x%x, block_size_addr: 0x%x)", fd, sector_size_addr, block_size_addr);
|
||||
|
||||
Memory.Write64(sector_size_addr, 4096); // ?
|
||||
Memory.Write64(block_size_addr, 4096); // ?
|
||||
|
||||
return CELL_OK;
|
||||
}
|
103
rpcs3/Gui/InstructionEditor.cpp
Normal file
103
rpcs3/Gui/InstructionEditor.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
class InstructionEditorDialog
|
||||
: public wxDialog
|
||||
{
|
||||
u64 pc;
|
||||
PPC_DisAsm* disasm;
|
||||
PPC_Decoder* decoder;
|
||||
wxTextCtrl* t2_instr;
|
||||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
PPCThread* CPU;
|
||||
|
||||
public:
|
||||
InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||
|
||||
void updatePreview(wxCommandEvent& event);
|
||||
};
|
||||
|
||||
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
||||
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
|
||||
, pc(_pc)
|
||||
, CPU(_CPU)
|
||||
, decoder(_decoder)
|
||||
, disasm(_disasm)
|
||||
{
|
||||
wxBoxSizer* s_panel_margin_x(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_panel_margin_y(new wxBoxSizer(wxVERTICAL));
|
||||
|
||||
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
|
||||
wxBoxSizer* s_t1_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_t2_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_t3_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
|
||||
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Address: ");
|
||||
wxStaticText* t1_addr = new wxStaticText(this, wxID_ANY, wxString::Format("%08x",pc));
|
||||
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Instruction:");
|
||||
t2_instr = new wxTextCtrl(this, wxID_ANY);
|
||||
wxStaticText* t3_text = new wxStaticText(this, wxID_ANY, "Preview: ");
|
||||
t3_preview = new wxStaticText(this, wxID_ANY, "");
|
||||
|
||||
s_t1_panel->Add(t1_text);
|
||||
s_t1_panel->AddSpacer(8);
|
||||
s_t1_panel->Add(t1_addr);
|
||||
|
||||
s_t2_panel->Add(t2_text);
|
||||
s_t2_panel->AddSpacer(8);
|
||||
s_t2_panel->Add(t2_instr);
|
||||
|
||||
s_t3_panel->Add(t3_text);
|
||||
s_t3_panel->AddSpacer(8);
|
||||
s_t3_panel->Add(t3_preview);
|
||||
|
||||
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
|
||||
s_b_panel->AddSpacer(5);
|
||||
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxRIGHT, 0, 5);
|
||||
|
||||
s_panel->Add(s_t1_panel);
|
||||
s_panel->AddSpacer(8);
|
||||
s_panel->Add(s_t3_panel);
|
||||
s_panel->AddSpacer(8);
|
||||
s_panel->Add(s_t2_panel);
|
||||
s_panel->AddSpacer(16);
|
||||
s_panel->Add(s_b_panel);
|
||||
|
||||
s_panel_margin_y->AddSpacer(12);
|
||||
s_panel_margin_y->Add(s_panel);
|
||||
s_panel_margin_y->AddSpacer(12);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
s_panel_margin_x->Add(s_panel_margin_y);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
|
||||
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
|
||||
t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(CPU->GetOffset() + pc)));
|
||||
|
||||
this->SetSizerAndFit(s_panel_margin_x);
|
||||
|
||||
if(this->ShowModal() == wxID_OK)
|
||||
{
|
||||
unsigned long opcode;
|
||||
if (!t2_instr->GetValue().ToULong(&opcode, 16))
|
||||
wxMessageBox("This instruction could not be parsed.\nNo changes were made.","Error");
|
||||
else
|
||||
Memory.Write32(CPU->GetOffset() + pc, (u32)opcode);
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
|
||||
{
|
||||
unsigned long opcode;
|
||||
if (t2_instr->GetValue().ToULong(&opcode, 16))
|
||||
{
|
||||
decoder->Decode((u32)opcode);
|
||||
wxString preview = disasm->last_opcode;
|
||||
while (preview[0] != ':') preview.Remove(0,1);
|
||||
preview.Remove(0,1);
|
||||
t3_preview->SetLabel(preview);
|
||||
}
|
||||
else
|
||||
{
|
||||
t3_preview->SetLabel("Could not parse instruction.");
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "InterpreterDisAsm.h"
|
||||
|
||||
#include "InstructionEditor.cpp"
|
||||
#include "RegisterEditor.cpp"
|
||||
|
||||
//static const int show_lines = 30;
|
||||
|
||||
u64 InterpreterDisAsmFrame::CentrePc(const u64 pc) const
|
||||
@ -67,6 +70,7 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
|
||||
Connect(m_btn_step->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoStep));
|
||||
Connect(m_btn_run->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoRun));
|
||||
Connect(m_btn_pause->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoPause));
|
||||
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_KEY_DOWN, wxListEventHandler(InterpreterDisAsmFrame::InstrKey));
|
||||
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(InterpreterDisAsmFrame::DClick));
|
||||
Connect(m_choice_units->GetId(),wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(InterpreterDisAsmFrame::OnSelectUnit));
|
||||
Connect(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
|
||||
@ -442,6 +446,27 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
||||
ThreadBase::Start();
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
|
||||
{
|
||||
long i = m_list->GetFirstSelected();
|
||||
if(i < 0) return;
|
||||
|
||||
const u64 start_pc = PC - m_item_count*4;
|
||||
const u64 pc = start_pc + i*4;
|
||||
|
||||
switch(event.GetKeyCode())
|
||||
{
|
||||
case 'E':
|
||||
InstructionEditorDialog(this, pc, CPU, decoder, disasm);
|
||||
DoUpdate();
|
||||
return;
|
||||
case 'R':
|
||||
RegisterEditorDialog(this, pc, CPU, decoder, disasm);
|
||||
DoUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::DClick(wxListEvent& event)
|
||||
{
|
||||
long i = m_list->GetFirstSelected();
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
void DoRun(wxCommandEvent& event);
|
||||
void DoPause(wxCommandEvent& event);
|
||||
void DoStep(wxCommandEvent& event);
|
||||
void InstrKey(wxListEvent& event);
|
||||
void DClick(wxListEvent& event);
|
||||
|
||||
void MouseWheel(wxMouseEvent& event);
|
||||
|
105
rpcs3/Gui/RegisterEditor.cpp
Normal file
105
rpcs3/Gui/RegisterEditor.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
class RegisterEditorDialog
|
||||
: public wxDialog
|
||||
{
|
||||
u64 pc;
|
||||
PPC_DisAsm* disasm;
|
||||
PPC_Decoder* decoder;
|
||||
wxComboBox* t1_register;
|
||||
wxTextCtrl* t2_value;
|
||||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
PPCThread* CPU;
|
||||
|
||||
public:
|
||||
RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||
|
||||
void updateRegister(wxCommandEvent& event);
|
||||
void updatePreview(wxCommandEvent& event);
|
||||
};
|
||||
|
||||
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
||||
: wxDialog(parent, wxID_ANY, "Edit registers", wxDefaultPosition)
|
||||
, pc(_pc)
|
||||
, CPU(_CPU)
|
||||
, decoder(_decoder)
|
||||
, disasm(_disasm)
|
||||
{
|
||||
wxBoxSizer* s_panel_margin_x(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_panel_margin_y(new wxBoxSizer(wxVERTICAL));
|
||||
|
||||
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
|
||||
wxBoxSizer* s_t1_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_t2_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_t3_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||
|
||||
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Register: ");
|
||||
t1_register = new wxComboBox(this, wxID_ANY, wxEmptyString);
|
||||
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Value (Hex):");
|
||||
t2_value = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1));
|
||||
|
||||
s_t1_panel->Add(t1_text);
|
||||
s_t1_panel->AddSpacer(8);
|
||||
s_t1_panel->Add(t1_register);
|
||||
|
||||
s_t2_panel->Add(t2_text);
|
||||
s_t2_panel->AddSpacer(8);
|
||||
s_t2_panel->Add(t2_value);
|
||||
|
||||
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
|
||||
s_b_panel->AddSpacer(5);
|
||||
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxLEFT, 0, 5);
|
||||
|
||||
s_panel->Add(s_t1_panel);
|
||||
s_panel->AddSpacer(8);
|
||||
s_panel->Add(s_t2_panel);
|
||||
s_panel->AddSpacer(16);
|
||||
s_panel->Add(s_b_panel);
|
||||
|
||||
s_panel_margin_y->AddSpacer(12);
|
||||
s_panel_margin_y->Add(s_panel);
|
||||
s_panel_margin_y->AddSpacer(12);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
s_panel_margin_x->Add(s_panel_margin_y);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
|
||||
this->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(RegisterEditorDialog::updateRegister));
|
||||
|
||||
if (CPU->GetType() == PPC_THREAD_PPU)
|
||||
{
|
||||
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("FPR[%d]",i));
|
||||
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("VPR[%d]",i));
|
||||
t1_register->Append("CR");
|
||||
t1_register->Append("LR");
|
||||
t1_register->Append("CTR");
|
||||
t1_register->Append("XER");
|
||||
t1_register->Append("FPSCR");
|
||||
}
|
||||
if (CPU->GetType() == PPC_THREAD_SPU)
|
||||
{
|
||||
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||
}
|
||||
if (CPU->GetType() == PPC_THREAD_RAW_SPU)
|
||||
{
|
||||
wxMessageBox("RawSPU threads not yet supported.","Error");
|
||||
return;
|
||||
}
|
||||
|
||||
this->SetSizerAndFit(s_panel_margin_x);
|
||||
|
||||
if(this->ShowModal() == wxID_OK)
|
||||
{
|
||||
wxString reg = t1_register->GetStringSelection();
|
||||
wxString value = t2_value->GetValue();
|
||||
if (!CPU->WriteRegString(reg,value))
|
||||
wxMessageBox("This value could not be converted.\nNo changes were made.","Error");
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
|
||||
{
|
||||
wxString reg = t1_register->GetStringSelection();
|
||||
t2_value->SetValue(CPU->ReadRegString(reg));
|
||||
}
|
Loading…
Reference in New Issue
Block a user