mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
- Implemented MTCRF instruction.
- Implemented sys_spu_thread_set_argument syscall. - Improved Debugger.
This commit is contained in:
parent
6d7d3acb43
commit
fb57bb9c4e
@ -11,7 +11,6 @@ PPCThread::PPCThread(PPCThreadType type)
|
|||||||
: ThreadBase(true, "PPCThread")
|
: ThreadBase(true, "PPCThread")
|
||||||
, m_type(type)
|
, m_type(type)
|
||||||
, DisAsmFrame(NULL)
|
, DisAsmFrame(NULL)
|
||||||
, m_arg(0)
|
|
||||||
, m_dec(NULL)
|
, m_dec(NULL)
|
||||||
, stack_size(0)
|
, stack_size(0)
|
||||||
, stack_addr(0)
|
, stack_addr(0)
|
||||||
@ -43,6 +42,7 @@ void PPCThread::Reset()
|
|||||||
|
|
||||||
m_sync_wait = 0;
|
m_sync_wait = 0;
|
||||||
m_wait_thread_id = -1;
|
m_wait_thread_id = -1;
|
||||||
|
memset(m_args, 0, sizeof(u64) * 4);
|
||||||
|
|
||||||
SetPc(0);
|
SetPc(0);
|
||||||
cycle = 0;
|
cycle = 0;
|
||||||
@ -88,8 +88,6 @@ void PPCThread::CloseStack()
|
|||||||
void PPCThread::SetId(const u32 id)
|
void PPCThread::SetId(const u32 id)
|
||||||
{
|
{
|
||||||
m_id = id;
|
m_id = id;
|
||||||
ID& thread = Emu.GetIdManager().GetIDData(m_id);
|
|
||||||
thread.m_name = GetName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCThread::SetName(const wxString& name)
|
void PPCThread::SetName(const wxString& name)
|
||||||
@ -119,10 +117,20 @@ bool PPCThread::Sync()
|
|||||||
|
|
||||||
int PPCThread::ThreadStatus()
|
int PPCThread::ThreadStatus()
|
||||||
{
|
{
|
||||||
if(Emu.IsStopped()) return PPCThread_Stopped;
|
if(Emu.IsStopped())
|
||||||
if(TestDestroy()) return PPCThread_Break;
|
{
|
||||||
|
return PPCThread_Stopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(TestDestroy())
|
||||||
|
{
|
||||||
|
return PPCThread_Break;
|
||||||
|
}
|
||||||
|
|
||||||
if(Emu.IsPaused() || Sync())
|
if(Emu.IsPaused() || Sync())
|
||||||
|
{
|
||||||
return PPCThread_Sleeping;
|
return PPCThread_Sleeping;
|
||||||
|
}
|
||||||
|
|
||||||
return PPCThread_Running;
|
return PPCThread_Running;
|
||||||
}
|
}
|
||||||
@ -186,7 +194,7 @@ void PPCThread::SetError(const u32 error)
|
|||||||
wxArrayString PPCThread::ErrorToString(const u32 error)
|
wxArrayString PPCThread::ErrorToString(const u32 error)
|
||||||
{
|
{
|
||||||
wxArrayString earr;
|
wxArrayString earr;
|
||||||
earr.Clear();
|
|
||||||
if(error == 0) return earr;
|
if(error == 0) return earr;
|
||||||
|
|
||||||
earr.Add("Unknown error");
|
earr.Add("Unknown error");
|
||||||
|
@ -27,12 +27,13 @@ protected:
|
|||||||
wxWindow* DisAsmFrame;
|
wxWindow* DisAsmFrame;
|
||||||
u32 m_id;
|
u32 m_id;
|
||||||
PPCThreadType m_type;
|
PPCThreadType m_type;
|
||||||
u64 m_arg;
|
u64 m_args[4];
|
||||||
u64 m_prio;
|
u64 m_prio;
|
||||||
bool m_joinable;
|
bool m_joinable;
|
||||||
bool m_joining;
|
bool m_joining;
|
||||||
Array<u64> argv_addr;
|
Array<u64> argv_addr;
|
||||||
u64 m_offset;
|
u64 m_offset;
|
||||||
|
u32 m_exit_status;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
u64 stack_size;
|
u64 stack_size;
|
||||||
@ -47,14 +48,17 @@ public:
|
|||||||
virtual u64 GetStackAddr() const { return stack_addr; }
|
virtual u64 GetStackAddr() const { return stack_addr; }
|
||||||
virtual u64 GetStackSize() const { return stack_size; }
|
virtual u64 GetStackSize() const { return stack_size; }
|
||||||
virtual u64 GetFreeStackSize() const=0;
|
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 SetId(const u32 id);
|
||||||
void SetName(const wxString& name);
|
void SetName(const wxString& name);
|
||||||
void SetPrio(const u64 prio) { m_prio = prio; }
|
void SetPrio(const u64 prio) { m_prio = prio; }
|
||||||
void SetOffset(const u64 offset) { m_offset = offset; }
|
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; }
|
u64 GetPrio() const { return m_prio; }
|
||||||
wxString GetName() const { return m_name; }
|
wxString GetName() const { return m_name; }
|
||||||
wxString GetFName() const
|
wxString GetFName() const
|
||||||
|
@ -274,9 +274,9 @@ private:
|
|||||||
{
|
{
|
||||||
DisAsm_V2("vlogefp", vd, vb);
|
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)
|
void VMAXFP(u32 vd, u32 va, u32 vb)
|
||||||
{
|
{
|
||||||
@ -1166,10 +1166,17 @@ private:
|
|||||||
{
|
{
|
||||||
DisAsm_R3_OE_RC("adde", rd, ra, rb, oe, rc);
|
DisAsm_R3_OE_RC("adde", rd, ra, rb, oe, rc);
|
||||||
}
|
}
|
||||||
void MTOCRF(u32 crm, u32 rs)
|
void MTOCRF(u32 l, u32 crm, u32 rs)
|
||||||
|
{
|
||||||
|
if(l)
|
||||||
{
|
{
|
||||||
DisAsm_INT1_R1("mtocrf", crm, rs);
|
DisAsm_INT1_R1("mtocrf", crm, rs);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisAsm_INT1_R1("mtcrf", crm, rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
void STDX(u32 rs, u32 ra, u32 rb)
|
void STDX(u32 rs, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
DisAsm_R3("stdx.", rs, ra, rb);
|
DisAsm_R3("stdx.", rs, ra, rb);
|
||||||
@ -1284,10 +1291,6 @@ private:
|
|||||||
{
|
{
|
||||||
DisAsm_V1_R2("lvxl", vd, ra, rb);
|
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)
|
void MFTB(u32 rd, u32 spr)
|
||||||
{
|
{
|
||||||
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
|
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
|
||||||
|
@ -125,8 +125,10 @@ namespace PPU_instr
|
|||||||
*/
|
*/
|
||||||
static CodeField<30> AA;
|
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.
|
Link bit.
|
||||||
0 Does not update the link register (LR).
|
0 Does not update the link register (LR).
|
||||||
@ -177,36 +179,7 @@ namespace PPU_instr
|
|||||||
static CodeFieldSigned<16, 31> D;
|
static CodeFieldSigned<16, 31> D;
|
||||||
|
|
||||||
//
|
//
|
||||||
struct : public CodeFieldSigned<16, 31>
|
static CodeFieldSignedOffset<16, 29, 2> DS;
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
//This immediate field is used to specify a 16-bit signed integer
|
//This immediate field is used to specify a 16-bit signed integer
|
||||||
static CodeFieldSigned<16, 31> simm16;
|
static CodeFieldSigned<16, 31> simm16;
|
||||||
@ -269,7 +242,7 @@ namespace PPU_instr
|
|||||||
bind_instr(main_list, ADDIS, RD, RA, simm16);
|
bind_instr(main_list, ADDIS, RD, RA, simm16);
|
||||||
bind_instr(main_list, BC, BO, BI, BD, AA, LK);
|
bind_instr(main_list, BC, BO, BI, BD, AA, LK);
|
||||||
bind_instr(main_list, SC, SYS);
|
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, RLWIMI, RA, RS, SH, MB, ME, RC);
|
||||||
bind_instr(main_list, RLWINM, 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);
|
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, STFD, FRS, RA, D);
|
||||||
bind_instr(main_list, STFDU, 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, VMHADDSHS, VD, VA, VB, VC);
|
||||||
bind_instr(g04_list, VMHRADDSHS, VD, VA, VB, VC);
|
bind_instr(g04_list, VMHRADDSHS, VD, VA, VB, VC);
|
||||||
bind_instr(g04_list, VMLADDUHM, 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);
|
/*0x087*/bind_instr(g1f_list, STVEBX, VS, RA, RB);
|
||||||
/*0x088*/bind_instr(g1f_list, SUBFE, RD, RA, RB, OE, RC);
|
/*0x088*/bind_instr(g1f_list, SUBFE, RD, RA, RB, OE, RC);
|
||||||
/*0x08a*/bind_instr(g1f_list, ADDE, 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);
|
/*0x095*/bind_instr(g1f_list, STDX, RS, RA, RB);
|
||||||
/*0x096*/bind_instr(g1f_list, STWCX_, RS, RA, RB);
|
/*0x096*/bind_instr(g1f_list, STWCX_, RS, RA, RB);
|
||||||
/*0x097*/bind_instr(g1f_list, STWX, 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);
|
/*0x156*/bind_instr(g1f_list, DST, RA, RB, STRM, L_6);
|
||||||
/*0x157*/bind_instr(g1f_list, LHAX, RD, RA, RB);
|
/*0x157*/bind_instr(g1f_list, LHAX, RD, RA, RB);
|
||||||
/*0x167*/bind_instr(g1f_list, LVXL, VD, 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);
|
/*0x173*/bind_instr(g1f_list, MFTB, RD, SPR);
|
||||||
/*0x176*/bind_instr(g1f_list, DSTST, RA, RB, STRM, L_6);
|
/*0x176*/bind_instr(g1f_list, DSTST, RA, RB, STRM, L_6);
|
||||||
/*0x177*/bind_instr(g1f_list, LHAUX, RD, RA, RB);
|
/*0x177*/bind_instr(g1f_list, LHAUX, RD, RA, RB);
|
||||||
@ -554,7 +526,7 @@ namespace PPU_instr
|
|||||||
/*0x1d3*/bind_instr(g1f_list, MTSPR, SPR, RS);
|
/*0x1d3*/bind_instr(g1f_list, MTSPR, SPR, RS);
|
||||||
/*0x1d6*///DCBI
|
/*0x1d6*///DCBI
|
||||||
/*0x1dc*/bind_instr(g1f_list, NAND, RA, RS, RB, RC);
|
/*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);
|
/*0x1e9*/bind_instr(g1f_list, DIVD, RD, RA, RB, OE, RC);
|
||||||
/*0x1eb*/bind_instr(g1f_list, DIVW, 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);
|
/*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);
|
/*0x257*/bind_instr(g1f_list, LFDX, FRD, RA, RB);
|
||||||
/*0x277*/bind_instr(g1f_list, LFDUX, FRD, RA, RB);
|
/*0x277*/bind_instr(g1f_list, LFDUX, FRD, RA, RB);
|
||||||
/*0x287*/bind_instr(g1f_list, STVLX, VS, 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);
|
/*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);
|
/*0x307*/bind_instr(g1f_list, LVLXL, VD, RA, RB);
|
||||||
/*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB);
|
/*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB);
|
||||||
/*0x318*/bind_instr(g1f_list, SRAW, RA, RS, RB, RC);
|
/*0x318*/bind_instr(g1f_list, SRAW, RA, RS, RB, RC);
|
||||||
@ -588,7 +560,7 @@ namespace PPU_instr
|
|||||||
/*0x3d6*///ICBI
|
/*0x3d6*///ICBI
|
||||||
/*0x3f6*/bind_instr(g1f_list, DCBZ, RA, RB);
|
/*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(g3a_list, LDU, RD, RA, DS);
|
||||||
|
|
||||||
bind_instr(g3b_list, FDIVS, FRD, FRA, FRB, RC);
|
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, FNMSUBS, FRD, FRA, FRC, FRB, RC);
|
||||||
bind_instr(g3b_list, FNMADDS, 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(g3e_list, STDU, RS, RA, DS);
|
||||||
|
|
||||||
bind_instr(g3f_list, FSEL, FRD, FRA, FRC, FRB, RC);
|
bind_instr(g3f_list, FSEL, FRD, FRA, FRC, FRB, RC);
|
||||||
|
@ -97,18 +97,12 @@ private:
|
|||||||
const u8 bo1 = (bo & 0x08) ? 1 : 0;
|
const u8 bo1 = (bo & 0x08) ? 1 : 0;
|
||||||
const u8 bo2 = (bo & 0x04) ? 1 : 0;
|
const u8 bo2 = (bo & 0x04) ? 1 : 0;
|
||||||
const u8 bo3 = (bo & 0x02) ? 1 : 0;
|
const u8 bo3 = (bo & 0x02) ? 1 : 0;
|
||||||
const u8 bo4 = (bo & 0x01) ? 1 : 0;
|
|
||||||
|
|
||||||
if(!bo2) --CPU.CTR;
|
if(!bo2) --CPU.CTR;
|
||||||
|
|
||||||
const u8 ctr_ok = bo2 | ((CPU.CTR != 0) ^ bo3);
|
const u8 ctr_ok = bo2 | ((CPU.CTR != 0) ^ bo3);
|
||||||
const u8 cond_ok = bo0 | (CPU.IsCR(bi) ^ (~bo1 & 0x1));
|
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;
|
return ctr_ok && cond_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,7 +799,7 @@ private:
|
|||||||
CPU.VPR[vd]._f[w] = log(CPU.VPR[vb]._f[w]) / log(2.0f);
|
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++)
|
for (uint w = 0; w < 4; w++)
|
||||||
{
|
{
|
||||||
@ -2549,7 +2543,9 @@ private:
|
|||||||
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
|
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
|
||||||
if(oe) UNK("addeo");
|
if(oe) UNK("addeo");
|
||||||
}
|
}
|
||||||
void MTOCRF(u32 crm, u32 rs)
|
void MTOCRF(u32 l, u32 crm, u32 rs)
|
||||||
|
{
|
||||||
|
if(l)
|
||||||
{
|
{
|
||||||
u32 n = 0, count = 0;
|
u32 n = 0, count = 0;
|
||||||
for(u32 i=0; i<8; ++i)
|
for(u32 i=0; i<8; ++i)
|
||||||
@ -2566,7 +2562,19 @@ private:
|
|||||||
//CR[4*n : 4*n+3] = RS[32+4*n : 32+4*n+3];
|
//CR[4*n : 4*n+3] = RS[32+4*n : 32+4*n+3];
|
||||||
CPU.SetCR(n, (CPU.GPR[rs] >> (4*n)) & 0xf);
|
CPU.SetCR(n, (CPU.GPR[rs] >> (4*n)) & 0xf);
|
||||||
}
|
}
|
||||||
else CPU.CR.CR = 0;
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void STDX(u32 rs, u32 ra, u32 rb)
|
void STDX(u32 rs, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -2584,6 +2592,7 @@ private:
|
|||||||
{
|
{
|
||||||
Memory.Write32(addr, CPU.GPR[rs]);
|
Memory.Write32(addr, CPU.GPR[rs]);
|
||||||
CPU.SetCR_EQ(0, true);
|
CPU.SetCR_EQ(0, true);
|
||||||
|
CPU.reserve = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2732,12 +2741,6 @@ private:
|
|||||||
{
|
{
|
||||||
CPU.VPR[vd]._u128 = Memory.Read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
|
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)
|
void MFTB(u32 rd, u32 spr)
|
||||||
{
|
{
|
||||||
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
|
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
|
||||||
@ -3175,8 +3178,41 @@ private:
|
|||||||
}
|
}
|
||||||
void FDIVS(u32 frd, u32 fra, u32 frb, bool rc)
|
void FDIVS(u32 frd, u32 fra, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
|
if(FPRdouble::IsNaN(CPU.FPR[fra]))
|
||||||
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] / CPU.FPR[frb]);
|
{
|
||||||
|
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();
|
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
|
||||||
if(rc) UNK("fdivs.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
if(rc) UNK("fdivs.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
@ -3194,13 +3230,17 @@ private:
|
|||||||
}
|
}
|
||||||
void FSQRTS(u32 frd, u32 frb, bool rc)
|
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]);
|
if(rc) UNK("fsqrts.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FRES(u32 frd, u32 frb, bool rc)
|
void FRES(u32 frd, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
|
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
|
||||||
CPU.FPR[frd] = static_cast<float>(1.0f/CPU.FPR[frb]);
|
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]);
|
if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FMULS(u32 frd, u32 fra, u32 frc, bool rc)
|
void FMULS(u32 frd, u32 fra, u32 frc, bool rc)
|
||||||
|
@ -318,7 +318,6 @@ namespace PPU_opcodes
|
|||||||
DST = 0x156, //Data Stream Touch
|
DST = 0x156, //Data Stream Touch
|
||||||
LHAX = 0x157,
|
LHAX = 0x157,
|
||||||
LVXL = 0x167, //Load Vector Indexed Last
|
LVXL = 0x167, //Load Vector Indexed Last
|
||||||
ABS = 0x168,
|
|
||||||
MFTB = 0x173,
|
MFTB = 0x173,
|
||||||
DSTST = 0x176, //Data Stream Touch for Store
|
DSTST = 0x176, //Data Stream Touch for Store
|
||||||
LHAUX = 0x177,
|
LHAUX = 0x177,
|
||||||
@ -436,7 +435,7 @@ public:
|
|||||||
|
|
||||||
static u64 branchTarget(const u64 pc, const u64 imm)
|
static u64 branchTarget(const u64 pc, const u64 imm)
|
||||||
{
|
{
|
||||||
return pc + (imm & ~0x3);
|
return pc + (imm & ~0x3ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void NULL_OP() = 0;
|
virtual void NULL_OP() = 0;
|
||||||
@ -498,7 +497,7 @@ public:
|
|||||||
virtual void VCTUXS(u32 vd, u32 uimm5, u32 vb) = 0;
|
virtual void VCTUXS(u32 vd, u32 uimm5, u32 vb) = 0;
|
||||||
virtual void VEXPTEFP(u32 vd, u32 vb) = 0;
|
virtual void VEXPTEFP(u32 vd, u32 vb) = 0;
|
||||||
virtual void VLOGEFP(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 VMAXFP(u32 vd, u32 va, u32 vb) = 0;
|
||||||
virtual void VMAXSB(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;
|
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 STVEBX(u32 vs, u32 ra, u32 rb) = 0;
|
||||||
virtual void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 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 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 STDX(u32 rs, u32 ra, u32 rb) = 0;
|
||||||
virtual void STWCX_(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;
|
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 DST(u32 ra, u32 rb, u32 strm, u32 t) = 0;
|
||||||
virtual void LHAX(u32 rd, u32 ra, u32 rb) = 0;
|
virtual void LHAX(u32 rd, u32 ra, u32 rb) = 0;
|
||||||
virtual void LVXL(u32 vd, 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 MFTB(u32 rd, u32 spr) = 0;
|
||||||
virtual void DSTST(u32 ra, u32 rb, u32 strm, u32 t) = 0;
|
virtual void DSTST(u32 ra, u32 rb, u32 strm, u32 t) = 0;
|
||||||
virtual void LHAUX(u32 rd, u32 ra, u32 rb) = 0;
|
virtual void LHAUX(u32 rd, u32 ra, u32 rb) = 0;
|
||||||
|
@ -68,19 +68,6 @@ void PPUThread::InitRegs()
|
|||||||
|
|
||||||
SetPc(pc);
|
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());
|
const s32 thread_num = Emu.GetCPU().GetThreadNumById(!IsSPU(), GetId());
|
||||||
|
|
||||||
if(thread_num < 0)
|
if(thread_num < 0)
|
||||||
@ -106,22 +93,41 @@ void PPUThread::InitRegs()
|
|||||||
GPR[1] = stack_point;
|
GPR[1] = stack_point;
|
||||||
GPR[2] = rtoc;
|
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[3] = argc;
|
||||||
GPR[4] = argv;
|
GPR[4] = argv;
|
||||||
GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk
|
GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk
|
||||||
}
|
}
|
||||||
else
|
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[0] = pc;
|
||||||
GPR[8] = entry;
|
GPR[8] = entry;
|
||||||
GPR[11] = 0x80;
|
GPR[11] = 0x80;
|
||||||
GPR[12] = Emu.GetMallocPageSize();
|
GPR[12] = Emu.GetMallocPageSize();
|
||||||
GPR[13] = Memory.PRXMem.Alloc(0x10000) + 0x7060 - 8;
|
GPR[13] = prx_mem + 0x7060;
|
||||||
GPR[28] = GPR[4];
|
GPR[28] = GPR[4];
|
||||||
GPR[29] = GPR[3];
|
GPR[29] = GPR[3];
|
||||||
GPR[31] = GPR[5];
|
GPR[31] = GPR[5];
|
||||||
@ -172,15 +178,30 @@ bool dump_enable = false;
|
|||||||
|
|
||||||
void PPUThread::DoCode(const s32 code)
|
void PPUThread::DoCode(const s32 code)
|
||||||
{
|
{
|
||||||
|
static bool is_last_enabled = false;
|
||||||
|
|
||||||
if(dump_enable)
|
if(dump_enable)
|
||||||
{
|
{
|
||||||
static wxFile f("dump.txt", wxFile::write);
|
static wxFile f("dump.txt", wxFile::write);
|
||||||
static PPU_DisAsm disasm(*this, DumpMode);
|
static PPU_DisAsm disasm(*this, DumpMode);
|
||||||
static PPU_Decoder decoder(disasm);
|
static PPU_Decoder decoder(disasm);
|
||||||
|
|
||||||
|
if(!is_last_enabled)
|
||||||
|
{
|
||||||
|
f.Write(RegsToString() + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
disasm.dump_pc = PC;
|
disasm.dump_pc = PC;
|
||||||
decoder.Decode(code);
|
decoder.Decode(code);
|
||||||
f.Write(disasm.last_opcode);
|
f.Write(disasm.last_opcode);
|
||||||
|
|
||||||
|
is_last_enabled = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_last_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(++cycle > 220)
|
if(++cycle > 220)
|
||||||
{
|
{
|
||||||
@ -193,7 +214,7 @@ void PPUThread::DoCode(const s32 code)
|
|||||||
|
|
||||||
bool FPRdouble::IsINF(PPCdouble d)
|
bool FPRdouble::IsINF(PPCdouble d)
|
||||||
{
|
{
|
||||||
return wxFinite(d) ? 1 : 0;
|
return d.GetType() == FPR_INF;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FPRdouble::IsNaN(PPCdouble d)
|
bool FPRdouble::IsNaN(PPCdouble d)
|
||||||
|
@ -18,6 +18,18 @@ enum
|
|||||||
CR_SO = 0x1,
|
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
|
enum FPSCR_EXP
|
||||||
{
|
{
|
||||||
FPSCR_FX = 0x80000000,
|
FPSCR_FX = 0x80000000,
|
||||||
@ -302,6 +314,9 @@ enum FPRType
|
|||||||
FPR_ND = 0x18,
|
FPR_ND = 0x18,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u64 FPR_NAN_I = 0x7FF8000000000000ULL;
|
||||||
|
static const double& FPR_NAN = (double&)FPR_NAN_I;
|
||||||
|
|
||||||
struct PPCdouble
|
struct PPCdouble
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
@ -30,7 +30,11 @@ void SPUThread::DoReset()
|
|||||||
|
|
||||||
void SPUThread::InitRegs()
|
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
|
u64 SPUThread::GetFreeStackSize() const
|
||||||
|
@ -461,7 +461,7 @@ void GLGSRender::InitVertexData()
|
|||||||
void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count)
|
void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 count)
|
||||||
{
|
{
|
||||||
#if CMD_DEBUG
|
#if CMD_DEBUG
|
||||||
wxString debug = getMethodName(cmd);
|
wxString debug = GetMethodName(cmd);
|
||||||
debug += "(";
|
debug += "(";
|
||||||
for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + wxString::Format("0x%x", args[i]);
|
for(u32 i=0; i<count; ++i) debug += (i ? ", " : "") + wxString::Format("0x%x", args[i]);
|
||||||
debug += ")";
|
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);
|
m_indexed_array.m_data.InsertRoomEnd(4);
|
||||||
index = Memory.Read32(m_indexed_array.m_addr + i * 4);
|
index = Memory.Read32(m_indexed_array.m_addr + i * 4);
|
||||||
*(u32*)&m_indexed_array.m_data[pos] = index;
|
*(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;
|
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();
|
int pos = m_indexed_array.m_data.GetCount();
|
||||||
m_indexed_array.m_data.InsertRoomEnd(2);
|
m_indexed_array.m_data.InsertRoomEnd(2);
|
||||||
index = Memory.Read16(m_indexed_array.m_addr + i * 2);
|
index = Memory.Read16(m_indexed_array.m_addr + i * 2);
|
||||||
ConLog.Warning("index 2: %d", index);
|
//ConLog.Warning("index 2: %d", index);
|
||||||
*(u32*)&m_indexed_array.m_data[pos] = index;
|
*(u16*)&m_indexed_array.m_data[pos] = index;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1294,13 +1294,13 @@ void GLGSRender::ExecCMD()
|
|||||||
case 0:
|
case 0:
|
||||||
glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_INT, nullptr);
|
||||||
checkForGlError("glDrawElements #4");
|
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;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr);
|
glDrawElements(m_draw_mode, m_indexed_array.m_count, GL_UNSIGNED_SHORT, nullptr);
|
||||||
checkForGlError("glDrawElements #2");
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1310,7 +1310,7 @@ void GLGSRender::ExecCMD()
|
|||||||
|
|
||||||
DisableVertexData();
|
DisableVertexData();
|
||||||
m_indexed_array.Reset();
|
m_indexed_array.Reset();
|
||||||
Emu.Pause();
|
//Emu.Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_draw_array_count)
|
if(m_draw_array_count)
|
||||||
|
@ -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
|
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
|
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
|
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, 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, 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
|
null_func, null_func, null_func, null_func, null_func, //189
|
||||||
@ -260,6 +260,7 @@ void SysCalls::DoSyscall(u32 code)
|
|||||||
|
|
||||||
case 999:
|
case 999:
|
||||||
dump_enable = !dump_enable;
|
dump_enable = !dump_enable;
|
||||||
|
Emu.Pause();
|
||||||
ConLog.Warning("Dump %s", dump_enable ? "enabled" : "disabled");
|
ConLog.Warning("Dump %s", dump_enable ? "enabled" : "disabled");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -251,6 +251,7 @@ extern int sys_heap_malloc(const u32 heap_addr, const u32 size);
|
|||||||
//sys_spu
|
//sys_spu
|
||||||
extern int sys_spu_image_open(u32 img_addr, u32 path_addr);
|
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_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_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_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);
|
extern int sys_spu_thread_create(u64 thread_id_addr, u64 entry_addr, u64 arg, int prio, u32 stacksize, u64 flags, u64 threadname_addr);
|
||||||
|
@ -7,6 +7,14 @@ extern Module cellGcmSys;
|
|||||||
CellGcmConfig current_config;
|
CellGcmConfig current_config;
|
||||||
CellGcmContextData current_context;
|
CellGcmContextData current_context;
|
||||||
gcmInfo gcm_info;
|
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)
|
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_size = 0xf900000; //TODO
|
||||||
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
|
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
|
||||||
|
|
||||||
|
map_offset_addr = 0;
|
||||||
|
map_offset_pos = 0;
|
||||||
current_config.ioSize = re32(ioSize);
|
current_config.ioSize = re32(ioSize);
|
||||||
current_config.ioAddress = re32(ioAddress);
|
current_config.ioAddress = re32(ioAddress);
|
||||||
current_config.localSize = re32(local_size);
|
current_config.localSize = re32(local_size);
|
||||||
@ -91,10 +101,19 @@ int cellGcmAddressToOffset(u32 address, u32 offset_addr)
|
|||||||
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, 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(!Memory.IsGoodAddr(offset_addr, sizeof(u32))) return CELL_EFAULT;
|
||||||
|
|
||||||
Memory.Write32(offset_addr,
|
if(!map_offset_addr)
|
||||||
Memory.RSXFBMem.IsInMyRange(address)
|
{
|
||||||
? address - Memory.RSXFBMem.GetStartAddr()
|
map_offset_addr = Memory.Alloc(4*50, 4);
|
||||||
: 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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -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());
|
Memory.Write32(thread_id_addr, new_thread.GetId());
|
||||||
new_thread.SetEntry(entry);
|
new_thread.SetEntry(entry);
|
||||||
new_thread.SetArg(arg);
|
new_thread.SetArg(0, arg);
|
||||||
new_thread.SetPrio(prio);
|
new_thread.SetPrio(prio);
|
||||||
new_thread.stack_size = stacksize;
|
new_thread.stack_size = stacksize;
|
||||||
//new_thread.flags = flags;
|
//new_thread.flags = flags;
|
||||||
|
@ -36,14 +36,16 @@ struct sys_spu_image
|
|||||||
int nsegs;
|
int nsegs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u32 g_spu_group_thr_count = 255;
|
||||||
|
|
||||||
struct SpuGroupInfo
|
struct SpuGroupInfo
|
||||||
{
|
{
|
||||||
PPCThread* threads[10];
|
PPCThread* threads[g_spu_group_thr_count];
|
||||||
sys_spu_thread_group_attribute& attr;
|
sys_spu_thread_group_attribute& attr;
|
||||||
|
|
||||||
SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(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())
|
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;
|
delete stream;
|
||||||
|
|
||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
@ -83,7 +85,7 @@ int sys_spu_image_open(u32 img_addr, u32 path_addr)
|
|||||||
u32 entry = LoadSpuImage(*stream);
|
u32 entry = LoadSpuImage(*stream);
|
||||||
delete 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.type, 1);
|
||||||
re(ret.entry_point, entry);
|
re(ret.entry_point, entry);
|
||||||
re(ret.segs_addr, 0x0);
|
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;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpuGroupInfo& group_info = *(SpuGroupInfo*)Emu.GetIdManager().GetIDData(group).m_data;
|
||||||
|
|
||||||
if(
|
if(
|
||||||
!Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) ||
|
!Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) ||
|
||||||
!Memory.IsGoodAddr(attr_addr, sizeof(sys_spu_thread_attribute)) ||
|
!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;
|
return CELL_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_spu_image& img = (sys_spu_image&)Memory[img_addr];
|
auto& img = (sys_spu_image&)Memory[img_addr];
|
||||||
sys_spu_thread_attribute& attr = (sys_spu_thread_attribute&)Memory[attr_addr];
|
auto& attr = (sys_spu_thread_attribute&)Memory[attr_addr];
|
||||||
sys_spu_thread_argument& arg = (sys_spu_thread_argument&)Memory[arg_addr];
|
auto& arg = (sys_spu_thread_argument&)Memory[arg_addr];
|
||||||
|
|
||||||
if(!Memory.IsGoodAddr(re(attr.name_addr), re(attr.name_len)))
|
if(!Memory.IsGoodAddr(re(attr.name_addr), re(attr.name_len)))
|
||||||
{
|
{
|
||||||
return CELL_EFAULT;
|
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);
|
u32 entry = re(img.entry_point);
|
||||||
wxString name = Memory.ReadString(re(attr.name_addr), re(attr.name_len));
|
wxString name = Memory.ReadString(re(attr.name_addr), re(attr.name_len));
|
||||||
u64 a1 = re(arg.arg1);
|
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.SetOffset(g_spu_offset);
|
||||||
new_thread.SetEntry(entry - g_spu_offset);
|
new_thread.SetEntry(entry - g_spu_offset);
|
||||||
new_thread.SetName(name);
|
new_thread.SetName(name);
|
||||||
SPU_GPR_hdr* GPR = ((SPUThread&)new_thread).GPR;
|
|
||||||
new_thread.Run();
|
new_thread.Run();
|
||||||
new_thread.Pause();
|
new_thread.Pause();
|
||||||
GPR[3]._u64[1] = a1;
|
new_thread.SetArg(0, a1);
|
||||||
GPR[4]._u64[1] = a2;
|
new_thread.SetArg(1, a2);
|
||||||
GPR[5]._u64[1] = a3;
|
new_thread.SetArg(2, a3);
|
||||||
GPR[6]._u64[1] = a4;
|
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;
|
group_info.threads[spu_num] = &new_thread;
|
||||||
|
|
||||||
return CELL_OK;
|
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
|
//173
|
||||||
int sys_spu_thread_group_start(u32 id)
|
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;
|
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||||
|
|
||||||
Emu.Pause();
|
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])
|
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;
|
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
|
//160
|
||||||
int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
|
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;
|
SpuGroupInfo* group = (SpuGroupInfo*)Emu.GetIdManager().GetIDData(id).m_data;
|
||||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(eq).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])
|
if(group->threads[i])
|
||||||
{
|
{
|
||||||
|
@ -85,8 +85,6 @@ void Emulator::Load()
|
|||||||
Memory.Init();
|
Memory.Init();
|
||||||
GetInfo().Reset();
|
GetInfo().Reset();
|
||||||
|
|
||||||
Memory.Write64(Memory.PRXMem.Alloc(8), 0xDEADBEEFABADCAFE);
|
|
||||||
|
|
||||||
bool is_error;
|
bool is_error;
|
||||||
vfsLocalFile f(m_path);
|
vfsLocalFile f(m_path);
|
||||||
Loader l(f);
|
Loader l(f);
|
||||||
@ -127,9 +125,6 @@ void Emulator::Load()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
thread.SetEntry(l.GetEntry());
|
thread.SetEntry(l.GetEntry());
|
||||||
}
|
|
||||||
|
|
||||||
thread.SetArg(thread.GetId());
|
|
||||||
Memory.StackMem.Alloc(0x1000);
|
Memory.StackMem.Alloc(0x1000);
|
||||||
thread.InitStack();
|
thread.InitStack();
|
||||||
thread.AddArgv(m_path);
|
thread.AddArgv(m_path);
|
||||||
@ -149,6 +144,7 @@ void Emulator::Load()
|
|||||||
ppu_thr_exit_data += ADDI(11, 0, 41);
|
ppu_thr_exit_data += ADDI(11, 0, 41);
|
||||||
ppu_thr_exit_data += SC(2);
|
ppu_thr_exit_data += SC(2);
|
||||||
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
|
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
thread.Run();
|
thread.Run();
|
||||||
|
|
||||||
|
@ -99,16 +99,9 @@ DebuggerPanel::DebuggerPanel(wxWindow* parent) : wxPanel(parent, wxID_ANY, wxDef
|
|||||||
{
|
{
|
||||||
m_aui_mgr.SetManagedWindow(this);
|
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(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_aui_mgr.Update();
|
||||||
|
|
||||||
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(DebuggerPanel::HandleCommand), (wxObject*)0, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerPanel::~DebuggerPanel()
|
DebuggerPanel::~DebuggerPanel()
|
||||||
@ -119,30 +112,3 @@ DebuggerPanel::~DebuggerPanel()
|
|||||||
void DebuggerPanel::UpdateUI()
|
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();
|
|
||||||
}
|
|
@ -5,13 +5,10 @@
|
|||||||
class DebuggerPanel : public wxPanel
|
class DebuggerPanel : public wxPanel
|
||||||
{
|
{
|
||||||
wxAuiManager m_aui_mgr;
|
wxAuiManager m_aui_mgr;
|
||||||
wxAuiNotebook* m_nb;
|
|
||||||
AppConnector m_app_connector;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DebuggerPanel(wxWindow* parent);
|
DebuggerPanel(wxWindow* parent);
|
||||||
~DebuggerPanel();
|
~DebuggerPanel();
|
||||||
|
|
||||||
void UpdateUI();
|
void UpdateUI();
|
||||||
void HandleCommand(wxCommandEvent& event);
|
|
||||||
};
|
};
|
@ -3,35 +3,25 @@
|
|||||||
|
|
||||||
//static const int show_lines = 30;
|
//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);
|
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)
|
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(500, 700), wxTAB_TRAVERSAL)
|
||||||
, ThreadBase(false, "DisAsmFrame Thread")
|
, ThreadBase(false, "DisAsmFrame Thread")
|
||||||
, CPU(*cpu)
|
|
||||||
, PC(0)
|
, PC(0)
|
||||||
|
, CPU(nullptr)
|
||||||
, m_item_count(30)
|
, 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_p_main = *new wxBoxSizer(wxVERTICAL);
|
||||||
wxBoxSizer& s_b_main = *new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer& s_b_main = *new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
m_list = new wxListView(this);
|
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_addr = *new wxButton(this, wxID_ANY, "Go To Address");
|
||||||
wxButton& b_go_to_pc = *new wxButton(this, wxID_ANY, "Go To PC");
|
wxButton& b_go_to_pc = *new wxButton(this, wxID_ANY, "Go To PC");
|
||||||
@ -45,6 +35,7 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent, PPCThread* cpu)
|
|||||||
s_b_main.Add(m_btn_step, 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_run, wxSizerFlags().Border(wxALL, 5));
|
||||||
s_b_main.Add(m_btn_pause, 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,
|
m_regs = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
|
||||||
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_DONTWRAP|wxNO_BORDER|wxTE_RICH2);
|
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_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_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(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
|
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(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_KEY_DOWN, wxKeyEventHandler(InterpreterDisAsmFrame::OnKeyDown), (wxObject*)0, this);
|
||||||
|
|
||||||
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(InterpreterDisAsmFrame::HandleCommand), (wxObject*)0, this);
|
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(InterpreterDisAsmFrame::HandleCommand), (wxObject*)0, this);
|
||||||
WriteRegs();
|
|
||||||
|
ShowAddr(CentrePc(PC));
|
||||||
|
UpdateUnitList();
|
||||||
}
|
}
|
||||||
|
|
||||||
InterpreterDisAsmFrame::~InterpreterDisAsmFrame()
|
InterpreterDisAsmFrame::~InterpreterDisAsmFrame()
|
||||||
@ -90,6 +83,48 @@ InterpreterDisAsmFrame::~InterpreterDisAsmFrame()
|
|||||||
ThreadBase::Stop();
|
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)
|
void InterpreterDisAsmFrame::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
if(wxGetActiveWindow() != wxGetTopLevelParent(this))
|
if(wxGetActiveWindow() != wxGetTopLevelParent(this))
|
||||||
@ -164,17 +199,27 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
|
|||||||
{
|
{
|
||||||
PC = addr;
|
PC = addr;
|
||||||
m_list->Freeze();
|
m_list->Freeze();
|
||||||
disasm->offset = CPU.GetOffset();
|
|
||||||
|
if(!CPU)
|
||||||
|
{
|
||||||
for(uint i=0; i<m_item_count; ++i, PC += 4)
|
for(uint i=0; i<m_item_count; ++i, PC += 4)
|
||||||
{
|
{
|
||||||
if(!Memory.IsGoodAddr(CPU.GetOffset() + PC, 4))
|
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
disasm->offset = CPU->GetOffset();
|
||||||
|
for(uint i=0; i<m_item_count; ++i, PC += 4)
|
||||||
|
{
|
||||||
|
if(!Memory.IsGoodAddr(CPU->GetOffset() + PC, 4))
|
||||||
{
|
{
|
||||||
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
|
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
disasm->dump_pc = PC;
|
disasm->dump_pc = PC;
|
||||||
decoder->Decode(Memory.Read32(CPU.GetOffset() + PC));
|
decoder->Decode(Memory.Read32(CPU->GetOffset() + PC));
|
||||||
|
|
||||||
if(IsBreakPoint(PC))
|
if(IsBreakPoint(PC))
|
||||||
{
|
{
|
||||||
@ -187,7 +232,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
|
|||||||
|
|
||||||
wxColour colour;
|
wxColour colour;
|
||||||
|
|
||||||
if((!CPU.IsRunned() || !Emu.IsRunned()) && PC == CPU.PC)
|
if((!CPU->IsRunned() || !Emu.IsRunned()) && PC == CPU->PC)
|
||||||
{
|
{
|
||||||
colour = wxColour("Green");
|
colour = wxColour("Green");
|
||||||
}
|
}
|
||||||
@ -207,6 +252,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
|
|||||||
|
|
||||||
m_list->SetItemBackgroundColour( i, colour );
|
m_list->SetItemBackgroundColour( i, colour );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while(remove_markedPC.GetCount())
|
while(remove_markedPC.GetCount())
|
||||||
{
|
{
|
||||||
@ -234,7 +280,7 @@ void InterpreterDisAsmFrame::WriteRegs()
|
|||||||
{
|
{
|
||||||
m_regs->Freeze();
|
m_regs->Freeze();
|
||||||
m_regs->Clear();
|
m_regs->Clear();
|
||||||
m_regs->WriteText(CPU.RegsToString());
|
if(CPU) m_regs->WriteText(CPU->RegsToString());
|
||||||
m_regs->Thaw();
|
m_regs->Thaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +299,7 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(thr->GetId() == CPU.GetId())
|
else if(CPU && thr->GetId() == CPU->GetId())
|
||||||
{
|
{
|
||||||
switch(event.GetId())
|
switch(event.GetId())
|
||||||
{
|
{
|
||||||
@ -266,7 +312,6 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
|
|||||||
DoUpdate();
|
DoUpdate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case DID_START_THREAD:
|
case DID_START_THREAD:
|
||||||
case DID_EXEC_THREAD:
|
case DID_EXEC_THREAD:
|
||||||
case DID_RESUME_THREAD:
|
case DID_RESUME_THREAD:
|
||||||
@ -285,6 +330,36 @@ void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
|
|||||||
m_btn_run->Disable();
|
m_btn_run->Disable();
|
||||||
m_btn_step->Disable();
|
m_btn_step->Disable();
|
||||||
m_btn_pause->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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,11 +388,11 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
|
|||||||
|
|
||||||
diag->SetSizerAndFit( s_panel );
|
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)
|
if(diag->ShowModal() == wxID_OK)
|
||||||
{
|
{
|
||||||
u64 pc = CPU.PC;
|
u64 pc = CPU ? CPU->PC : 0x0;
|
||||||
sscanf(p_pc->GetLabel(), "%llx", &pc);
|
sscanf(p_pc->GetLabel(), "%llx", &pc);
|
||||||
remove_markedPC.AddCpy(Emu.GetMarkedPoints().AddCpy(pc));
|
remove_markedPC.AddCpy(Emu.GetMarkedPoints().AddCpy(pc));
|
||||||
ShowAddr(CentrePc(pc));
|
ShowAddr(CentrePc(pc));
|
||||||
@ -326,17 +401,19 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
|
|||||||
|
|
||||||
void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event))
|
void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
ShowAddr(CentrePc(CPU.PC));
|
if(CPU) ShowAddr(CentrePc(CPU->PC));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool dump_enable;
|
extern bool dump_enable;
|
||||||
void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
|
void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if(CPU.IsPaused()) CPU.Resume();
|
if(!CPU) return;
|
||||||
|
|
||||||
|
if(CPU->IsPaused()) CPU->Resume();
|
||||||
|
|
||||||
if(!Emu.IsPaused())
|
if(!Emu.IsPaused())
|
||||||
{
|
{
|
||||||
CPU.Exec();
|
CPU->Exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
//ThreadBase::Start();
|
//ThreadBase::Start();
|
||||||
@ -344,7 +421,7 @@ void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
|
|||||||
|
|
||||||
void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event))
|
void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
CPU.Pause();
|
if(CPU) CPU->Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
||||||
@ -418,7 +495,8 @@ bool InterpreterDisAsmFrame::RemoveBreakPoint(u64 pc)
|
|||||||
|
|
||||||
void InterpreterDisAsmFrame::Task()
|
void InterpreterDisAsmFrame::Task()
|
||||||
{
|
{
|
||||||
wxGetApp().SendDbgCommand(DID_RESUME_THREAD, &CPU);
|
if(!CPU) return;
|
||||||
|
wxGetApp().SendDbgCommand(DID_RESUME_THREAD, CPU);
|
||||||
|
|
||||||
bool dump_status = dump_enable;
|
bool dump_status = dump_enable;
|
||||||
|
|
||||||
@ -428,9 +506,9 @@ void InterpreterDisAsmFrame::Task()
|
|||||||
{
|
{
|
||||||
do
|
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)
|
catch(const wxString& e)
|
||||||
{
|
{
|
||||||
@ -443,5 +521,5 @@ void InterpreterDisAsmFrame::Task()
|
|||||||
|
|
||||||
//CPU.FreeTls();
|
//CPU.FreeTls();
|
||||||
|
|
||||||
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, &CPU);
|
wxGetApp().SendDbgCommand(DID_PAUSE_THREAD, CPU);
|
||||||
}
|
}
|
@ -20,16 +20,19 @@ class InterpreterDisAsmFrame
|
|||||||
wxButton* m_btn_pause;
|
wxButton* m_btn_pause;
|
||||||
AppConnector m_app_connector;
|
AppConnector m_app_connector;
|
||||||
u32 m_item_count;
|
u32 m_item_count;
|
||||||
|
wxChoice* m_choice_units;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPCThread& CPU;
|
PPCThread* CPU;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InterpreterDisAsmFrame(wxWindow* parent, PPCThread* cpu);
|
InterpreterDisAsmFrame(wxWindow* parent);
|
||||||
~InterpreterDisAsmFrame();
|
~InterpreterDisAsmFrame();
|
||||||
|
|
||||||
u32 CentrePc(const u32 pc) const;
|
void UpdateUnitList();
|
||||||
|
|
||||||
|
u64 CentrePc(const u64 pc) const;
|
||||||
|
void OnSelectUnit(wxCommandEvent& event);
|
||||||
void OnKeyDown(wxKeyEvent& event);
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
void OnResize(wxSizeEvent& event);
|
void OnResize(wxSizeEvent& event);
|
||||||
void DoUpdate();
|
void DoUpdate();
|
||||||
|
@ -30,13 +30,16 @@ bool SELFLoader::LoadData(u64 offset)
|
|||||||
if( !l.LoadEhdrInfo(self_hdr.se_elfoff) ||
|
if( !l.LoadEhdrInfo(self_hdr.se_elfoff) ||
|
||||||
!l.LoadPhdrInfo(self_hdr.se_phdroff) ||
|
!l.LoadPhdrInfo(self_hdr.se_phdroff) ||
|
||||||
!l.LoadShdrInfo(self_hdr.se_shdroff) ||
|
!l.LoadShdrInfo(self_hdr.se_shdroff) ||
|
||||||
!l.LoadData(offset) )
|
!l.LoadData(self_hdr.se_appinfooff) )
|
||||||
{
|
{
|
||||||
ConLog.Error("Broken SELF file.");
|
ConLog.Error("Broken SELF file.");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
machine = l.GetMachine();
|
||||||
|
entry = l.GetEntry();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ConLog.Error("Boot SELF not supported yet!");
|
ConLog.Error("Boot SELF not supported yet!");
|
||||||
|
Loading…
Reference in New Issue
Block a user