1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

- Implemented ARM9Interpreter & ARM9DisAsm.

- Implemented MemoryBlockLE & DynamicMemoryBlockLE.
- Implemented CPUDecoder.
This commit is contained in:
DH 2013-11-05 20:12:18 +02:00
parent 0b35be32a4
commit 6b22e7d90a
31 changed files with 475 additions and 177 deletions

View File

@ -0,0 +1,32 @@
#pragma once
#include "Emu/CPU/CPUDecoder.h"
#include "ARM9Opcodes.h"
class ARM9Decoder : public CPUDecoder
{
ARM9Opcodes& m_op;
public:
ARM9Decoder(ARM9Opcodes& op) : m_op(op)
{
}
virtual void DecodeMemory(const u64 address)
{
const u16 code0 = Memory.Read16(address);
const u16 code1 = Memory.Read16(address + 2);
const u16 opcode = code0;
switch(opcode)
{
case 0:
m_op.NULL_OP();
break;
default:
m_op.UNK(opcode, code0, code1);
break;
}
}
};

View File

@ -0,0 +1,36 @@
#pragma once
#include "Emu/ARM9/ARM9Opcodes.h"
#include "Emu/CPU/CPUDisAsm.h"
#include "Gui/DisAsmFrame.h"
#include "Emu/Memory/Memory.h"
class ARM9DisAsm
: public CPUDisAsm
, public ARM9Opcodes
{
public:
ARM9DisAsm(CPUDisAsmMode mode) : CPUDisAsm(mode)
{
}
protected:
virtual u32 DisAsmBranchTarget(const s32 imm)
{
return dump_pc + (imm << 2);
}
void NULL_OP()
{
Write("null");
}
void NOP()
{
Write("nop");
}
void UNK(const u16 opcode, const u16 code0, const u16 code1)
{
Write(wxString::Format("Unknown/Illegal opcode! (0x%04x : 0x%04x : 0x%04x)", opcode, code0, code1));
}
};

View File

@ -0,0 +1,29 @@
#pragma once
#include "Emu/ARM9/ARM9Opcodes.h"
class ARM9Interpreter : public ARM9Opcodes
{
ARM9Thread& CPU;
public:
ARM9Interpreter(ARM9Thread& cpu) : CPU(cpu)
{
}
protected:
void NULL_OP()
{
ConLog.Error("null");
Emu.Pause();
}
void NOP()
{
}
void UNK(const u16 opcode, const u16 code0, const u16 code1)
{
ConLog.Error("Unknown/Illegal opcode! (0x%04x : 0x%04x : 0x%04x)", opcode, code0, code1);
Emu.Pause();
}
};

View File

@ -0,0 +1,18 @@
#pragma once
namespace ARM9_opcodes
{
enum ARM9_MainOpcodes
{
};
}
class ARM9Opcodes
{
public:
virtual void NULL_OP() = 0;
virtual void NOP() = 0;
virtual void UNK(const u16 opcode, const u16 code0, const u16 code1) = 0;
};

View File

@ -1,5 +1,8 @@
#include "stdafx.h"
#include "ARM9Thread.h"
#include "ARM9Decoder.h"
#include "ARM9DisAsm.h"
#include "ARM9Interpreter.h"
ARM9Thread::ARM9Thread() : CPUThread(CPU_THREAD_ARM9)
{
@ -50,6 +53,17 @@ void ARM9Thread::DoReset()
void ARM9Thread::DoRun()
{
switch(Ini.CPUDecoderMode.GetValue())
{
case 0:
//m_dec = new PPUDecoder(*new PPUDisAsm());
break;
case 1:
case 2:
m_dec = new ARM9Decoder(*new ARM9Interpreter(*this));
break;
}
}
void ARM9Thread::DoPause()

View File

@ -2,6 +2,12 @@
#include "CPUInstrTable.h"
#pragma warning( disable : 4800 )
class CPUDecoder
{
public:
virtual void DecodeMemory(const u64 address)=0;
};
template<typename TO>
class InstrCaller
{

View File

@ -16,6 +16,8 @@ CPUThread::CPUThread(CPUThreadType type)
, m_sync_wait(false)
, m_wait_thread_id(-1)
, m_free_data(false)
, m_dec(nullptr)
, m_is_step(false)
{
}
@ -94,11 +96,6 @@ bool CPUThread::Sync()
int CPUThread::ThreadStatus()
{
if(m_is_step)
{
return CPUThread_Step;
}
if(Emu.IsStopped())
{
return CPUThread_Stopped;
@ -109,6 +106,11 @@ int CPUThread::ThreadStatus()
return CPUThread_Break;
}
if(m_is_step)
{
return CPUThread_Step;
}
if(Emu.IsPaused() || Sync())
{
return CPUThread_Sleeping;
@ -223,6 +225,7 @@ void CPUThread::Stop()
Reset();
DoStop();
Emu.CheckStatus();
delete m_dec;
wxGetApp().SendDbgCommand(DID_STOPED_THREAD, this);
}
@ -276,7 +279,7 @@ void CPUThread::Task()
continue;
}
DoCode();
m_dec->DecodeMemory(PC + m_offset);
NextPc();
if(status == CPUThread_Step)

View File

@ -41,6 +41,8 @@ protected:
u32 m_exit_status;
CPUDecoder* m_dec;
public:
virtual void InitRegs()=0;
@ -177,7 +179,6 @@ protected:
protected:
virtual void Task();
virtual void DoCode() = 0;
};
CPUThread* GetCurrentCPUThread();

View File

@ -0,0 +1,7 @@
#include "stdafx.h"
#include "PPCDecoder.h"
void PPCDecoder::DecodeMemory(const u64 address)
{
Decode(Memory.Read32(address));
}

View File

@ -2,15 +2,12 @@
#include "Emu/CPU/CPUDecoder.h"
#include "PPCInstrTable.h"
class PPCDecoder
class PPCDecoder : public CPUDecoder
{
protected:
u32 m_code;
public:
u32 GetCode() const { return m_code; }
virtual void Decode(const u32 code)=0;
virtual void DecodeMemory(const u64 address);
};

View File

@ -14,9 +14,7 @@ PPCThread* GetCurrentPPCThread()
return (PPCThread*)thread;
}
PPCThread::PPCThread(CPUThreadType type)
: CPUThread(type)
, m_dec(nullptr)
PPCThread::PPCThread(CPUThreadType type) : CPUThread(type)
{
}

View File

@ -6,7 +6,6 @@
class PPCThread : public CPUThread
{
protected:
PPCDecoder* m_dec;
u64 m_args[4];
Array<u64> m_argv_addr;

View File

@ -178,45 +178,6 @@ void PPUThread::DoStop()
bool dump_enable = false;
void PPUThread::DoCode()
{
const u32 code = Memory.Read32(m_offset + PC);
#ifdef _DEBUG
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;
}
#endif
if(++cycle > 220)
{
cycle = 0;
TB++;
}
m_dec->Decode(code);
}
bool FPRdouble::IsINF(PPCdouble d)
{
return ((u64&)d & 0x7FFFFFFFFFFFFFFFULL) == 0x7FF0000000000000ULL;

View File

@ -827,8 +827,6 @@ protected:
virtual void DoPause();
virtual void DoResume();
virtual void DoStop();
virtual void DoCode();
};
PPUThread& GetCurrentPPUThread();

View File

@ -311,7 +311,7 @@ void RawSPUThread::Task()
SPU.Status.SetValue(SPU_STATUS_RUNNING);
}
DoCode();
m_dec->DecodeMemory(PC + m_offset);
NextPc();
for(uint i=0; i<bp.GetCount(); ++i)

View File

@ -87,8 +87,3 @@ void SPUThread::DoStop()
delete m_dec;
m_dec = 0;
}
void SPUThread::DoCode()
{
m_dec->Decode(Memory.Read32(m_offset + PC));
}

View File

@ -364,9 +364,6 @@ protected:
virtual void DoPause();
virtual void DoResume();
virtual void DoStop();
protected:
virtual void DoCode();
};
SPUThread& GetCurrentSPUThread();

View File

@ -248,6 +248,86 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value)
return true;
}
bool MemoryBlockLE::Read8(const u64 addr, u8* value)
{
if(!IsMyAddress(addr)) return false;
*value = *(u8*)GetMem(FixAddr(addr));
return true;
}
bool MemoryBlockLE::Read16(const u64 addr, u16* value)
{
if(!IsMyAddress(addr)) return false;
*value = *(u16*)GetMem(FixAddr(addr));
return true;
}
bool MemoryBlockLE::Read32(const u64 addr, u32* value)
{
if(!IsMyAddress(addr)) return false;
*value = *(u32*)GetMem(FixAddr(addr));
return true;
}
bool MemoryBlockLE::Read64(const u64 addr, u64* value)
{
if(!IsMyAddress(addr)) return false;
*value = *(u64*)GetMem(FixAddr(addr));
return true;
}
bool MemoryBlockLE::Read128(const u64 addr, u128* value)
{
if(!IsMyAddress(addr)) return false;
*value = *(u128*)GetMem(FixAddr(addr));
return true;
}
bool MemoryBlockLE::Write8(const u64 addr, const u8 value)
{
if(!IsMyAddress(addr)) return false;
*(u8*)GetMem(FixAddr(addr)) = value;
return true;
}
bool MemoryBlockLE::Write16(const u64 addr, const u16 value)
{
if(!IsMyAddress(addr)) return false;
*(u16*)GetMem(FixAddr(addr)) = value;
return true;
}
bool MemoryBlockLE::Write32(const u64 addr, const u32 value)
{
if(!IsMyAddress(addr)) return false;
*(u32*)GetMem(FixAddr(addr)) = value;
return true;
}
bool MemoryBlockLE::Write64(const u64 addr, const u64 value)
{
if(!IsMyAddress(addr)) return false;
*(u64*)GetMem(FixAddr(addr)) = value;
return true;
}
bool MemoryBlockLE::Write128(const u64 addr, const u128 value)
{
if(!IsMyAddress(addr)) return false;
*(u128*)GetMem(FixAddr(addr)) = value;
return true;
}
//NullMemoryBlock
bool NullMemoryBlock::Read8(const u64 addr, u8* WXUNUSED(value))
{
@ -320,11 +400,13 @@ bool NullMemoryBlock::Write128(const u64 addr, const u128 value)
}
//DynamicMemoryBlock
DynamicMemoryBlock::DynamicMemoryBlock() : m_max_size(0)
template<typename PT>
DynamicMemoryBlockBase<PT>::DynamicMemoryBlockBase() : m_max_size(0)
{
}
const u32 DynamicMemoryBlock::GetUsedSize() const
template<typename PT>
const u32 DynamicMemoryBlockBase<PT>::GetUsedSize() const
{
u32 size = 0;
@ -336,17 +418,20 @@ const u32 DynamicMemoryBlock::GetUsedSize() const
return size;
}
bool DynamicMemoryBlock::IsInMyRange(const u64 addr)
template<typename PT>
bool DynamicMemoryBlockBase<PT>::IsInMyRange(const u64 addr)
{
return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize();
}
bool DynamicMemoryBlock::IsInMyRange(const u64 addr, const u32 size)
template<typename PT>
bool DynamicMemoryBlockBase<PT>::IsInMyRange(const u64 addr, const u32 size)
{
return IsInMyRange(addr) && IsInMyRange(addr + size - 1);
}
bool DynamicMemoryBlock::IsMyAddress(const u64 addr)
template<typename PT>
bool DynamicMemoryBlockBase<PT>::IsMyAddress(const u64 addr)
{
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
@ -359,7 +444,8 @@ bool DynamicMemoryBlock::IsMyAddress(const u64 addr)
return false;
}
MemoryBlock* DynamicMemoryBlock::SetRange(const u64 start, const u32 size)
template<typename PT>
MemoryBlock* DynamicMemoryBlockBase<PT>::SetRange(const u64 start, const u32 size)
{
m_max_size = size;
MemoryBlock::SetRange(start, 0);
@ -367,7 +453,8 @@ MemoryBlock* DynamicMemoryBlock::SetRange(const u64 start, const u32 size)
return this;
}
void DynamicMemoryBlock::Delete()
template<typename PT>
void DynamicMemoryBlockBase<PT>::Delete()
{
m_used_mem.Clear();
m_max_size = 0;
@ -375,7 +462,8 @@ void DynamicMemoryBlock::Delete()
MemoryBlock::Delete();
}
bool DynamicMemoryBlock::Alloc(u64 addr, u32 size)
template<typename PT>
bool DynamicMemoryBlockBase<PT>::Alloc(u64 addr, u32 size)
{
if(!IsInMyRange(addr, size))
{
@ -398,12 +486,14 @@ bool DynamicMemoryBlock::Alloc(u64 addr, u32 size)
return true;
}
void DynamicMemoryBlock::AppendUsedMem(u64 addr, u32 size)
template<typename PT>
void DynamicMemoryBlockBase<PT>::AppendUsedMem(u64 addr, u32 size)
{
m_used_mem.Move(new MemBlockInfo(addr, size));
}
u64 DynamicMemoryBlock::Alloc(u32 size)
template<typename PT>
u64 DynamicMemoryBlockBase<PT>::Alloc(u32 size)
{
for(u64 addr=GetStartAddr(); addr <= GetEndAddr() - size;)
{
@ -430,12 +520,14 @@ u64 DynamicMemoryBlock::Alloc(u32 size)
return 0;
}
bool DynamicMemoryBlock::Alloc()
template<typename PT>
bool DynamicMemoryBlockBase<PT>::Alloc()
{
return Alloc(GetSize() - GetUsedSize()) != 0;
}
bool DynamicMemoryBlock::Free(u64 addr)
template<typename PT>
bool DynamicMemoryBlockBase<PT>::Free(u64 addr)
{
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{
@ -449,7 +541,8 @@ bool DynamicMemoryBlock::Free(u64 addr)
return false;
}
u8* DynamicMemoryBlock::GetMem(u64 addr) const
template<typename PT>
u8* DynamicMemoryBlockBase<PT>::GetMem(u64 addr) const
{
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
{

View File

@ -4,7 +4,8 @@
enum MemoryType
{
Memory_PS3,
Memory_Vita,
Memory_PSV,
Memory_PSP,
};
class MemoryBase
@ -13,6 +14,7 @@ class MemoryBase
public:
ArrayF<MemoryBlock> MemoryBlocks;
MemoryBlock* UserMemory;
DynamicMemoryBlock MainMem;
DynamicMemoryBlock PRXMem;
@ -23,6 +25,21 @@ public:
MemoryBlock SpuRawMem;
MemoryBlock SpuThrMem;
struct
{
DynamicMemoryBlockLE RAM;
DynamicMemoryBlockLE Userspace;
} PSVMemory;
struct
{
DynamicMemoryBlockLE Scratchpad;
DynamicMemoryBlockLE VRAM;
DynamicMemoryBlockLE RAM;
DynamicMemoryBlockLE Kernel;
DynamicMemoryBlockLE Userspace;
} PSPMemory;
bool m_inited;
MemoryBase()
@ -143,7 +160,7 @@ public:
{
case Memory_PS3:
MemoryBlocks.Add(MainMem.SetRange(0x00010000, 0x2FFF0000));
MemoryBlocks.Add(PRXMem.SetRange(0x30000000, 0x10000000));
MemoryBlocks.Add(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000));
MemoryBlocks.Add(RSXCMDMem.SetRange(0x40000000, 0x10000000));
MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000));
MemoryBlocks.Add(RSXFBMem.SetRange(0xC0000000, 0x10000000));
@ -152,7 +169,17 @@ public:
//MemoryBlocks.Add(SpuThrMem.SetRange(0xF0000000, 0x10000000));
break;
case Memory_Vita:
case Memory_PSV:
MemoryBlocks.Add(PSVMemory.RAM.SetRange(0x81000000, 0x10000000));
MemoryBlocks.Add(UserMemory = PSVMemory.Userspace.SetRange(0x91000000, 0x10000000));
break;
case Memory_PSP:
MemoryBlocks.Add(PSPMemory.Scratchpad.SetRange(0x00010000, 0x00004000));
MemoryBlocks.Add(PSPMemory.VRAM.SetRange(0x04000000, 0x00200000));
MemoryBlocks.Add(PSPMemory.RAM.SetRange(0x08000000, 0x02000000));
MemoryBlocks.Add(PSPMemory.Kernel.SetRange(0x88000000, 0x00800000));
MemoryBlocks.Add(UserMemory = PSPMemory.Userspace.SetRange(0x08800000, 0x01800000));
break;
}
@ -315,22 +342,22 @@ public:
u32 GetUserMemTotalSize()
{
return PRXMem.GetSize();
return UserMemory->GetSize();
}
u32 GetUserMemAvailSize()
{
return PRXMem.GetSize() - PRXMem.GetUsedSize();
return UserMemory->GetSize() - UserMemory->GetUsedSize();
}
u64 Alloc(const u32 size, const u32 align)
{
return PRXMem.Alloc(AlignAddr(size, align));
return UserMemory->Alloc(AlignAddr(size, align));
}
bool Free(const u64 addr)
{
return PRXMem.Free(addr);
return UserMemory->Free(addr);
}
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
@ -353,7 +380,7 @@ public:
{
if(MemoryBlocks[i].GetStartAddr() == addr)
{
MemoryBlocks.RemoveFAt(i);
MemoryBlocks.RemoveAt(i);
}
}
}

View File

@ -98,8 +98,30 @@ public:
const u64 GetStartAddr() const { return range_start; }
const u64 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; }
virtual const u32 GetSize() const { return range_size; }
virtual const u32 GetUsedSize() const { return GetSize(); }
u8* GetMem() const { return mem; }
virtual u8* GetMem(u64 addr) const { return mem + addr; }
virtual bool Alloc(u64 addr, u32 size) { return false; }
virtual u64 Alloc(u32 size) { return 0; }
virtual bool Alloc() { return false; }
virtual bool Free(u64 addr) { return false; }
};
class MemoryBlockLE : public MemoryBlock
{
public:
virtual bool Read8(const u64 addr, u8* value) override;
virtual bool Read16(const u64 addr, u16* value) override;
virtual bool Read32(const u64 addr, u32* value) override;
virtual bool Read64(const u64 addr, u64* value) override;
virtual bool Read128(const u64 addr, u128* value) override;
virtual bool Write8(const u64 addr, const u8 value) override;
virtual bool Write16(const u64 addr, const u16 value) override;
virtual bool Write32(const u64 addr, const u32 value) override;
virtual bool Write64(const u64 addr, const u64 value) override;
virtual bool Write128(const u64 addr, const u128 value) override;
};
class MemoryMirror : public MemoryBlock
@ -145,32 +167,36 @@ class NullMemoryBlock : public MemoryBlock
virtual bool Write128(const u64 addr, const u128 value);
};
class DynamicMemoryBlock : public MemoryBlock
template<typename PT>
class DynamicMemoryBlockBase : public PT
{
Array<MemBlockInfo> m_used_mem;
u32 m_max_size;
public:
DynamicMemoryBlock();
DynamicMemoryBlockBase();
const u32 GetSize() const { return m_max_size; }
const u32 GetUsedSize() const;
bool IsInMyRange(const u64 addr);
bool IsInMyRange(const u64 addr, const u32 size);
bool IsMyAddress(const u64 addr);
virtual bool IsInMyRange(const u64 addr);
virtual bool IsInMyRange(const u64 addr, const u32 size);
virtual bool IsMyAddress(const u64 addr);
MemoryBlock* SetRange(const u64 start, const u32 size);
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
virtual void Delete();
bool Alloc(u64 addr, u32 size);
u64 Alloc(u32 size);
bool Alloc();
bool Free(u64 addr);
virtual bool Alloc(u64 addr, u32 size);
virtual u64 Alloc(u32 size);
virtual bool Alloc();
virtual bool Free(u64 addr);
virtual u8* GetMem(u64 addr) const;
private:
void AppendUsedMem(u64 addr, u32 size);
};
typedef DynamicMemoryBlockBase<MemoryBlock> DynamicMemoryBlock;
typedef DynamicMemoryBlockBase<MemoryBlockLE> DynamicMemoryBlockLE;

View File

@ -123,6 +123,14 @@ void Emulator::Load()
case MACHINE_PPC64:
Memory.Init(Memory_PS3);
break;
case MACHINE_MIPS:
Memory.Init(Memory_PSP);
break;
case MACHINE_ARM:
Memory.Init(Memory_PSV);
break;
}
is_error = !l.Load();
@ -148,6 +156,7 @@ void Emulator::Load()
{
case MACHINE_PPC64: thread_type = CPU_THREAD_PPU; break;
case MACHINE_SPU: thread_type = CPU_THREAD_SPU; break;
case MACHINE_ARM: thread_type = CPU_THREAD_ARM9; break;
default:
is_error = true;

View File

@ -2,21 +2,21 @@ class InstructionEditorDialog
: public wxDialog
{
u64 pc;
PPCDisAsm* disasm;
PPCDecoder* decoder;
CPUDisAsm* disasm;
CPUDecoder* decoder;
wxTextCtrl* t2_instr;
wxStaticText* t3_preview;
public:
PPCThread* CPU;
CPUThread* CPU;
public:
InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPCDecoder* _decoder, PPCDisAsm* _disasm);
InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm);
void updatePreview(wxCommandEvent& event);
};
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPCDecoder* _decoder, PPCDisAsm* _disasm)
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
, pc(_pc)
, CPU(_CPU)
@ -90,11 +90,18 @@ void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
unsigned long opcode;
if (t2_instr->GetValue().ToULong(&opcode, 16))
{
disasm->dump_pc = pc;
decoder->Decode((u32)opcode);
wxString preview = disasm->last_opcode;
preview.Remove(0, preview.Find(':') + 1);
t3_preview->SetLabel(preview);
if(CPU->GetType() == CPU_THREAD_ARM9)
{
t3_preview->SetLabel("Preview for ARM9Thread not implemented yet.");
}
else
{
disasm->dump_pc = pc;
((PPCDecoder*)decoder)->Decode((u32)opcode);
wxString preview = disasm->last_opcode;
preview.Remove(0, preview.Find(':') + 1);
t3_preview->SetLabel(preview);
}
}
else
{

View File

@ -1,5 +1,11 @@
#include "stdafx.h"
#include "InterpreterDisAsm.h"
#include "Emu/Cell/PPUDecoder.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/SPUDecoder.h"
#include "Emu/Cell/SPUDisAsm.h"
#include "Emu/ARM9/ARM9DisAsm.h"
#include "Emu/ARM9/ARM9Decoder.h"
#include "InstructionEditor.cpp"
#include "RegisterEditor.cpp"
@ -101,7 +107,7 @@ void InterpreterDisAsmFrame::UpdateUnitList()
void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
{
CPU = (PPCThread*)event.GetClientData();
CPU = (CPUThread*)event.GetClientData();
delete decoder;
//delete disasm;
@ -128,6 +134,14 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
disasm = &dis_asm;
}
break;
case CPU_THREAD_ARM9:
{
ARM9DisAsm& dis_asm = *new ARM9DisAsm(CPUDisAsm_InterpreterMode);
decoder = new ARM9Decoder(dis_asm);
disasm = &dis_asm;
}
break;
}
}
@ -228,7 +242,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
}
disasm->dump_pc = PC;
decoder->Decode(Memory.Read32(CPU->GetOffset() + PC));
decoder->DecodeMemory(CPU->GetOffset() + PC);
if(IsBreakPoint(PC))
{
@ -303,7 +317,7 @@ void InterpreterDisAsmFrame::WriteRegs()
void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
{
PPCThread* thr = (PPCThread*)event.GetClientData();
CPUThread* thr = (CPUThread*)event.GetClientData();
event.Skip();
if(!thr)

View File

@ -1,15 +1,13 @@
#pragma once
#include "Emu/Cell/PPCThread.h"
#include "Emu/Cell/PPUDecoder.h"
#include "Emu/Cell/PPUDisAsm.h"
#include "Emu/Cell/SPUDecoder.h"
#include "Emu/Cell/SPUDisAsm.h"
#include "Emu/CPU/CPUThread.h"
#include "Emu/CPU/CPUDecoder.h"
#include "Emu/CPU/CPUDisAsm.h"
class InterpreterDisAsmFrame : public wxPanel
{
wxListView* m_list;
PPCDisAsm* disasm;
PPCDecoder* decoder;
CPUDisAsm* disasm;
CPUDecoder* decoder;
u64 PC;
Array<u32> remove_markedPC;
wxTextCtrl* m_regs;
@ -21,7 +19,7 @@ class InterpreterDisAsmFrame : public wxPanel
wxChoice* m_choice_units;
public:
PPCThread* CPU;
CPUThread* CPU;
public:
InterpreterDisAsmFrame(wxWindow* parent);

View File

@ -1,23 +1,23 @@
class RegisterEditorDialog : public wxDialog
{
u64 pc;
PPCDisAsm* disasm;
PPCDecoder* decoder;
CPUDisAsm* disasm;
CPUDecoder* decoder;
wxComboBox* t1_register;
wxTextCtrl* t2_value;
wxStaticText* t3_preview;
public:
PPCThread* CPU;
CPUThread* CPU;
public:
RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPCDecoder* _decoder, PPCDisAsm* _disasm);
RegisterEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm);
void updateRegister(wxCommandEvent& event);
void updatePreview(wxCommandEvent& event);
};
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPCDecoder* _decoder, PPCDisAsm* _disasm)
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, CPUThread* _CPU, CPUDecoder* _decoder, CPUDisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit registers", wxDefaultPosition)
, pc(_pc)
, CPU(_CPU)
@ -82,6 +82,10 @@ RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread*
case CPU_THREAD_RAW_SPU:
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
break;
default:
wxMessageBox("Not supported thread.", "Error");
return;
}
SetSizerAndFit(s_panel_margin_x);

View File

@ -1,8 +1,6 @@
#include "stdafx.h"
#include "ELF32.h"
bool isLittleEndian;
ELF32Loader::ELF32Loader(vfsStream& f)
: elf32_f(f)
, LoaderBase()
@ -38,29 +36,26 @@ bool ELF32Loader::Close()
bool ELF32Loader::LoadEhdrInfo()
{
u8 endian;
elf32_f.Seek(5);
elf32_f.Read(&endian, 1);
isLittleEndian = (endian == 0x1);
elf32_f.Reset();
elf32_f.Seek(0);
if (isLittleEndian) ehdr.LoadLE(elf32_f);
else ehdr.Load(elf32_f);
ehdr.Load(elf32_f);
if(!ehdr.CheckMagic()) return false;
if(ehdr.IsLittleEndian())
ConLog.Warning("ELF32 LE");
switch(ehdr.e_machine)
{
case MACHINE_MIPS:
case MACHINE_PPC64:
case MACHINE_SPU:
case MACHINE_ARM:
machine = (Elf_Machine)ehdr.e_machine;
break;
default:
machine = MACHINE_Unknown;
ConLog.Error("Unknown elf32 type: 0x%x", ehdr.e_machine);
ConLog.Error("Unknown elf32 machine: 0x%x", ehdr.e_machine);
return false;
}
@ -86,11 +81,25 @@ bool ELF32Loader::LoadPhdrInfo()
for(uint i=0; i<ehdr.e_phnum; ++i)
{
Elf32_Phdr* phdr = new Elf32_Phdr();
if(isLittleEndian) phdr->LoadLE(elf32_f);
if(ehdr.IsLittleEndian()) phdr->LoadLE(elf32_f);
else phdr->Load(elf32_f);
phdr_arr.Move(phdr);
}
if(!Memory.IsGoodAddr(entry))
{
//entry is physical, convert to virtual
for(size_t i=0; i<phdr_arr.GetCount(); ++i)
{
if(phdr_arr[i].p_paddr >= entry && entry < phdr_arr[i].p_paddr + phdr_arr[i].p_memsz)
{
entry += phdr_arr[i].p_vaddr;
ConLog.Warning("virtual entry = 0x%x", entry);
break;
}
}
}
return true;
}
@ -100,7 +109,7 @@ bool ELF32Loader::LoadShdrInfo()
for(u32 i=0; i<ehdr.e_shnum; ++i)
{
Elf32_Shdr* shdr = new Elf32_Shdr();
if(isLittleEndian) shdr->LoadLE(elf32_f);
if(ehdr.IsLittleEndian()) shdr->LoadLE(elf32_f);
else shdr->Load(elf32_f);
shdr_arr.Move(shdr);
}
@ -138,8 +147,10 @@ bool ELF32Loader::LoadEhdrData(u64 offset)
return true;
}
bool ELF32Loader::LoadPhdrData(u64 offset)
bool ELF32Loader::LoadPhdrData(u64 _offset)
{
const u64 offset = machine == MACHINE_SPU ? _offset : 0;
for(u32 i=0; i<phdr_arr.GetCount(); ++i)
{
phdr_arr[i].Show();
@ -165,7 +176,16 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
);
}
Memory.MainMem.Alloc(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz);
switch(machine)
{
case MACHINE_SPU: Memory.MainMem.Alloc(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break;
case MACHINE_MIPS: Memory.PSPMemory.RAM.Alloc(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break;
case MACHINE_ARM: Memory.PSVMemory.RAM.Alloc(phdr_arr[i].p_vaddr + offset, phdr_arr[i].p_memsz); break;
default:
continue;
}
elf32_f.Seek(phdr_arr[i].p_offset);
elf32_f.Read(&Memory[phdr_arr[i].p_vaddr + offset], phdr_arr[i].p_filesz);
}
@ -173,7 +193,7 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
{
elf32_f.Seek(phdr_arr[i].p_offset);
Elf32_Note note;
if(isLittleEndian) note.LoadLE(elf32_f);
if(ehdr.IsLittleEndian()) note.LoadLE(elf32_f);
else note.Load(elf32_f);
if(note.type != 1)

View File

@ -48,6 +48,11 @@ struct Elf32_Ehdr
#endif
}
bool IsLittleEndian() const
{
return e_data == 1;
}
void Load(vfsStream& f)
{
e_magic = Read32(f);
@ -55,43 +60,41 @@ struct Elf32_Ehdr
e_data = Read8(f);
e_curver = Read8(f);
e_os_abi = Read8(f);
e_abi_ver = Read64(f);
e_type = Read16(f);
e_machine = Read16(f);
e_version = Read32(f);
e_entry = Read32(f);
e_phoff = Read32(f);
e_shoff = Read32(f);
e_flags = Read32(f);
e_ehsize = Read16(f);
e_phentsize = Read16(f);
e_phnum = Read16(f);
e_shentsize = Read16(f);
e_shnum = Read16(f);
e_shstrndx = Read16(f);
}
void LoadLE(vfsStream& f)
{
e_magic = Read32(f);
e_class = Read8(f);
e_data = Read8(f);
e_curver = Read8(f);
e_os_abi = Read8(f);
e_abi_ver = Read64LE(f);
e_type = Read16LE(f);
e_machine = Read16LE(f);
e_version = Read32LE(f);
e_entry = Read32LE(f);
e_phoff = Read32LE(f);
e_shoff = Read32LE(f);
e_flags = Read32LE(f);
e_ehsize = Read16LE(f);
e_phentsize = Read16LE(f);
e_phnum = Read16LE(f);
e_shentsize = Read16LE(f);
e_shnum = Read16LE(f);
e_shstrndx = Read16LE(f);
if(IsLittleEndian())
{
e_abi_ver = Read64LE(f);
e_type = Read16LE(f);
e_machine = Read16LE(f);
e_version = Read32LE(f);
e_entry = Read32LE(f);
e_phoff = Read32LE(f);
e_shoff = Read32LE(f);
e_flags = Read32LE(f);
e_ehsize = Read16LE(f);
e_phentsize = Read16LE(f);
e_phnum = Read16LE(f);
e_shentsize = Read16LE(f);
e_shnum = Read16LE(f);
e_shstrndx = Read16LE(f);
}
else
{
e_abi_ver = Read64(f);
e_type = Read16(f);
e_machine = Read16(f);
e_version = Read32(f);
e_entry = Read32(f);
e_phoff = Read32(f);
e_shoff = Read32(f);
e_flags = Read32(f);
e_ehsize = Read16(f);
e_phentsize = Read16(f);
e_phnum = Read16(f);
e_shentsize = Read16(f);
e_shnum = Read16(f);
e_shstrndx = Read16(f);
}
}
bool CheckMagic() const { return e_magic == 0x7F454C46; }

View File

@ -42,8 +42,9 @@ const wxString Ehdr_MachineToString(const u16 machine)
switch(machine)
{
case MACHINE_MIPS: return "MIPS";
case MACHINE_PPC64: return "PowerPC64";
case MACHINE_PPC64: return "PowerPC64";
case MACHINE_SPU: return "SPU";
case MACHINE_ARM: return "ARM";
};
return wxString::Format("Unknown (%x)", machine);

View File

@ -11,6 +11,7 @@ enum Elf_Machine
MACHINE_MIPS = 0x08,
MACHINE_PPC64 = 0x15,
MACHINE_SPU = 0x17,
MACHINE_ARM = 0x28,
};
enum ShdrType

View File

@ -203,6 +203,7 @@
<ClCompile Include="AppConnector.cpp" />
<ClCompile Include="Emu\ARM9\ARM9Thread.cpp" />
<ClCompile Include="Emu\Cell\MFC.cpp" />
<ClCompile Include="Emu\Cell\PPCDecoder.cpp" />
<ClCompile Include="Emu\Cell\PPCThread.cpp" />
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
<ClCompile Include="Emu\Cell\PPUThread.cpp" />

View File

@ -322,6 +322,9 @@
<ClCompile Include="Emu\ARM9\ARM9Thread.cpp">
<Filter>Emu\ARM9</Filter>
</ClCompile>
<ClCompile Include="Emu\Cell\PPCDecoder.cpp">
<Filter>Emu\Cell</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />