mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 20:22:30 +01:00
- Implemented ARM9Interpreter & ARM9DisAsm.
- Implemented MemoryBlockLE & DynamicMemoryBlockLE. - Implemented CPUDecoder.
This commit is contained in:
parent
0b35be32a4
commit
6b22e7d90a
32
rpcs3/Emu/ARM9/ARM9Decoder.h
Normal file
32
rpcs3/Emu/ARM9/ARM9Decoder.h
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
36
rpcs3/Emu/ARM9/ARM9DisAsm.h
Normal file
36
rpcs3/Emu/ARM9/ARM9DisAsm.h
Normal 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));
|
||||||
|
}
|
||||||
|
};
|
29
rpcs3/Emu/ARM9/ARM9Interpreter.h
Normal file
29
rpcs3/Emu/ARM9/ARM9Interpreter.h
Normal 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();
|
||||||
|
}
|
||||||
|
};
|
18
rpcs3/Emu/ARM9/ARM9Opcodes.h
Normal file
18
rpcs3/Emu/ARM9/ARM9Opcodes.h
Normal 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;
|
||||||
|
};
|
@ -1,5 +1,8 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ARM9Thread.h"
|
#include "ARM9Thread.h"
|
||||||
|
#include "ARM9Decoder.h"
|
||||||
|
#include "ARM9DisAsm.h"
|
||||||
|
#include "ARM9Interpreter.h"
|
||||||
|
|
||||||
ARM9Thread::ARM9Thread() : CPUThread(CPU_THREAD_ARM9)
|
ARM9Thread::ARM9Thread() : CPUThread(CPU_THREAD_ARM9)
|
||||||
{
|
{
|
||||||
@ -50,6 +53,17 @@ void ARM9Thread::DoReset()
|
|||||||
|
|
||||||
void ARM9Thread::DoRun()
|
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()
|
void ARM9Thread::DoPause()
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
#include "CPUInstrTable.h"
|
#include "CPUInstrTable.h"
|
||||||
#pragma warning( disable : 4800 )
|
#pragma warning( disable : 4800 )
|
||||||
|
|
||||||
|
class CPUDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void DecodeMemory(const u64 address)=0;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename TO>
|
template<typename TO>
|
||||||
class InstrCaller
|
class InstrCaller
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,8 @@ CPUThread::CPUThread(CPUThreadType type)
|
|||||||
, m_sync_wait(false)
|
, m_sync_wait(false)
|
||||||
, m_wait_thread_id(-1)
|
, m_wait_thread_id(-1)
|
||||||
, m_free_data(false)
|
, m_free_data(false)
|
||||||
|
, m_dec(nullptr)
|
||||||
|
, m_is_step(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,11 +96,6 @@ bool CPUThread::Sync()
|
|||||||
|
|
||||||
int CPUThread::ThreadStatus()
|
int CPUThread::ThreadStatus()
|
||||||
{
|
{
|
||||||
if(m_is_step)
|
|
||||||
{
|
|
||||||
return CPUThread_Step;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Emu.IsStopped())
|
if(Emu.IsStopped())
|
||||||
{
|
{
|
||||||
return CPUThread_Stopped;
|
return CPUThread_Stopped;
|
||||||
@ -109,6 +106,11 @@ int CPUThread::ThreadStatus()
|
|||||||
return CPUThread_Break;
|
return CPUThread_Break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_is_step)
|
||||||
|
{
|
||||||
|
return CPUThread_Step;
|
||||||
|
}
|
||||||
|
|
||||||
if(Emu.IsPaused() || Sync())
|
if(Emu.IsPaused() || Sync())
|
||||||
{
|
{
|
||||||
return CPUThread_Sleeping;
|
return CPUThread_Sleeping;
|
||||||
@ -223,6 +225,7 @@ void CPUThread::Stop()
|
|||||||
Reset();
|
Reset();
|
||||||
DoStop();
|
DoStop();
|
||||||
Emu.CheckStatus();
|
Emu.CheckStatus();
|
||||||
|
delete m_dec;
|
||||||
|
|
||||||
wxGetApp().SendDbgCommand(DID_STOPED_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_STOPED_THREAD, this);
|
||||||
}
|
}
|
||||||
@ -276,7 +279,7 @@ void CPUThread::Task()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoCode();
|
m_dec->DecodeMemory(PC + m_offset);
|
||||||
NextPc();
|
NextPc();
|
||||||
|
|
||||||
if(status == CPUThread_Step)
|
if(status == CPUThread_Step)
|
||||||
|
@ -41,6 +41,8 @@ protected:
|
|||||||
|
|
||||||
u32 m_exit_status;
|
u32 m_exit_status;
|
||||||
|
|
||||||
|
CPUDecoder* m_dec;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void InitRegs()=0;
|
virtual void InitRegs()=0;
|
||||||
|
|
||||||
@ -177,7 +179,6 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Task();
|
virtual void Task();
|
||||||
virtual void DoCode() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CPUThread* GetCurrentCPUThread();
|
CPUThread* GetCurrentCPUThread();
|
7
rpcs3/Emu/Cell/PPCDecoder.cpp
Normal file
7
rpcs3/Emu/Cell/PPCDecoder.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "PPCDecoder.h"
|
||||||
|
|
||||||
|
void PPCDecoder::DecodeMemory(const u64 address)
|
||||||
|
{
|
||||||
|
Decode(Memory.Read32(address));
|
||||||
|
}
|
@ -2,15 +2,12 @@
|
|||||||
#include "Emu/CPU/CPUDecoder.h"
|
#include "Emu/CPU/CPUDecoder.h"
|
||||||
#include "PPCInstrTable.h"
|
#include "PPCInstrTable.h"
|
||||||
|
|
||||||
class PPCDecoder
|
class PPCDecoder : public CPUDecoder
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
u32 m_code;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
u32 GetCode() const { return m_code; }
|
|
||||||
|
|
||||||
virtual void Decode(const u32 code)=0;
|
virtual void Decode(const u32 code)=0;
|
||||||
|
|
||||||
|
virtual void DecodeMemory(const u64 address);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,9 +14,7 @@ PPCThread* GetCurrentPPCThread()
|
|||||||
return (PPCThread*)thread;
|
return (PPCThread*)thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCThread::PPCThread(CPUThreadType type)
|
PPCThread::PPCThread(CPUThreadType type) : CPUThread(type)
|
||||||
: CPUThread(type)
|
|
||||||
, m_dec(nullptr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
class PPCThread : public CPUThread
|
class PPCThread : public CPUThread
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
PPCDecoder* m_dec;
|
|
||||||
u64 m_args[4];
|
u64 m_args[4];
|
||||||
Array<u64> m_argv_addr;
|
Array<u64> m_argv_addr;
|
||||||
|
|
||||||
|
@ -178,45 +178,6 @@ void PPUThread::DoStop()
|
|||||||
|
|
||||||
bool dump_enable = false;
|
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)
|
bool FPRdouble::IsINF(PPCdouble d)
|
||||||
{
|
{
|
||||||
return ((u64&)d & 0x7FFFFFFFFFFFFFFFULL) == 0x7FF0000000000000ULL;
|
return ((u64&)d & 0x7FFFFFFFFFFFFFFFULL) == 0x7FF0000000000000ULL;
|
||||||
|
@ -827,8 +827,6 @@ protected:
|
|||||||
virtual void DoPause();
|
virtual void DoPause();
|
||||||
virtual void DoResume();
|
virtual void DoResume();
|
||||||
virtual void DoStop();
|
virtual void DoStop();
|
||||||
|
|
||||||
virtual void DoCode();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PPUThread& GetCurrentPPUThread();
|
PPUThread& GetCurrentPPUThread();
|
@ -311,7 +311,7 @@ void RawSPUThread::Task()
|
|||||||
SPU.Status.SetValue(SPU_STATUS_RUNNING);
|
SPU.Status.SetValue(SPU_STATUS_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoCode();
|
m_dec->DecodeMemory(PC + m_offset);
|
||||||
NextPc();
|
NextPc();
|
||||||
|
|
||||||
for(uint i=0; i<bp.GetCount(); ++i)
|
for(uint i=0; i<bp.GetCount(); ++i)
|
||||||
|
@ -87,8 +87,3 @@ void SPUThread::DoStop()
|
|||||||
delete m_dec;
|
delete m_dec;
|
||||||
m_dec = 0;
|
m_dec = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPUThread::DoCode()
|
|
||||||
{
|
|
||||||
m_dec->Decode(Memory.Read32(m_offset + PC));
|
|
||||||
}
|
|
||||||
|
@ -364,9 +364,6 @@ protected:
|
|||||||
virtual void DoPause();
|
virtual void DoPause();
|
||||||
virtual void DoResume();
|
virtual void DoResume();
|
||||||
virtual void DoStop();
|
virtual void DoStop();
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void DoCode();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SPUThread& GetCurrentSPUThread();
|
SPUThread& GetCurrentSPUThread();
|
@ -248,6 +248,86 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value)
|
|||||||
return true;
|
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
|
//NullMemoryBlock
|
||||||
bool NullMemoryBlock::Read8(const u64 addr, u8* WXUNUSED(value))
|
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::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;
|
u32 size = 0;
|
||||||
|
|
||||||
@ -336,17 +418,20 @@ const u32 DynamicMemoryBlock::GetUsedSize() const
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicMemoryBlock::IsInMyRange(const u64 addr)
|
template<typename PT>
|
||||||
|
bool DynamicMemoryBlockBase<PT>::IsInMyRange(const u64 addr)
|
||||||
{
|
{
|
||||||
return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize();
|
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);
|
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)
|
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
@ -359,7 +444,8 @@ bool DynamicMemoryBlock::IsMyAddress(const u64 addr)
|
|||||||
return false;
|
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;
|
m_max_size = size;
|
||||||
MemoryBlock::SetRange(start, 0);
|
MemoryBlock::SetRange(start, 0);
|
||||||
@ -367,7 +453,8 @@ MemoryBlock* DynamicMemoryBlock::SetRange(const u64 start, const u32 size)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicMemoryBlock::Delete()
|
template<typename PT>
|
||||||
|
void DynamicMemoryBlockBase<PT>::Delete()
|
||||||
{
|
{
|
||||||
m_used_mem.Clear();
|
m_used_mem.Clear();
|
||||||
m_max_size = 0;
|
m_max_size = 0;
|
||||||
@ -375,7 +462,8 @@ void DynamicMemoryBlock::Delete()
|
|||||||
MemoryBlock::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))
|
if(!IsInMyRange(addr, size))
|
||||||
{
|
{
|
||||||
@ -398,12 +486,14 @@ bool DynamicMemoryBlock::Alloc(u64 addr, u32 size)
|
|||||||
return true;
|
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));
|
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;)
|
for(u64 addr=GetStartAddr(); addr <= GetEndAddr() - size;)
|
||||||
{
|
{
|
||||||
@ -430,12 +520,14 @@ u64 DynamicMemoryBlock::Alloc(u32 size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicMemoryBlock::Alloc()
|
template<typename PT>
|
||||||
|
bool DynamicMemoryBlockBase<PT>::Alloc()
|
||||||
{
|
{
|
||||||
return Alloc(GetSize() - GetUsedSize()) != 0;
|
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)
|
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
@ -449,7 +541,8 @@ bool DynamicMemoryBlock::Free(u64 addr)
|
|||||||
return false;
|
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)
|
for(u32 i=0; i<m_used_mem.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
enum MemoryType
|
enum MemoryType
|
||||||
{
|
{
|
||||||
Memory_PS3,
|
Memory_PS3,
|
||||||
Memory_Vita,
|
Memory_PSV,
|
||||||
|
Memory_PSP,
|
||||||
};
|
};
|
||||||
|
|
||||||
class MemoryBase
|
class MemoryBase
|
||||||
@ -13,6 +14,7 @@ class MemoryBase
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ArrayF<MemoryBlock> MemoryBlocks;
|
ArrayF<MemoryBlock> MemoryBlocks;
|
||||||
|
MemoryBlock* UserMemory;
|
||||||
|
|
||||||
DynamicMemoryBlock MainMem;
|
DynamicMemoryBlock MainMem;
|
||||||
DynamicMemoryBlock PRXMem;
|
DynamicMemoryBlock PRXMem;
|
||||||
@ -23,6 +25,21 @@ public:
|
|||||||
MemoryBlock SpuRawMem;
|
MemoryBlock SpuRawMem;
|
||||||
MemoryBlock SpuThrMem;
|
MemoryBlock SpuThrMem;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
DynamicMemoryBlockLE RAM;
|
||||||
|
DynamicMemoryBlockLE Userspace;
|
||||||
|
} PSVMemory;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
DynamicMemoryBlockLE Scratchpad;
|
||||||
|
DynamicMemoryBlockLE VRAM;
|
||||||
|
DynamicMemoryBlockLE RAM;
|
||||||
|
DynamicMemoryBlockLE Kernel;
|
||||||
|
DynamicMemoryBlockLE Userspace;
|
||||||
|
} PSPMemory;
|
||||||
|
|
||||||
bool m_inited;
|
bool m_inited;
|
||||||
|
|
||||||
MemoryBase()
|
MemoryBase()
|
||||||
@ -143,7 +160,7 @@ public:
|
|||||||
{
|
{
|
||||||
case Memory_PS3:
|
case Memory_PS3:
|
||||||
MemoryBlocks.Add(MainMem.SetRange(0x00010000, 0x2FFF0000));
|
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(RSXCMDMem.SetRange(0x40000000, 0x10000000));
|
||||||
MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000));
|
MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000));
|
||||||
MemoryBlocks.Add(RSXFBMem.SetRange(0xC0000000, 0x10000000));
|
MemoryBlocks.Add(RSXFBMem.SetRange(0xC0000000, 0x10000000));
|
||||||
@ -152,7 +169,17 @@ public:
|
|||||||
//MemoryBlocks.Add(SpuThrMem.SetRange(0xF0000000, 0x10000000));
|
//MemoryBlocks.Add(SpuThrMem.SetRange(0xF0000000, 0x10000000));
|
||||||
break;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,22 +342,22 @@ public:
|
|||||||
|
|
||||||
u32 GetUserMemTotalSize()
|
u32 GetUserMemTotalSize()
|
||||||
{
|
{
|
||||||
return PRXMem.GetSize();
|
return UserMemory->GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetUserMemAvailSize()
|
u32 GetUserMemAvailSize()
|
||||||
{
|
{
|
||||||
return PRXMem.GetSize() - PRXMem.GetUsedSize();
|
return UserMemory->GetSize() - UserMemory->GetUsedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 Alloc(const u32 size, const u32 align)
|
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)
|
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)
|
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
|
||||||
@ -353,7 +380,7 @@ public:
|
|||||||
{
|
{
|
||||||
if(MemoryBlocks[i].GetStartAddr() == addr)
|
if(MemoryBlocks[i].GetStartAddr() == addr)
|
||||||
{
|
{
|
||||||
MemoryBlocks.RemoveFAt(i);
|
MemoryBlocks.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,30 @@ public:
|
|||||||
const u64 GetStartAddr() const { return range_start; }
|
const u64 GetStartAddr() const { return range_start; }
|
||||||
const u64 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; }
|
const u64 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; }
|
||||||
virtual const u32 GetSize() const { return range_size; }
|
virtual const u32 GetSize() const { return range_size; }
|
||||||
|
virtual const u32 GetUsedSize() const { return GetSize(); }
|
||||||
u8* GetMem() const { return mem; }
|
u8* GetMem() const { return mem; }
|
||||||
virtual u8* GetMem(u64 addr) const { return mem + addr; }
|
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
|
class MemoryMirror : public MemoryBlock
|
||||||
@ -145,32 +167,36 @@ class NullMemoryBlock : public MemoryBlock
|
|||||||
virtual bool Write128(const u64 addr, const u128 value);
|
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;
|
Array<MemBlockInfo> m_used_mem;
|
||||||
u32 m_max_size;
|
u32 m_max_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DynamicMemoryBlock();
|
DynamicMemoryBlockBase();
|
||||||
|
|
||||||
const u32 GetSize() const { return m_max_size; }
|
const u32 GetSize() const { return m_max_size; }
|
||||||
const u32 GetUsedSize() const;
|
const u32 GetUsedSize() const;
|
||||||
|
|
||||||
bool IsInMyRange(const u64 addr);
|
virtual bool IsInMyRange(const u64 addr);
|
||||||
bool IsInMyRange(const u64 addr, const u32 size);
|
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
||||||
bool IsMyAddress(const u64 addr);
|
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();
|
virtual void Delete();
|
||||||
|
|
||||||
bool Alloc(u64 addr, u32 size);
|
virtual bool Alloc(u64 addr, u32 size);
|
||||||
u64 Alloc(u32 size);
|
virtual u64 Alloc(u32 size);
|
||||||
bool Alloc();
|
virtual bool Alloc();
|
||||||
bool Free(u64 addr);
|
virtual bool Free(u64 addr);
|
||||||
|
|
||||||
virtual u8* GetMem(u64 addr) const;
|
virtual u8* GetMem(u64 addr) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AppendUsedMem(u64 addr, u32 size);
|
void AppendUsedMem(u64 addr, u32 size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef DynamicMemoryBlockBase<MemoryBlock> DynamicMemoryBlock;
|
||||||
|
typedef DynamicMemoryBlockBase<MemoryBlockLE> DynamicMemoryBlockLE;
|
||||||
|
@ -123,6 +123,14 @@ void Emulator::Load()
|
|||||||
case MACHINE_PPC64:
|
case MACHINE_PPC64:
|
||||||
Memory.Init(Memory_PS3);
|
Memory.Init(Memory_PS3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MACHINE_MIPS:
|
||||||
|
Memory.Init(Memory_PSP);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MACHINE_ARM:
|
||||||
|
Memory.Init(Memory_PSV);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_error = !l.Load();
|
is_error = !l.Load();
|
||||||
@ -148,6 +156,7 @@ void Emulator::Load()
|
|||||||
{
|
{
|
||||||
case MACHINE_PPC64: thread_type = CPU_THREAD_PPU; break;
|
case MACHINE_PPC64: thread_type = CPU_THREAD_PPU; break;
|
||||||
case MACHINE_SPU: thread_type = CPU_THREAD_SPU; break;
|
case MACHINE_SPU: thread_type = CPU_THREAD_SPU; break;
|
||||||
|
case MACHINE_ARM: thread_type = CPU_THREAD_ARM9; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
is_error = true;
|
is_error = true;
|
||||||
|
@ -2,21 +2,21 @@ class InstructionEditorDialog
|
|||||||
: public wxDialog
|
: public wxDialog
|
||||||
{
|
{
|
||||||
u64 pc;
|
u64 pc;
|
||||||
PPCDisAsm* disasm;
|
CPUDisAsm* disasm;
|
||||||
PPCDecoder* decoder;
|
CPUDecoder* decoder;
|
||||||
wxTextCtrl* t2_instr;
|
wxTextCtrl* t2_instr;
|
||||||
wxStaticText* t3_preview;
|
wxStaticText* t3_preview;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPCThread* CPU;
|
CPUThread* CPU;
|
||||||
|
|
||||||
public:
|
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);
|
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)
|
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
|
||||||
, pc(_pc)
|
, pc(_pc)
|
||||||
, CPU(_CPU)
|
, CPU(_CPU)
|
||||||
@ -90,11 +90,18 @@ void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
|
|||||||
unsigned long opcode;
|
unsigned long opcode;
|
||||||
if (t2_instr->GetValue().ToULong(&opcode, 16))
|
if (t2_instr->GetValue().ToULong(&opcode, 16))
|
||||||
{
|
{
|
||||||
disasm->dump_pc = pc;
|
if(CPU->GetType() == CPU_THREAD_ARM9)
|
||||||
decoder->Decode((u32)opcode);
|
{
|
||||||
wxString preview = disasm->last_opcode;
|
t3_preview->SetLabel("Preview for ARM9Thread not implemented yet.");
|
||||||
preview.Remove(0, preview.Find(':') + 1);
|
}
|
||||||
t3_preview->SetLabel(preview);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "InterpreterDisAsm.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 "InstructionEditor.cpp"
|
||||||
#include "RegisterEditor.cpp"
|
#include "RegisterEditor.cpp"
|
||||||
@ -101,7 +107,7 @@ void InterpreterDisAsmFrame::UpdateUnitList()
|
|||||||
|
|
||||||
void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
|
void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
CPU = (PPCThread*)event.GetClientData();
|
CPU = (CPUThread*)event.GetClientData();
|
||||||
|
|
||||||
delete decoder;
|
delete decoder;
|
||||||
//delete disasm;
|
//delete disasm;
|
||||||
@ -128,6 +134,14 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
|
|||||||
disasm = &dis_asm;
|
disasm = &dis_asm;
|
||||||
}
|
}
|
||||||
break;
|
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;
|
disasm->dump_pc = PC;
|
||||||
decoder->Decode(Memory.Read32(CPU->GetOffset() + PC));
|
decoder->DecodeMemory(CPU->GetOffset() + PC);
|
||||||
|
|
||||||
if(IsBreakPoint(PC))
|
if(IsBreakPoint(PC))
|
||||||
{
|
{
|
||||||
@ -303,7 +317,7 @@ void InterpreterDisAsmFrame::WriteRegs()
|
|||||||
|
|
||||||
void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
|
void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
PPCThread* thr = (PPCThread*)event.GetClientData();
|
CPUThread* thr = (CPUThread*)event.GetClientData();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
|
||||||
if(!thr)
|
if(!thr)
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Emu/Cell/PPCThread.h"
|
#include "Emu/CPU/CPUThread.h"
|
||||||
#include "Emu/Cell/PPUDecoder.h"
|
#include "Emu/CPU/CPUDecoder.h"
|
||||||
#include "Emu/Cell/PPUDisAsm.h"
|
#include "Emu/CPU/CPUDisAsm.h"
|
||||||
#include "Emu/Cell/SPUDecoder.h"
|
|
||||||
#include "Emu/Cell/SPUDisAsm.h"
|
|
||||||
|
|
||||||
class InterpreterDisAsmFrame : public wxPanel
|
class InterpreterDisAsmFrame : public wxPanel
|
||||||
{
|
{
|
||||||
wxListView* m_list;
|
wxListView* m_list;
|
||||||
PPCDisAsm* disasm;
|
CPUDisAsm* disasm;
|
||||||
PPCDecoder* decoder;
|
CPUDecoder* decoder;
|
||||||
u64 PC;
|
u64 PC;
|
||||||
Array<u32> remove_markedPC;
|
Array<u32> remove_markedPC;
|
||||||
wxTextCtrl* m_regs;
|
wxTextCtrl* m_regs;
|
||||||
@ -21,7 +19,7 @@ class InterpreterDisAsmFrame : public wxPanel
|
|||||||
wxChoice* m_choice_units;
|
wxChoice* m_choice_units;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPCThread* CPU;
|
CPUThread* CPU;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InterpreterDisAsmFrame(wxWindow* parent);
|
InterpreterDisAsmFrame(wxWindow* parent);
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
class RegisterEditorDialog : public wxDialog
|
class RegisterEditorDialog : public wxDialog
|
||||||
{
|
{
|
||||||
u64 pc;
|
u64 pc;
|
||||||
PPCDisAsm* disasm;
|
CPUDisAsm* disasm;
|
||||||
PPCDecoder* decoder;
|
CPUDecoder* decoder;
|
||||||
wxComboBox* t1_register;
|
wxComboBox* t1_register;
|
||||||
wxTextCtrl* t2_value;
|
wxTextCtrl* t2_value;
|
||||||
wxStaticText* t3_preview;
|
wxStaticText* t3_preview;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PPCThread* CPU;
|
CPUThread* CPU;
|
||||||
|
|
||||||
public:
|
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 updateRegister(wxCommandEvent& event);
|
||||||
void updatePreview(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)
|
: wxDialog(parent, wxID_ANY, "Edit registers", wxDefaultPosition)
|
||||||
, pc(_pc)
|
, pc(_pc)
|
||||||
, CPU(_CPU)
|
, CPU(_CPU)
|
||||||
@ -82,6 +82,10 @@ RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread*
|
|||||||
case CPU_THREAD_RAW_SPU:
|
case CPU_THREAD_RAW_SPU:
|
||||||
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxMessageBox("Not supported thread.", "Error");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSizerAndFit(s_panel_margin_x);
|
SetSizerAndFit(s_panel_margin_x);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "ELF32.h"
|
#include "ELF32.h"
|
||||||
|
|
||||||
bool isLittleEndian;
|
|
||||||
|
|
||||||
ELF32Loader::ELF32Loader(vfsStream& f)
|
ELF32Loader::ELF32Loader(vfsStream& f)
|
||||||
: elf32_f(f)
|
: elf32_f(f)
|
||||||
, LoaderBase()
|
, LoaderBase()
|
||||||
@ -38,29 +36,26 @@ bool ELF32Loader::Close()
|
|||||||
|
|
||||||
bool ELF32Loader::LoadEhdrInfo()
|
bool ELF32Loader::LoadEhdrInfo()
|
||||||
{
|
{
|
||||||
u8 endian;
|
|
||||||
elf32_f.Seek(5);
|
|
||||||
elf32_f.Read(&endian, 1);
|
|
||||||
isLittleEndian = (endian == 0x1);
|
|
||||||
|
|
||||||
elf32_f.Reset();
|
|
||||||
elf32_f.Seek(0);
|
elf32_f.Seek(0);
|
||||||
if (isLittleEndian) ehdr.LoadLE(elf32_f);
|
ehdr.Load(elf32_f);
|
||||||
else ehdr.Load(elf32_f);
|
|
||||||
|
|
||||||
if(!ehdr.CheckMagic()) return false;
|
if(!ehdr.CheckMagic()) return false;
|
||||||
|
|
||||||
|
if(ehdr.IsLittleEndian())
|
||||||
|
ConLog.Warning("ELF32 LE");
|
||||||
|
|
||||||
switch(ehdr.e_machine)
|
switch(ehdr.e_machine)
|
||||||
{
|
{
|
||||||
case MACHINE_MIPS:
|
case MACHINE_MIPS:
|
||||||
case MACHINE_PPC64:
|
case MACHINE_PPC64:
|
||||||
case MACHINE_SPU:
|
case MACHINE_SPU:
|
||||||
|
case MACHINE_ARM:
|
||||||
machine = (Elf_Machine)ehdr.e_machine;
|
machine = (Elf_Machine)ehdr.e_machine;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
machine = MACHINE_Unknown;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,11 +81,25 @@ bool ELF32Loader::LoadPhdrInfo()
|
|||||||
for(uint i=0; i<ehdr.e_phnum; ++i)
|
for(uint i=0; i<ehdr.e_phnum; ++i)
|
||||||
{
|
{
|
||||||
Elf32_Phdr* phdr = new Elf32_Phdr();
|
Elf32_Phdr* phdr = new Elf32_Phdr();
|
||||||
if(isLittleEndian) phdr->LoadLE(elf32_f);
|
if(ehdr.IsLittleEndian()) phdr->LoadLE(elf32_f);
|
||||||
else phdr->Load(elf32_f);
|
else phdr->Load(elf32_f);
|
||||||
phdr_arr.Move(phdr);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +109,7 @@ bool ELF32Loader::LoadShdrInfo()
|
|||||||
for(u32 i=0; i<ehdr.e_shnum; ++i)
|
for(u32 i=0; i<ehdr.e_shnum; ++i)
|
||||||
{
|
{
|
||||||
Elf32_Shdr* shdr = new Elf32_Shdr();
|
Elf32_Shdr* shdr = new Elf32_Shdr();
|
||||||
if(isLittleEndian) shdr->LoadLE(elf32_f);
|
if(ehdr.IsLittleEndian()) shdr->LoadLE(elf32_f);
|
||||||
else shdr->Load(elf32_f);
|
else shdr->Load(elf32_f);
|
||||||
shdr_arr.Move(shdr);
|
shdr_arr.Move(shdr);
|
||||||
}
|
}
|
||||||
@ -138,8 +147,10 @@ bool ELF32Loader::LoadEhdrData(u64 offset)
|
|||||||
return true;
|
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)
|
for(u32 i=0; i<phdr_arr.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
phdr_arr[i].Show();
|
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.Seek(phdr_arr[i].p_offset);
|
||||||
elf32_f.Read(&Memory[phdr_arr[i].p_vaddr + offset], phdr_arr[i].p_filesz);
|
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_f.Seek(phdr_arr[i].p_offset);
|
||||||
Elf32_Note note;
|
Elf32_Note note;
|
||||||
if(isLittleEndian) note.LoadLE(elf32_f);
|
if(ehdr.IsLittleEndian()) note.LoadLE(elf32_f);
|
||||||
else note.Load(elf32_f);
|
else note.Load(elf32_f);
|
||||||
|
|
||||||
if(note.type != 1)
|
if(note.type != 1)
|
||||||
|
@ -48,6 +48,11 @@ struct Elf32_Ehdr
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsLittleEndian() const
|
||||||
|
{
|
||||||
|
return e_data == 1;
|
||||||
|
}
|
||||||
|
|
||||||
void Load(vfsStream& f)
|
void Load(vfsStream& f)
|
||||||
{
|
{
|
||||||
e_magic = Read32(f);
|
e_magic = Read32(f);
|
||||||
@ -55,43 +60,41 @@ struct Elf32_Ehdr
|
|||||||
e_data = Read8(f);
|
e_data = Read8(f);
|
||||||
e_curver = Read8(f);
|
e_curver = Read8(f);
|
||||||
e_os_abi = 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)
|
if(IsLittleEndian())
|
||||||
{
|
{
|
||||||
e_magic = Read32(f);
|
e_abi_ver = Read64LE(f);
|
||||||
e_class = Read8(f);
|
e_type = Read16LE(f);
|
||||||
e_data = Read8(f);
|
e_machine = Read16LE(f);
|
||||||
e_curver = Read8(f);
|
e_version = Read32LE(f);
|
||||||
e_os_abi = Read8(f);
|
e_entry = Read32LE(f);
|
||||||
e_abi_ver = Read64LE(f);
|
e_phoff = Read32LE(f);
|
||||||
e_type = Read16LE(f);
|
e_shoff = Read32LE(f);
|
||||||
e_machine = Read16LE(f);
|
e_flags = Read32LE(f);
|
||||||
e_version = Read32LE(f);
|
e_ehsize = Read16LE(f);
|
||||||
e_entry = Read32LE(f);
|
e_phentsize = Read16LE(f);
|
||||||
e_phoff = Read32LE(f);
|
e_phnum = Read16LE(f);
|
||||||
e_shoff = Read32LE(f);
|
e_shentsize = Read16LE(f);
|
||||||
e_flags = Read32LE(f);
|
e_shnum = Read16LE(f);
|
||||||
e_ehsize = Read16LE(f);
|
e_shstrndx = Read16LE(f);
|
||||||
e_phentsize = Read16LE(f);
|
}
|
||||||
e_phnum = Read16LE(f);
|
else
|
||||||
e_shentsize = Read16LE(f);
|
{
|
||||||
e_shnum = Read16LE(f);
|
e_abi_ver = Read64(f);
|
||||||
e_shstrndx = Read16LE(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; }
|
bool CheckMagic() const { return e_magic == 0x7F454C46; }
|
||||||
|
@ -42,8 +42,9 @@ const wxString Ehdr_MachineToString(const u16 machine)
|
|||||||
switch(machine)
|
switch(machine)
|
||||||
{
|
{
|
||||||
case MACHINE_MIPS: return "MIPS";
|
case MACHINE_MIPS: return "MIPS";
|
||||||
case MACHINE_PPC64: return "PowerPC64";
|
case MACHINE_PPC64: return "PowerPC64";
|
||||||
case MACHINE_SPU: return "SPU";
|
case MACHINE_SPU: return "SPU";
|
||||||
|
case MACHINE_ARM: return "ARM";
|
||||||
};
|
};
|
||||||
|
|
||||||
return wxString::Format("Unknown (%x)", machine);
|
return wxString::Format("Unknown (%x)", machine);
|
||||||
|
@ -11,6 +11,7 @@ enum Elf_Machine
|
|||||||
MACHINE_MIPS = 0x08,
|
MACHINE_MIPS = 0x08,
|
||||||
MACHINE_PPC64 = 0x15,
|
MACHINE_PPC64 = 0x15,
|
||||||
MACHINE_SPU = 0x17,
|
MACHINE_SPU = 0x17,
|
||||||
|
MACHINE_ARM = 0x28,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ShdrType
|
enum ShdrType
|
||||||
|
@ -203,6 +203,7 @@
|
|||||||
<ClCompile Include="AppConnector.cpp" />
|
<ClCompile Include="AppConnector.cpp" />
|
||||||
<ClCompile Include="Emu\ARM9\ARM9Thread.cpp" />
|
<ClCompile Include="Emu\ARM9\ARM9Thread.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\MFC.cpp" />
|
<ClCompile Include="Emu\Cell\MFC.cpp" />
|
||||||
|
<ClCompile Include="Emu\Cell\PPCDecoder.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\PPCThread.cpp" />
|
<ClCompile Include="Emu\Cell\PPCThread.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
|
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\PPUThread.cpp" />
|
<ClCompile Include="Emu\Cell\PPUThread.cpp" />
|
||||||
|
@ -322,6 +322,9 @@
|
|||||||
<ClCompile Include="Emu\ARM9\ARM9Thread.cpp">
|
<ClCompile Include="Emu\ARM9\ARM9Thread.cpp">
|
||||||
<Filter>Emu\ARM9</Filter>
|
<Filter>Emu\ARM9</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Emu\Cell\PPCDecoder.cpp">
|
||||||
|
<Filter>Emu\Cell</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
|
Loading…
Reference in New Issue
Block a user