1
0
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:
B1ackDaemon 2013-09-23 06:55:37 -07:00
commit e655999a23
14 changed files with 521 additions and 51 deletions

View File

@ -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();

View File

@ -753,6 +753,69 @@ public:
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:

View File

@ -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)

View File

@ -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(&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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}
@ -373,5 +394,86 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, u32 pos_addr)
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
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;
}

View 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.");
}
}

View File

@ -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();

View File

@ -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);

View 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));
}