- Implemented MTCRF instruction.

- Implemented sys_spu_thread_set_argument syscall.
- Improved Debugger.
This commit is contained in:
DH 2013-07-08 16:24:46 +03:00
parent 6d7d3acb43
commit fb57bb9c4e
21 changed files with 456 additions and 276 deletions

View File

@ -11,7 +11,6 @@ PPCThread::PPCThread(PPCThreadType type)
: ThreadBase(true, "PPCThread")
, m_type(type)
, DisAsmFrame(NULL)
, m_arg(0)
, m_dec(NULL)
, stack_size(0)
, stack_addr(0)
@ -43,6 +42,7 @@ void PPCThread::Reset()
m_sync_wait = 0;
m_wait_thread_id = -1;
memset(m_args, 0, sizeof(u64) * 4);
SetPc(0);
cycle = 0;
@ -88,8 +88,6 @@ void PPCThread::CloseStack()
void PPCThread::SetId(const u32 id)
{
m_id = id;
ID& thread = Emu.GetIdManager().GetIDData(m_id);
thread.m_name = GetName();
}
void PPCThread::SetName(const wxString& name)
@ -119,10 +117,20 @@ bool PPCThread::Sync()
int PPCThread::ThreadStatus()
{
if(Emu.IsStopped()) return PPCThread_Stopped;
if(TestDestroy()) return PPCThread_Break;
if(Emu.IsStopped())
{
return PPCThread_Stopped;
}
if(TestDestroy())
{
return PPCThread_Break;
}
if(Emu.IsPaused() || Sync())
{
return PPCThread_Sleeping;
}
return PPCThread_Running;
}
@ -186,7 +194,7 @@ void PPCThread::SetError(const u32 error)
wxArrayString PPCThread::ErrorToString(const u32 error)
{
wxArrayString earr;
earr.Clear();
if(error == 0) return earr;
earr.Add("Unknown error");

View File

@ -27,12 +27,13 @@ protected:
wxWindow* DisAsmFrame;
u32 m_id;
PPCThreadType m_type;
u64 m_arg;
u64 m_args[4];
u64 m_prio;
bool m_joinable;
bool m_joining;
Array<u64> argv_addr;
u64 m_offset;
u32 m_exit_status;
public:
u64 stack_size;
@ -47,14 +48,17 @@ public:
virtual u64 GetStackAddr() const { return stack_addr; }
virtual u64 GetStackSize() const { return stack_size; }
virtual u64 GetFreeStackSize() const=0;
void SetArg(const u64 arg) { m_arg = arg; }
void SetArg(const uint pos, const u64 arg) { assert(pos < 4); m_args[pos] = arg; }
void SetId(const u32 id);
void SetName(const wxString& name);
void SetPrio(const u64 prio) { m_prio = prio; }
void SetOffset(const u64 offset) { m_offset = offset; }
u64 GetOffset() { return m_offset; }
void SetExitStatus(const u32 status) { m_exit_status = status; }
u64 GetOffset() const { return m_offset; }
u32 GetExitStatus() const { return m_exit_status; }
u64 GetPrio() const { return m_prio; }
wxString GetName() const { return m_name; }
wxString GetFName() const

View File

@ -274,9 +274,9 @@ private:
{
DisAsm_V2("vlogefp", vd, vb);
}
void VMADDFP(u32 vd, u32 va, u32 vb, u32 vc)
void VMADDFP(u32 vd, u32 va, u32 vc, u32 vb)
{
DisAsm_V4("vmaddfp", vd, va, vb, vc);
DisAsm_V4("vmaddfp", vd, va, vc, vb);
}
void VMAXFP(u32 vd, u32 va, u32 vb)
{
@ -1166,9 +1166,16 @@ private:
{
DisAsm_R3_OE_RC("adde", rd, ra, rb, oe, rc);
}
void MTOCRF(u32 crm, u32 rs)
void MTOCRF(u32 l, u32 crm, u32 rs)
{
DisAsm_INT1_R1("mtocrf", crm, rs);
if(l)
{
DisAsm_INT1_R1("mtocrf", crm, rs);
}
else
{
DisAsm_INT1_R1("mtcrf", crm, rs);
}
}
void STDX(u32 rs, u32 ra, u32 rb)
{
@ -1284,10 +1291,6 @@ private:
{
DisAsm_V1_R2("lvxl", vd, ra, rb);
}
void ABS(u32 rd, u32 ra, u32 oe, bool rc)
{
DisAsm_R2_OE_RC("abs", rd, ra, oe, rc);
}
void MFTB(u32 rd, u32 spr)
{
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);

View File

@ -125,8 +125,10 @@ namespace PPU_instr
*/
static CodeField<30> AA;
static CodeFieldSignedOffset<6, 29, 2> LI(FIELD_BRANCH);
//
static CodeFieldSigned<6, 31> LL(FIELD_BRANCH);
static CodeFieldSignedOffset<6, 29, 2> LL(FIELD_BRANCH);
/*
Link bit.
0 Does not update the link register (LR).
@ -177,36 +179,7 @@ namespace PPU_instr
static CodeFieldSigned<16, 31> D;
//
struct : public CodeFieldSigned<16, 31>
{
static __forceinline u32 decode(u32 data)
{
int res = sign<size>((data & mask) >> shift);
if(res < 0) return res - 1;
return res;
}
static __forceinline void encode(u32& data, u32 value)
{
if((s32)value < 0)
{
value++;
}
data &= ~mask;
data |= (value << shift) & mask;
}
virtual u32 operator ()(u32 data) const
{
return decode(data);
}
virtual void operator ()(u32& data, u32 value) const
{
return encode(data, value);
}
} static DS;
static CodeFieldSignedOffset<16, 29, 2> DS;
//This immediate field is used to specify a 16-bit signed integer
static CodeFieldSigned<16, 31> simm16;
@ -269,7 +242,7 @@ namespace PPU_instr
bind_instr(main_list, ADDIS, RD, RA, simm16);
bind_instr(main_list, BC, BO, BI, BD, AA, LK);
bind_instr(main_list, SC, SYS);
bind_instr(main_list, B, LL, AA, LK);
bind_instr(main_list, B, LI, AA, LK);
bind_instr(main_list, RLWIMI, RA, RS, SH, MB, ME, RC);
bind_instr(main_list, RLWINM, RA, RS, SH, MB, ME, RC);
bind_instr(main_list, RLWNM, RA, RS, RB, MB, ME, RC);
@ -302,7 +275,7 @@ namespace PPU_instr
bind_instr(main_list, STFD, FRS, RA, D);
bind_instr(main_list, STFDU, FRS, RA, D);
bind_instr(g04_list, VMADDFP, VD, VA, VB, VC);
bind_instr(g04_list, VMADDFP, VD, VA, VC, VB);
bind_instr(g04_list, VMHADDSHS, VD, VA, VB, VC);
bind_instr(g04_list, VMHRADDSHS, VD, VA, VB, VC);
bind_instr(g04_list, VMLADDUHM, VD, VA, VB, VC);
@ -515,7 +488,7 @@ namespace PPU_instr
/*0x087*/bind_instr(g1f_list, STVEBX, VS, RA, RB);
/*0x088*/bind_instr(g1f_list, SUBFE, RD, RA, RB, OE, RC);
/*0x08a*/bind_instr(g1f_list, ADDE, RD, RA, RB, OE, RC);
/*0x090*/bind_instr(g1f_list, MTOCRF, CRM, RS);
/*0x090*/bind_instr(g1f_list, MTOCRF, L_11, CRM, RS);
/*0x095*/bind_instr(g1f_list, STDX, RS, RA, RB);
/*0x096*/bind_instr(g1f_list, STWCX_, RS, RA, RB);
/*0x097*/bind_instr(g1f_list, STWX, RS, RA, RB);
@ -541,7 +514,6 @@ namespace PPU_instr
/*0x156*/bind_instr(g1f_list, DST, RA, RB, STRM, L_6);
/*0x157*/bind_instr(g1f_list, LHAX, RD, RA, RB);
/*0x167*/bind_instr(g1f_list, LVXL, VD, RA, RB);
/*0x168*/bind_instr(g1f_list, ABS, RD, RA, OE, RC);
/*0x173*/bind_instr(g1f_list, MFTB, RD, SPR);
/*0x176*/bind_instr(g1f_list, DSTST, RA, RB, STRM, L_6);
/*0x177*/bind_instr(g1f_list, LHAUX, RD, RA, RB);
@ -554,7 +526,7 @@ namespace PPU_instr
/*0x1d3*/bind_instr(g1f_list, MTSPR, SPR, RS);
/*0x1d6*///DCBI
/*0x1dc*/bind_instr(g1f_list, NAND, RA, RS, RB, RC);
/*0x1e7*/bind_instr(g1f_list, STVXL, RS, RA, RB);
/*0x1e7*/bind_instr(g1f_list, STVXL, VS, RA, RB);
/*0x1e9*/bind_instr(g1f_list, DIVD, RD, RA, RB, OE, RC);
/*0x1eb*/bind_instr(g1f_list, DIVW, RD, RA, RB, OE, RC);
/*0x207*/bind_instr(g1f_list, LVLX, VD, RA, RB);
@ -568,9 +540,9 @@ namespace PPU_instr
/*0x257*/bind_instr(g1f_list, LFDX, FRD, RA, RB);
/*0x277*/bind_instr(g1f_list, LFDUX, FRD, RA, RB);
/*0x287*/bind_instr(g1f_list, STVLX, VS, RA, RB);
/*0x297*/bind_instr(g1f_list, STFSX, RS, RA, RB);
/*0x297*/bind_instr(g1f_list, STFSX, FRS, RA, RB);
/*0x2a7*/bind_instr(g1f_list, STVRX, VS, RA, RB);
/*0x2d7*/bind_instr(g1f_list, STFDX, RS, RA, RB);
/*0x2d7*/bind_instr(g1f_list, STFDX, FRS, RA, RB);
/*0x307*/bind_instr(g1f_list, LVLXL, VD, RA, RB);
/*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB);
/*0x318*/bind_instr(g1f_list, SRAW, RA, RS, RB, RC);
@ -588,7 +560,7 @@ namespace PPU_instr
/*0x3d6*///ICBI
/*0x3f6*/bind_instr(g1f_list, DCBZ, RA, RB);
bind_instr(g3a_list, LD, RD, RA, D);
bind_instr(g3a_list, LD, RD, RA, DS);
bind_instr(g3a_list, LDU, RD, RA, DS);
bind_instr(g3b_list, FDIVS, FRD, FRA, FRB, RC);
@ -602,7 +574,7 @@ namespace PPU_instr
bind_instr(g3b_list, FNMSUBS, FRD, FRA, FRC, FRB, RC);
bind_instr(g3b_list, FNMADDS, FRD, FRA, FRC, FRB, RC);
bind_instr(g3e_list, STD, RS, RA, D);
bind_instr(g3e_list, STD, RS, RA, DS);
bind_instr(g3e_list, STDU, RS, RA, DS);
bind_instr(g3f_list, FSEL, FRD, FRA, FRC, FRB, RC);

View File

@ -97,18 +97,12 @@ private:
const u8 bo1 = (bo & 0x08) ? 1 : 0;
const u8 bo2 = (bo & 0x04) ? 1 : 0;
const u8 bo3 = (bo & 0x02) ? 1 : 0;
const u8 bo4 = (bo & 0x01) ? 1 : 0;
if(!bo2) --CPU.CTR;
const u8 ctr_ok = bo2 | ((CPU.CTR != 0) ^ bo3);
const u8 cond_ok = bo0 | (CPU.IsCR(bi) ^ (~bo1 & 0x1));
//if(bo1) CPU.SetCR(bi, bo4 ? 1 : 0);
//if(bo1) return !bo4;
//ConLog.Write("bo0: 0x%x, bo1: 0x%x, bo2: 0x%x, bo3: 0x%x", bo0, bo1, bo2, bo3);
return ctr_ok && cond_ok;
}
@ -805,7 +799,7 @@ private:
CPU.VPR[vd]._f[w] = log(CPU.VPR[vb]._f[w]) / log(2.0f);
}
}
void VMADDFP(u32 vd, u32 va, u32 vb, u32 vc)
void VMADDFP(u32 vd, u32 va, u32 vc, u32 vb)
{
for (uint w = 0; w < 4; w++)
{
@ -2549,24 +2543,38 @@ private:
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
if(oe) UNK("addeo");
}
void MTOCRF(u32 crm, u32 rs)
void MTOCRF(u32 l, u32 crm, u32 rs)
{
u32 n = 0, count = 0;
for(u32 i=0; i<8; ++i)
if(l)
{
if(crm & (1 << i))
u32 n = 0, count = 0;
for(u32 i=0; i<8; ++i)
{
n = i;
count++;
if(crm & (1 << i))
{
n = i;
count++;
}
}
if(count == 1)
{
//CR[4*n : 4*n+3] = RS[32+4*n : 32+4*n+3];
CPU.SetCR(n, (CPU.GPR[rs] >> (4*n)) & 0xf);
}
else
CPU.CR.CR = 0;
}
else
{
for(u32 i=0; i<8; ++i)
{
if(crm & (1 << i))
{
CPU.SetCR(i, CPU.GPR[rs] & (0xf << i));
}
}
}
if(count == 1)
{
//CR[4*n : 4*n+3] = RS[32+4*n : 32+4*n+3];
CPU.SetCR(n, (CPU.GPR[rs] >> (4*n)) & 0xf);
}
else CPU.CR.CR = 0;
}
void STDX(u32 rs, u32 ra, u32 rb)
{
@ -2584,6 +2592,7 @@ private:
{
Memory.Write32(addr, CPU.GPR[rs]);
CPU.SetCR_EQ(0, true);
CPU.reserve = false;
}
else
{
@ -2732,12 +2741,6 @@ private:
{
CPU.VPR[vd]._u128 = Memory.Read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
}
void ABS(u32 rd, u32 ra, u32 oe, bool rc)
{
CPU.GPR[rd] = abs((s64)CPU.GPR[ra]);
if(oe) UNK("abso");
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void MFTB(u32 rd, u32 spr)
{
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
@ -3175,8 +3178,41 @@ private:
}
void FDIVS(u32 frd, u32 fra, u32 frb, bool rc)
{
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] / CPU.FPR[frb]);
if(FPRdouble::IsNaN(CPU.FPR[fra]))
{
CPU.FPR[frd] = CPU.FPR[fra];
}
else if(FPRdouble::IsNaN(CPU.FPR[frb]))
{
CPU.FPR[frd] = CPU.FPR[frb];
}
else
{
if(CPU.FPR[frb] == 0.0)
{
if(CPU.FPR[fra] == 0.0)
{
CPU.FPSCR.VXZDZ = true;
CPU.FPR[frd] = FPR_NAN;
}
else
{
CPU.FPR[frd] = (float)(CPU.FPR[fra] / CPU.FPR[frb]);
}
CPU.FPSCR.ZX = true;
}
else if(FPRdouble::IsINF(CPU.FPR[fra]) && FPRdouble::IsINF(CPU.FPR[frb]))
{
CPU.FPSCR.VXIDI = true;
CPU.FPR[frd] = FPR_NAN;
}
else
{
CPU.FPR[frd] = (float)(CPU.FPR[fra] / CPU.FPR[frb]);
}
}
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
if(rc) UNK("fdivs.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
@ -3194,13 +3230,17 @@ private:
}
void FSQRTS(u32 frd, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(sqrt((float)CPU.FPR[frb]));
CPU.FPR[frd] = static_cast<float>(sqrt(CPU.FPR[frb]));
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
if(rc) UNK("fsqrts.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FRES(u32 frd, u32 frb, bool rc)
{
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
CPU.FPR[frd] = static_cast<float>(1.0f/CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FI = 0;
CPU.FPSCR.FR = 0;
if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FMULS(u32 frd, u32 fra, u32 frc, bool rc)

View File

@ -318,7 +318,6 @@ namespace PPU_opcodes
DST = 0x156, //Data Stream Touch
LHAX = 0x157,
LVXL = 0x167, //Load Vector Indexed Last
ABS = 0x168,
MFTB = 0x173,
DSTST = 0x176, //Data Stream Touch for Store
LHAUX = 0x177,
@ -436,8 +435,8 @@ public:
static u64 branchTarget(const u64 pc, const u64 imm)
{
return pc + (imm & ~0x3);
}
return pc + (imm & ~0x3ULL);
}
virtual void NULL_OP() = 0;
virtual void NOP() = 0;
@ -498,7 +497,7 @@ public:
virtual void VCTUXS(u32 vd, u32 uimm5, u32 vb) = 0;
virtual void VEXPTEFP(u32 vd, u32 vb) = 0;
virtual void VLOGEFP(u32 vd, u32 vb) = 0;
virtual void VMADDFP(u32 vd, u32 va, u32 vb, u32 vc) = 0;
virtual void VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) = 0;
virtual void VMAXFP(u32 vd, u32 va, u32 vb) = 0;
virtual void VMAXSB(u32 vd, u32 va, u32 vb) = 0;
virtual void VMAXSH(u32 vd, u32 va, u32 vb) = 0;
@ -675,7 +674,7 @@ public:
virtual void STVEBX(u32 vs, u32 ra, u32 rb) = 0;
virtual void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void MTOCRF(u32 crm, u32 rs) = 0;
virtual void MTOCRF(u32 l, u32 crm, u32 rs) = 0;
virtual void STDX(u32 rs, u32 ra, u32 rb) = 0;
virtual void STWCX_(u32 rs, u32 ra, u32 rb) = 0;
virtual void STWX(u32 rs, u32 ra, u32 rb) = 0;
@ -701,7 +700,6 @@ public:
virtual void DST(u32 ra, u32 rb, u32 strm, u32 t) = 0;
virtual void LHAX(u32 rd, u32 ra, u32 rb) = 0;
virtual void LVXL(u32 vd, u32 ra, u32 rb) = 0;
virtual void ABS(u32 rd, u32 ra, u32 oe, bool rc) = 0;
virtual void MFTB(u32 rd, u32 spr) = 0;
virtual void DSTST(u32 ra, u32 rb, u32 strm, u32 t) = 0;
virtual void LHAUX(u32 rd, u32 ra, u32 rb) = 0;

View File

@ -67,19 +67,6 @@ void PPUThread::InitRegs()
ConLog.Write("rtoc = 0x%x", rtoc);
SetPc(pc);
u64 argc = m_arg;
u64 argv = 0;
if(argv_addr.GetCount())
{
argc = argv_addr.GetCount();
stack_point -= 0xc + 4 * argc;
argv = stack_point;
mem64_t argv_list(argv);
for(int i=0; i<argc; ++i) argv_list += argv_addr[i];
}
const s32 thread_num = Emu.GetCPU().GetThreadNumById(!IsSPU(), GetId());
@ -106,22 +93,41 @@ void PPUThread::InitRegs()
GPR[1] = stack_point;
GPR[2] = rtoc;
if(argc)
for(int i=4; i<32; ++i)
{
if(i != 6)
GPR[i] = (i+1) * 0x10000;
}
if(argv_addr.GetCount())
{
u64 argc = argv_addr.GetCount();
stack_point -= 0xc + 4 * argc;
u64 argv = stack_point;
mem64_t argv_list(argv);
for(int i=0; i<argc; ++i) argv_list += argv_addr[i];
GPR[3] = argc;
GPR[4] = argv;
GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk
}
else
{
GPR[3] = m_arg;
GPR[3] = m_args[0];
GPR[4] = m_args[1];
GPR[5] = m_args[2];
GPR[6] = m_args[3];
}
u32 prx_mem = Memory.PRXMem.Alloc(0x10000);
Memory.Write64(prx_mem, 0xDEADBEEFABADCAFE);
GPR[0] = pc;
GPR[8] = entry;
GPR[11] = 0x80;
GPR[12] = Emu.GetMallocPageSize();
GPR[13] = Memory.PRXMem.Alloc(0x10000) + 0x7060 - 8;
GPR[13] = prx_mem + 0x7060;
GPR[28] = GPR[4];
GPR[29] = GPR[3];
GPR[31] = GPR[5];
@ -172,15 +178,30 @@ bool dump_enable = false;
void PPUThread::DoCode(const s32 code)
{
static bool is_last_enabled = false;
if(dump_enable)
{
static wxFile f("dump.txt", wxFile::write);
static PPU_DisAsm disasm(*this, DumpMode);
static PPU_Decoder decoder(disasm);
if(!is_last_enabled)
{
f.Write(RegsToString() + "\n");
}
disasm.dump_pc = PC;
decoder.Decode(code);
f.Write(disasm.last_opcode);
is_last_enabled = true;
}
else
{
is_last_enabled = false;
}
if(++cycle > 220)
{
@ -193,7 +214,7 @@ void PPUThread::DoCode(const s32 code)
bool FPRdouble::IsINF(PPCdouble d)
{
return wxFinite(d) ? 1 : 0;
return d.GetType() == FPR_INF;
}
bool FPRdouble::IsNaN(PPCdouble d)

View File

@ -18,6 +18,18 @@ enum
CR_SO = 0x1,
};
enum
{
PPU_THREAD_STATUS_IDLE = (1 << 0),
PPU_THREAD_STATUS_RUNNABLE = (1 << 1),
PPU_THREAD_STATUS_ONPROC = (1 << 2),
PPU_THREAD_STATUS_SLEEP = (1 << 3),
PPU_THREAD_STATUS_STOP = (1 << 4),
PPU_THREAD_STATUS_ZOMBIE = (1 << 5),
PPU_THREAD_STATUS_DELETED = (1 << 6),
PPU_THREAD_STATUS_UNKNOWN = (1 << 7),
};
enum FPSCR_EXP
{
FPSCR_FX = 0x80000000,
@ -302,6 +314,9 @@ enum FPRType
FPR_ND = 0x18,
};
static const u64 FPR_NAN_I = 0x7FF8000000000000ULL;
static const double& FPR_NAN = (double&)FPR_NAN_I;
struct PPCdouble
{
union
@ -707,7 +722,7 @@ public:
void SetFPSCR_FI(const u32 val)
{
if(val) SetFPSCRException(FPSCR_XX);
FPSCR.FI = val;
FPSCR.FI = val;
}
virtual wxString RegsToString()

View File

@ -30,7 +30,11 @@ void SPUThread::DoReset()
void SPUThread::InitRegs()
{
GPR[1]._u64[0] = stack_point;
//GPR[1]._u64[0] = stack_point;
GPR[3]._u64[1] = m_args[0];
GPR[4]._u64[1] = m_args[1];
GPR[5]._u64[1] = m_args[2];
GPR[6]._u64[1] = m_args[3];
}
u64 SPUThread::GetFreeStackSize() const

View File

@ -461,7 +461,7 @@ void GLGSRender::InitVertexData()
void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count)
{
#if CMD_DEBUG
wxString debug = getMethodName(cmd);
wxString debug = GetMethodName(cmd);
debug += "(";
for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + wxString::Format("0x%x", args[i]);
debug += ")";
@ -757,7 +757,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
m_indexed_array.m_data.InsertRoomEnd(4);
index = Memory.Read32(m_indexed_array.m_addr + i * 4);
*(u32*)&m_indexed_array.m_data[pos] = index;
ConLog.Warning("index 4: %d", *(u32*)&m_indexed_array.m_data[pos]);
//ConLog.Warning("index 4: %d", *(u32*)&m_indexed_array.m_data[pos]);
}
break;
@ -766,8 +766,8 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
int pos = m_indexed_array.m_data.GetCount();
m_indexed_array.m_data.InsertRoomEnd(2);
index = Memory.Read16(m_indexed_array.m_addr + i * 2);
ConLog.Warning("index 2: %d", index);
*(u32*)&m_indexed_array.m_data[pos] = index;
//ConLog.Warning("index 2: %d", index);
*(u16*)&m_indexed_array.m_data[pos] = index;
}
break;
}
@ -1294,13 +1294,13 @@ void GLGSRender::ExecCMD()
case 0:
glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr);
checkForGlError("glDrawElements #4");
for(uint i=0; i<m_indexed_array.m_count; i+=4) log.Write(wxString::Format("index 4: %d\n", (u32&)m_indexed_array.m_data[i]));
//for(uint i=0; i<m_indexed_array.m_count; i+=4) log.Write(wxString::Format("index 4: %d\n", (u32&)m_indexed_array.m_data[i]));
break;
case 1:
glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr);
checkForGlError("glDrawElements #2");
for(uint i=0; i<m_indexed_array.m_count; i+=2) log.Write(wxString::Format("index 2: %d\n", (u16&)m_indexed_array.m_data[i]));
//for(uint i=0; i<m_indexed_array.m_count; i+=2) log.Write(wxString::Format("index 2: %d\n", (u16&)m_indexed_array.m_data[i]));
break;
default:
@ -1310,7 +1310,7 @@ void GLGSRender::ExecCMD()
DisableVertexData();
m_indexed_array.Reset();
Emu.Pause();
//Emu.Pause();
}
if(m_draw_array_count)

View File

@ -39,7 +39,7 @@ static func_caller* sc_table[1024] =
null_func, bind_func(sys_spu_image_open), null_func, null_func, null_func, //159
bind_func(sys_raw_spu_create), null_func, null_func, null_func, null_func, //164
null_func, null_func, null_func, null_func, bind_func(sys_spu_initialize), //169
bind_func(sys_spu_thread_group_create), null_func, bind_func(sys_spu_thread_initialize), bind_func(sys_spu_thread_group_start), null_func, //174
bind_func(sys_spu_thread_group_create), bind_func(sys_spu_thread_set_argument), bind_func(sys_spu_thread_initialize), bind_func(sys_spu_thread_group_start), null_func, //174
null_func, null_func, null_func, null_func, null_func, //179
null_func, bind_func(sys_spu_thread_write_ls), bind_func(sys_spu_thread_read_ls), null_func, null_func, //184
null_func, null_func, null_func, null_func, null_func, //189
@ -260,6 +260,7 @@ void SysCalls::DoSyscall(u32 code)
case 999:
dump_enable = !dump_enable;
Emu.Pause();
ConLog.Warning("Dump %s", dump_enable ? "enabled" : "disabled");
return;

View File

@ -251,6 +251,7 @@ extern int sys_heap_malloc(const u32 heap_addr, const u32 size);
//sys_spu
extern int sys_spu_image_open(u32 img_addr, u32 path_addr);
extern int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_addr, u32 attr_addr, u32 arg_addr);
extern int sys_spu_thread_set_argument(u32 id, u32 arg_addr);
extern int sys_spu_thread_group_start(u32 id);
extern int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr);
extern int sys_spu_thread_create(u64 thread_id_addr, u64 entry_addr, u64 arg, int prio, u32 stacksize, u64 flags, u64 threadname_addr);

View File

@ -7,6 +7,14 @@ extern Module cellGcmSys;
CellGcmConfig current_config;
CellGcmContextData current_context;
gcmInfo gcm_info;
struct gcm_offset
{
u16 ea;
u16 offset;
};
u32 map_offset_addr = 0;
u32 map_offset_pos = 0;
int cellGcmMapMainMemory(u32 address, u32 size, u32 offset_addr)
{
@ -24,6 +32,8 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
const u32 local_size = 0xf900000; //TODO
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
map_offset_addr = 0;
map_offset_pos = 0;
current_config.ioSize = re32(ioSize);
current_config.ioAddress = re32(ioAddress);
current_config.localSize = re32(local_size);
@ -90,11 +100,20 @@ int cellGcmAddressToOffset(u32 address, u32 offset_addr)
{
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset_addr);
if(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
if(!map_offset_addr)
{
map_offset_addr = Memory.Alloc(4*50, 4);
}
Memory.Write32(offset_addr,
Memory.RSXFBMem.IsInMyRange(address)
? address - Memory.RSXFBMem.GetStartAddr()
: address - re(current_context.begin));
u32 sa = Memory.RSXFBMem.IsInMyRange(address) ? Memory.RSXFBMem.GetStartAddr() : re(current_context.begin);
u16 ea = (sa + address - sa) >> 16;
u32 offset = address - sa;
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
//map_offset_pos += 4;
Memory.Write32(offset_addr, offset);
return CELL_OK;
}

View File

@ -129,7 +129,7 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32
Memory.Write32(thread_id_addr, new_thread.GetId());
new_thread.SetEntry(entry);
new_thread.SetArg(arg);
new_thread.SetArg(0, arg);
new_thread.SetPrio(prio);
new_thread.stack_size = stacksize;
//new_thread.flags = flags;

View File

@ -36,14 +36,16 @@ struct sys_spu_image
int nsegs;
};
static const u32 g_spu_group_thr_count = 255;
struct SpuGroupInfo
{
PPCThread* threads[10];
PPCThread* threads[g_spu_group_thr_count];
sys_spu_thread_group_attribute& attr;
SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr)
{
memset(threads, 0, sizeof(PPCThread*) * 10);
memset(threads, 0, sizeof(PPCThread*) * g_spu_group_thr_count);
}
};
@ -74,7 +76,7 @@ int sys_spu_image_open(u32 img_addr, u32 path_addr)
if(!stream || !stream->IsOpened())
{
sc_spu.Error("'%s' not found!", path);
sc_spu.Error("sys_spu_image_open error: '%s' not found!", path);
delete stream;
return CELL_ENOENT;
@ -83,7 +85,7 @@ int sys_spu_image_open(u32 img_addr, u32 path_addr)
u32 entry = LoadSpuImage(*stream);
delete stream;
sys_spu_image& ret = (sys_spu_image&)Memory[img_addr];
auto& ret = (sys_spu_image&)Memory[img_addr];
re(ret.type, 1);
re(ret.entry_point, entry);
re(ret.segs_addr, 0x0);
@ -103,6 +105,8 @@ int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_a
return CELL_ESRCH;
}
SpuGroupInfo& group_info = *(SpuGroupInfo*)Emu.GetIdManager().GetIDData(group).m_data;
if(
!Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) ||
!Memory.IsGoodAddr(attr_addr, sizeof(sys_spu_thread_attribute)) ||
@ -111,15 +115,25 @@ int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_a
return CELL_EFAULT;
}
sys_spu_image& img = (sys_spu_image&)Memory[img_addr];
sys_spu_thread_attribute& attr = (sys_spu_thread_attribute&)Memory[attr_addr];
sys_spu_thread_argument& arg = (sys_spu_thread_argument&)Memory[arg_addr];
auto& img = (sys_spu_image&)Memory[img_addr];
auto& attr = (sys_spu_thread_attribute&)Memory[attr_addr];
auto& arg = (sys_spu_thread_argument&)Memory[arg_addr];
if(!Memory.IsGoodAddr(re(attr.name_addr), re(attr.name_len)))
{
return CELL_EFAULT;
}
if(spu_num >= g_spu_group_thr_count)
{
return CELL_EINVAL;
}
if(group_info.threads[spu_num])
{
return CELL_EBUSY;
}
u32 entry = re(img.entry_point);
wxString name = Memory.ReadString(re(attr.name_addr), re(attr.name_len));
u64 a1 = re(arg.arg1);
@ -140,21 +154,43 @@ int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_a
new_thread.SetOffset(g_spu_offset);
new_thread.SetEntry(entry - g_spu_offset);
new_thread.SetName(name);
SPU_GPR_hdr* GPR = ((SPUThread&)new_thread).GPR;
new_thread.Run();
new_thread.Pause();
GPR[3]._u64[1] = a1;
GPR[4]._u64[1] = a2;
GPR[5]._u64[1] = a3;
GPR[6]._u64[1] = a4;
new_thread.SetArg(0, a1);
new_thread.SetArg(1, a2);
new_thread.SetArg(2, a3);
new_thread.SetArg(3, a4);
ID& id = Emu.GetIdManager().GetIDData(group);
SpuGroupInfo& group_info = *(SpuGroupInfo*)id.m_data;
group_info.threads[spu_num] = &new_thread;
return CELL_OK;
}
//166
int sys_spu_thread_set_argument(u32 id, u32 arg_addr)
{
sc_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg_addr=0x%x)", id, arg_addr);
PPCThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || !thr->IsSPU())
{
return CELL_ESRCH;
}
if(!Memory.IsGoodAddr(arg_addr, sizeof(sys_spu_thread_argument)))
{
return CELL_EFAULT;
}
auto& arg = (sys_spu_thread_argument&)Memory[arg_addr];
thr->SetArg(0, re(arg.arg1));
thr->SetArg(1, re(arg.arg2));
thr->SetArg(2, re(arg.arg3));
thr->SetArg(3, re(arg.arg4));
return CELL_OK;
}
//173
int sys_spu_thread_group_start(u32 id)
{
@ -169,7 +205,7 @@ int sys_spu_thread_group_start(u32 id)
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
Emu.Pause();
for(int i=0; i<10; i++)
for(int i=0; i<g_spu_group_thr_count; i++)
{
if(group_info.threads[i])
{
@ -211,6 +247,21 @@ int sys_spu_thread_create(u64 thread_id_addr, u64 entry_addr, u64 arg,
return CELL_OK;
}
int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup)
{
if(!Emu.GetIdManager().CheckID(id))
{
return CELL_ESRCH;
}
if(spup > 63)
{
return CELL_EINVAL;
}
return CELL_OK;
}
//160
int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
{
@ -329,7 +380,7 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
SpuGroupInfo* group = (SpuGroupInfo*)Emu.GetIdManager().GetIDData(id).m_data;
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(eq).m_data;
for(int i=0; i<10; ++i)
for(int i=0; i<g_spu_group_thr_count; ++i)
{
if(group->threads[i])
{

View File

@ -85,8 +85,6 @@ void Emulator::Load()
Memory.Init();
GetInfo().Reset();
Memory.Write64(Memory.PRXMem.Alloc(8), 0xDEADBEEFABADCAFE);
bool is_error;
vfsLocalFile f(m_path);
Loader l(f);
@ -127,28 +125,26 @@ void Emulator::Load()
else
{
thread.SetEntry(l.GetEntry());
Memory.StackMem.Alloc(0x1000);
thread.InitStack();
thread.AddArgv(m_path);
//thread.AddArgv("-emu");
m_rsx_callback = Memory.MainMem.Alloc(4 * 4) + 4;
Memory.Write32(m_rsx_callback - 4, m_rsx_callback);
mem32_t callback_data(m_rsx_callback);
callback_data += ADDI(11, 0, 0x3ff);
callback_data += SC(2);
callback_data += BCLR(0x10 | 0x04, 0, 0, 0);
m_ppu_thr_exit = Memory.MainMem.Alloc(4 * 3);
mem32_t ppu_thr_exit_data(m_ppu_thr_exit);
ppu_thr_exit_data += ADDI(11, 0, 41);
ppu_thr_exit_data += SC(2);
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
}
thread.SetArg(thread.GetId());
Memory.StackMem.Alloc(0x1000);
thread.InitStack();
thread.AddArgv(m_path);
//thread.AddArgv("-emu");
m_rsx_callback = Memory.MainMem.Alloc(4 * 4) + 4;
Memory.Write32(m_rsx_callback - 4, m_rsx_callback);
mem32_t callback_data(m_rsx_callback);
callback_data += ADDI(11, 0, 0x3ff);
callback_data += SC(2);
callback_data += BCLR(0x10 | 0x04, 0, 0, 0);
m_ppu_thr_exit = Memory.MainMem.Alloc(4 * 3);
mem32_t ppu_thr_exit_data(m_ppu_thr_exit);
ppu_thr_exit_data += ADDI(11, 0, 41);
ppu_thr_exit_data += SC(2);
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
thread.Run();

View File

@ -99,16 +99,9 @@ DebuggerPanel::DebuggerPanel(wxWindow* parent) : wxPanel(parent, wxID_ANY, wxDef
{
m_aui_mgr.SetManagedWindow(this);
m_nb = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT |
wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS |
wxAUI_NB_WINDOWLIST_BUTTON | wxAUI_NB_TAB_MOVE | wxNO_BORDER);
m_aui_mgr.AddPane(new DbgEmuPanel(this), wxAuiPaneInfo().Top());
m_aui_mgr.AddPane(m_nb, wxAuiPaneInfo().Center().CaptionVisible(false).CloseButton().MaximizeButton());
m_aui_mgr.AddPane(new InterpreterDisAsmFrame(this), wxAuiPaneInfo().Center().CaptionVisible(false).CloseButton().MaximizeButton());
m_aui_mgr.Update();
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(DebuggerPanel::HandleCommand), (wxObject*)0, this);
}
DebuggerPanel::~DebuggerPanel()
@ -119,30 +112,3 @@ DebuggerPanel::~DebuggerPanel()
void DebuggerPanel::UpdateUI()
{
}
void DebuggerPanel::HandleCommand(wxCommandEvent& event)
{
PPCThread* thr = (PPCThread*)event.GetClientData();
switch(event.GetId())
{
case DID_CREATE_THREAD:
m_nb->AddPage(new InterpreterDisAsmFrame(m_nb, thr), thr->GetFName());
break;
case DID_REMOVE_THREAD:
for(uint i=0; i<m_nb->GetPageCount(); ++i)
{
InterpreterDisAsmFrame* page = (InterpreterDisAsmFrame*)m_nb->GetPage(i);
if(page->CPU.GetId() == thr->GetId())
{
m_nb->DeletePage(i);
break;
}
}
break;
}
event.Skip();
}

View File

@ -5,13 +5,10 @@
class DebuggerPanel : public wxPanel
{
wxAuiManager m_aui_mgr;
wxAuiNotebook* m_nb;
AppConnector m_app_connector;
public:
DebuggerPanel(wxWindow* parent);
~DebuggerPanel();
void UpdateUI();
void HandleCommand(wxCommandEvent& event);
};

View File

@ -3,48 +3,39 @@
//static const int show_lines = 30;
u32 InterpreterDisAsmFrame::CentrePc(const u32 pc) const
u64 InterpreterDisAsmFrame::CentrePc(const u64 pc) const
{
return pc - ((m_item_count / 2) * 4);
}
InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent, PPCThread* cpu)
InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(500, 700), wxTAB_TRAVERSAL)
, ThreadBase(false, "DisAsmFrame Thread")
, CPU(*cpu)
, PC(0)
, CPU(nullptr)
, m_item_count(30)
, decoder(nullptr)
, disasm(nullptr)
{
if(CPU.IsSPU())
{
SPU_DisAsm& dis_asm = *new SPU_DisAsm(CPU, InterpreterMode);
decoder = new SPU_Decoder(dis_asm);
disasm = &dis_asm;
}
else
{
PPU_DisAsm& dis_asm = *new PPU_DisAsm(CPU, InterpreterMode);
decoder = new PPU_Decoder(dis_asm);
disasm = &dis_asm;
}
wxBoxSizer& s_p_main = *new wxBoxSizer(wxVERTICAL);
wxBoxSizer& s_b_main = *new wxBoxSizer(wxHORIZONTAL);
m_list = new wxListView(this);
m_choice_units = new wxChoice(this, wxID_ANY);
wxButton& b_go_to_addr = *new wxButton(this, wxID_ANY, "Go To Address");
wxButton& b_go_to_pc = *new wxButton(this, wxID_ANY, "Go To PC");
m_btn_step = new wxButton(this, wxID_ANY, "Step");
m_btn_run = new wxButton(this, wxID_ANY, "Run");
m_btn_pause = new wxButton(this, wxID_ANY, "Pause");
m_btn_step = new wxButton(this, wxID_ANY, "Step");
m_btn_run = new wxButton(this, wxID_ANY, "Run");
m_btn_pause = new wxButton(this, wxID_ANY, "Pause");
s_b_main.Add(&b_go_to_addr, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(&b_go_to_pc, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_btn_step, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_btn_run, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_btn_pause, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(&b_go_to_addr, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(&b_go_to_pc, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_btn_step, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_btn_run, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_btn_pause, wxSizerFlags().Border(wxALL, 5));
s_b_main.Add(m_choice_units, wxSizerFlags().Border(wxALL, 5));
m_regs = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_DONTWRAP|wxNO_BORDER|wxTE_RICH2);
@ -77,12 +68,14 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent, PPCThread* cpu)
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_ITEM_ACTIVATED, wxListEventHandler(InterpreterDisAsmFrame::DClick));
Connect(m_choice_units->GetId(),wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(InterpreterDisAsmFrame::OnSelectUnit));
Connect(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
m_app_connector.Connect(m_list->GetId(), wxEVT_MOUSEWHEEL, wxMouseEventHandler(InterpreterDisAsmFrame::MouseWheel), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(InterpreterDisAsmFrame::OnKeyDown), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(InterpreterDisAsmFrame::HandleCommand), (wxObject*)0, this);
WriteRegs();
ShowAddr(CentrePc(PC));
UpdateUnitList();
}
InterpreterDisAsmFrame::~InterpreterDisAsmFrame()
@ -90,6 +83,48 @@ InterpreterDisAsmFrame::~InterpreterDisAsmFrame()
ThreadBase::Stop();
}
void InterpreterDisAsmFrame::UpdateUnitList()
{
m_choice_units->Freeze();
m_choice_units->Clear();
auto& thrs = Emu.GetCPU().GetThreads();
for(uint i=0; i<thrs.GetCount(); ++i)
{
m_choice_units->Append(thrs[i].GetFName(), &thrs[i]);
}
m_choice_units->Thaw();
}
void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
{
CPU = (PPCThread*)event.GetClientData();
delete decoder;
//delete disasm;
decoder = nullptr;
disasm = nullptr;
if(CPU)
{
if(CPU->IsSPU())
{
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*CPU, InterpreterMode);
decoder = new SPU_Decoder(dis_asm);
disasm = &dis_asm;
}
else
{
PPU_DisAsm& dis_asm = *new PPU_DisAsm(*CPU, InterpreterMode);
decoder = new PPU_Decoder(dis_asm);
disasm = &dis_asm;
}
}
DoUpdate();
}
void InterpreterDisAsmFrame::OnKeyDown(wxKeyEvent& event)
{
if(wxGetActiveWindow() != wxGetTopLevelParent(this))
@ -164,48 +199,59 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
{
PC = addr;
m_list->Freeze();
disasm->offset = CPU.GetOffset();
for(uint i=0; i<m_item_count; ++i, PC += 4)
if(!CPU)
{
if(!Memory.IsGoodAddr(CPU.GetOffset() + PC, 4))
for(uint i=0; i<m_item_count; ++i, PC += 4)
{
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
continue;
}
disasm->dump_pc = PC;
decoder->Decode(Memory.Read32(CPU.GetOffset() + PC));
if(IsBreakPoint(PC))
}
else
{
disasm->offset = CPU->GetOffset();
for(uint i=0; i<m_item_count; ++i, PC += 4)
{
m_list->SetItem(i, 0, ">>> " + disasm->last_opcode);
}
else
{
m_list->SetItem(i, 0, " " + disasm->last_opcode);
}
wxColour colour;
if((!CPU.IsRunned() || !Emu.IsRunned()) && PC == CPU.PC)
{
colour = wxColour("Green");
}
else
{
colour = wxColour("White");
for(u32 i=0; i<Emu.GetMarkedPoints().GetCount(); ++i)
if(!Memory.IsGoodAddr(CPU->GetOffset() + PC, 4))
{
if(Emu.GetMarkedPoints()[i] == PC)
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
continue;
}
disasm->dump_pc = PC;
decoder->Decode(Memory.Read32(CPU->GetOffset() + PC));
if(IsBreakPoint(PC))
{
m_list->SetItem(i, 0, ">>> " + disasm->last_opcode);
}
else
{
m_list->SetItem(i, 0, " " + disasm->last_opcode);
}
wxColour colour;
if((!CPU->IsRunned() || !Emu.IsRunned()) && PC == CPU->PC)
{
colour = wxColour("Green");
}
else
{
colour = wxColour("White");
for(u32 i=0; i<Emu.GetMarkedPoints().GetCount(); ++i)
{
colour = wxColour("Wheat");
break;
if(Emu.GetMarkedPoints()[i] == PC)
{
colour = wxColour("Wheat");
break;
}
}
}
}
m_list->SetItemBackgroundColour( i, colour );
m_list->SetItemBackgroundColour( i, colour );
}
}
while(remove_markedPC.GetCount())
@ -234,7 +280,7 @@ void InterpreterDisAsmFrame::WriteRegs()
{
m_regs->Freeze();
m_regs->Clear();
m_regs->WriteText(CPU.RegsToString());
if(CPU) m_regs->WriteText(CPU->RegsToString());
m_regs->Thaw();
}
@ -253,7 +299,7 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
break;
}
}
else if(thr->GetId() == CPU.GetId())
else if(CPU && thr->GetId() == CPU->GetId())
{
switch(event.GetId())
{
@ -266,7 +312,6 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
DoUpdate();
break;
case DID_START_THREAD:
case DID_EXEC_THREAD:
case DID_RESUME_THREAD:
@ -285,6 +330,36 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
m_btn_run->Disable();
m_btn_step->Disable();
m_btn_pause->Disable();
if(event.GetId() == DID_REMOVE_THREAD)
{
m_choice_units->SetSelection(-1);
wxCommandEvent event;
event.SetInt(-1);
//event.SetClientData(nullptr);
OnSelectUnit(event);
UpdateUnitList();
}
DoUpdate();
break;
}
}
else
{
switch(event.GetId())
{
case DID_CREATE_THREAD:
UpdateUnitList();
if(m_choice_units->GetSelection() == -1)
{
m_choice_units->SetSelection(0);
wxCommandEvent event;
event.SetInt(0);
event.SetClientData(&Emu.GetCPU().GetThreads()[0]);
OnSelectUnit(event);
DoUpdate();
}
break;
}
}
@ -313,11 +388,11 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
diag->SetSizerAndFit( s_panel );
p_pc->SetLabel(wxString::Format("%llx", CPU.PC));
if(CPU) p_pc->SetLabel(wxString::Format("%llx", CPU->PC));
if(diag->ShowModal() == wxID_OK)
{
u64 pc = CPU.PC;
u64 pc = CPU ? CPU->PC : 0x0;
sscanf(p_pc->GetLabel(), "%llx", &pc);
remove_markedPC.AddCpy(Emu.GetMarkedPoints().AddCpy(pc));
ShowAddr(CentrePc(pc));
@ -326,17 +401,19 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event))
{
ShowAddr(CentrePc(CPU.PC));
if(CPU) ShowAddr(CentrePc(CPU->PC));
}
extern bool dump_enable;
void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
{
if(CPU.IsPaused()) CPU.Resume();
if(!CPU) return;
if(CPU->IsPaused()) CPU->Resume();
if(!Emu.IsPaused())
{
CPU.Exec();
CPU->Exec();
}
//ThreadBase::Start();
@ -344,7 +421,7 @@ void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event))
{
CPU.Pause();
if(CPU) CPU->Pause();
}
void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
@ -418,7 +495,8 @@ bool InterpreterDisAsmFrame::RemoveBreakPoint(u64 pc)
void InterpreterDisAsmFrame::Task()
{
wxGetApp().SendDbgCommand(DID_RESUME_THREAD, &CPU);
if(!CPU) return;
wxGetApp().SendDbgCommand(DID_RESUME_THREAD, CPU);
bool dump_status = dump_enable;
@ -428,9 +506,9 @@ void InterpreterDisAsmFrame::Task()
{
do
{
CPU.ExecOnce();
CPU->ExecOnce();
}
while(CPU.IsRunned() && Emu.IsRunned() && !TestDestroy() && !IsBreakPoint(CPU.PC) && dump_status == dump_enable);
while(CPU->IsRunned() && Emu.IsRunned() && !TestDestroy() && !IsBreakPoint(CPU->PC) && dump_status == dump_enable);
}
catch(const wxString& e)
{
@ -443,5 +521,5 @@ void InterpreterDisAsmFrame::Task()
//CPU.FreeTls();
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, &CPU);
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, CPU);
}

View File

@ -20,16 +20,19 @@ class InterpreterDisAsmFrame
wxButton* m_btn_pause;
AppConnector m_app_connector;
u32 m_item_count;
wxChoice* m_choice_units;
public:
PPCThread& CPU;
PPCThread* CPU;
public:
InterpreterDisAsmFrame(wxWindow* parent, PPCThread* cpu);
InterpreterDisAsmFrame(wxWindow* parent);
~InterpreterDisAsmFrame();
u32 CentrePc(const u32 pc) const;
void UpdateUnitList();
u64 CentrePc(const u64 pc) const;
void OnSelectUnit(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnResize(wxSizeEvent& event);
void DoUpdate();

View File

@ -30,13 +30,16 @@ bool SELFLoader::LoadData(u64 offset)
if( !l.LoadEhdrInfo(self_hdr.se_elfoff) ||
!l.LoadPhdrInfo(self_hdr.se_phdroff) ||
!l.LoadShdrInfo(self_hdr.se_shdroff) ||
!l.LoadData(offset) )
!l.LoadData(self_hdr.se_appinfooff) )
{
ConLog.Error("Broken SELF file.");
return false;
}
machine = l.GetMachine();
entry = l.GetEntry();
return true;
ConLog.Error("Boot SELF not supported yet!");