mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00: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();
|
void Stop();
|
||||||
|
|
||||||
virtual wxString RegsToString() { return wxEmptyString; }
|
virtual wxString RegsToString() { return wxEmptyString; }
|
||||||
|
virtual wxString ReadRegString(wxString reg) { return wxEmptyString; }
|
||||||
|
virtual bool WriteRegString(wxString reg, wxString value) { return false; }
|
||||||
|
|
||||||
virtual void Exec();
|
virtual void Exec();
|
||||||
void ExecOnce();
|
void ExecOnce();
|
||||||
|
@ -753,6 +753,69 @@ public:
|
|||||||
return ret;
|
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);
|
virtual void AddArgv(const wxString& arg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -674,23 +674,36 @@ private:
|
|||||||
}
|
}
|
||||||
void FCGT(u32 rt, u32 ra, u32 rb)
|
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)
|
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)
|
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)
|
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)
|
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)
|
void CLGTH(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -704,23 +717,30 @@ private:
|
|||||||
}
|
}
|
||||||
void FCMGT(u32 rt, u32 ra, u32 rb)
|
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)
|
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)
|
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)
|
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)
|
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)
|
void CLGTB(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -733,19 +753,23 @@ private:
|
|||||||
}
|
}
|
||||||
void DFMA(u32 rt, u32 ra, u32 rb)
|
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)
|
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)
|
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)
|
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)
|
void CEQ(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -798,11 +822,15 @@ private:
|
|||||||
}
|
}
|
||||||
void FESD(u32 rt, u32 ra)
|
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)
|
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)
|
void FSCRWR(u32 rt, u32 ra)
|
||||||
{
|
{
|
||||||
@ -814,11 +842,15 @@ private:
|
|||||||
}
|
}
|
||||||
void FCEQ(u32 rt, u32 ra, u32 rb)
|
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)
|
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)
|
void MPY(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -847,11 +879,15 @@ private:
|
|||||||
}
|
}
|
||||||
void FCMEQ(u32 rt, u32 ra, u32 rb)
|
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)
|
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)
|
void MPYU(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -1177,15 +1213,24 @@ private:
|
|||||||
}
|
}
|
||||||
void FNMS(u32 rt, u32 ra, u32 rb, u32 rc)
|
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)
|
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)
|
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)
|
void UNK(u32 code, u32 opcode, u32 gcode)
|
||||||
|
@ -110,6 +110,8 @@ union SPU_GPR_hdr
|
|||||||
s16 _i16[8];
|
s16 _i16[8];
|
||||||
u8 _u8[16];
|
u8 _u8[16];
|
||||||
s8 _i8[16];
|
s8 _i8[16];
|
||||||
|
double _d[2];
|
||||||
|
float _f[4];
|
||||||
|
|
||||||
SPU_GPR_hdr() {}
|
SPU_GPR_hdr() {}
|
||||||
|
|
||||||
@ -249,6 +251,37 @@ public:
|
|||||||
return ret;
|
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:
|
public:
|
||||||
virtual void InitRegs();
|
virtual void InitRegs();
|
||||||
virtual u64 GetFreeStackSize() const;
|
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?)
|
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
unsigned char *gif = new unsigned char [fileSize];
|
unsigned char *gif = (unsigned char*)Memory.VirtualToRealAddr(buffer);
|
||||||
for(u32 i = 0; i < fileSize; i++){
|
unsigned char *image = stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4);
|
||||||
gif[i] = Memory.Read8(buffer+i);
|
|
||||||
}
|
|
||||||
Memory.Free(buffer);
|
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;
|
if (!image) return CELL_GIFDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
u32 image_size = width * height * 4;
|
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?)
|
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
unsigned char *jpg = new unsigned char [fileSize];
|
unsigned char *jpg = (unsigned char*)Memory.VirtualToRealAddr(buffer);
|
||||||
for(u32 i = 0; i < fileSize; i++){
|
unsigned char *image = stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4);
|
||||||
jpg[i] = Memory.Read8(buffer+i);
|
|
||||||
}
|
|
||||||
Memory.Free(buffer);
|
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;
|
if (!image) return CELL_JPGDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
u32 image_size = width * height * 4;
|
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?)
|
//Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
unsigned char *png = new unsigned char [fileSize];
|
unsigned char *png = (unsigned char*)Memory.VirtualToRealAddr(buffer);
|
||||||
for(u32 i = 0; i < fileSize; i++){
|
unsigned char *image = stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4);
|
||||||
png[i] = Memory.Read8(buffer+i);
|
|
||||||
}
|
|
||||||
Memory.Free(buffer);
|
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;
|
if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
u32 image_size = width * height * 4;
|
u32 image_size = width * height * 4;
|
||||||
|
@ -21,4 +21,7 @@ void sys_fs_init()
|
|||||||
sys_fs.AddFunc(0x2796fdf3, cellFsRmdir);
|
sys_fs.AddFunc(0x2796fdf3, cellFsRmdir);
|
||||||
sys_fs.AddFunc(0x7f4677a8, cellFsUnlink);
|
sys_fs.AddFunc(0x7f4677a8, cellFsUnlink);
|
||||||
sys_fs.AddFunc(0xa397d042, cellFsLseek);
|
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 cellFsRmdir(u32 path_addr);
|
||||||
extern int cellFsUnlink(u32 path_addr);
|
extern int cellFsUnlink(u32 path_addr);
|
||||||
extern int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_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
|
//cellVideo
|
||||||
extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);
|
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);
|
const wxString& path = Memory.ReadString(path_addr);
|
||||||
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb_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);
|
vfsStream* f = Emu.GetVFS().Open(path, vfsRead);
|
||||||
if(!f || !f->IsOpened())
|
if(!f || !f->IsOpened())
|
||||||
{
|
{
|
||||||
@ -322,7 +332,9 @@ int cellFsFstat(u32 fd, u32 sb_addr)
|
|||||||
|
|
||||||
int cellFsMkdir(u32 path_addr, u32 mode)
|
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);
|
sys_fs.Log("cellFsMkdir(path: %s, mode: 0x%x)", path, mode);
|
||||||
if(wxDirExists(path)) return CELL_EEXIST;
|
if(wxDirExists(path)) return CELL_EEXIST;
|
||||||
if(!wxMkdir(path)) return CELL_EBUSY;
|
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)
|
int cellFsRename(u32 from_addr, u32 to_addr)
|
||||||
{
|
{
|
||||||
const wxString& from = Memory.ReadString(from_addr);
|
const wxString& ps3_from = Memory.ReadString(from_addr);
|
||||||
const wxString& to = Memory.ReadString(to_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);
|
sys_fs.Log("cellFsRename(from: %s, to: %s)", from, to);
|
||||||
if(!wxFileExists(from)) return CELL_ENOENT;
|
if(!wxFileExists(from)) return CELL_ENOENT;
|
||||||
if(wxFileExists(to)) return CELL_EEXIST;
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellFsRmdir(u32 path_addr)
|
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);
|
sys_fs.Log("cellFsRmdir(path: %s)", path);
|
||||||
if(!wxDirExists(path)) return CELL_ENOENT;
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellFsUnlink(u32 path_addr)
|
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);
|
sys_fs.Error("cellFsUnlink(path: %s)", path);
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -373,5 +394,86 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_addr)
|
|||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
Memory.Write64(pos_addr, file.Seek(offset, seek_mode));
|
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;
|
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 "stdafx.h"
|
||||||
#include "InterpreterDisAsm.h"
|
#include "InterpreterDisAsm.h"
|
||||||
|
|
||||||
|
#include "InstructionEditor.cpp"
|
||||||
|
#include "RegisterEditor.cpp"
|
||||||
|
|
||||||
//static const int show_lines = 30;
|
//static const int show_lines = 30;
|
||||||
|
|
||||||
u64 InterpreterDisAsmFrame::CentrePc(const u64 pc) const
|
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_step->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoStep));
|
||||||
Connect(m_btn_run->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoRun));
|
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_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_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(InterpreterDisAsmFrame::DClick));
|
||||||
Connect(m_choice_units->GetId(),wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(InterpreterDisAsmFrame::OnSelectUnit));
|
Connect(m_choice_units->GetId(),wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(InterpreterDisAsmFrame::OnSelectUnit));
|
||||||
Connect(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
|
Connect(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
|
||||||
@ -442,6 +446,27 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
|||||||
ThreadBase::Start();
|
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)
|
void InterpreterDisAsmFrame::DClick(wxListEvent& event)
|
||||||
{
|
{
|
||||||
long i = m_list->GetFirstSelected();
|
long i = m_list->GetFirstSelected();
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
void DoRun(wxCommandEvent& event);
|
void DoRun(wxCommandEvent& event);
|
||||||
void DoPause(wxCommandEvent& event);
|
void DoPause(wxCommandEvent& event);
|
||||||
void DoStep(wxCommandEvent& event);
|
void DoStep(wxCommandEvent& event);
|
||||||
|
void InstrKey(wxListEvent& event);
|
||||||
void DClick(wxListEvent& event);
|
void DClick(wxListEvent& event);
|
||||||
|
|
||||||
void MouseWheel(wxMouseEvent& 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…
x
Reference in New Issue
Block a user