From 6b22e7d90aeb96ccdedb10337101a10f6e5e97f0 Mon Sep 17 00:00:00 2001 From: DH Date: Tue, 5 Nov 2013 20:12:18 +0200 Subject: [PATCH] - Implemented ARM9Interpreter & ARM9DisAsm. - Implemented MemoryBlockLE & DynamicMemoryBlockLE. - Implemented CPUDecoder. --- rpcs3/Emu/ARM9/ARM9Decoder.h | 32 +++++++++ rpcs3/Emu/ARM9/ARM9DisAsm.h | 36 ++++++++++ rpcs3/Emu/ARM9/ARM9Interpreter.h | 29 ++++++++ rpcs3/Emu/ARM9/ARM9Opcodes.h | 18 +++++ rpcs3/Emu/ARM9/ARM9Thread.cpp | 14 ++++ rpcs3/Emu/CPU/CPUDecoder.h | 6 ++ rpcs3/Emu/CPU/CPUThread.cpp | 15 ++-- rpcs3/Emu/CPU/CPUThread.h | 3 +- rpcs3/Emu/Cell/PPCDecoder.cpp | 7 ++ rpcs3/Emu/Cell/PPCDecoder.h | 9 +-- rpcs3/Emu/Cell/PPCThread.cpp | 4 +- rpcs3/Emu/Cell/PPCThread.h | 1 - rpcs3/Emu/Cell/PPUThread.cpp | 39 ---------- rpcs3/Emu/Cell/PPUThread.h | 2 - rpcs3/Emu/Cell/RawSPUThread.cpp | 2 +- rpcs3/Emu/Cell/SPUThread.cpp | 5 -- rpcs3/Emu/Cell/SPUThread.h | 3 - rpcs3/Emu/Memory/Memory.cpp | 119 +++++++++++++++++++++++++++---- rpcs3/Emu/Memory/Memory.h | 43 ++++++++--- rpcs3/Emu/Memory/MemoryBlock.h | 46 +++++++++--- rpcs3/Emu/System.cpp | 9 +++ rpcs3/Gui/InstructionEditor.cpp | 27 ++++--- rpcs3/Gui/InterpreterDisAsm.cpp | 20 +++++- rpcs3/Gui/InterpreterDisAsm.h | 14 ++-- rpcs3/Gui/RegisterEditor.cpp | 14 ++-- rpcs3/Loader/ELF32.cpp | 52 +++++++++----- rpcs3/Loader/ELF32.h | 75 +++++++++---------- rpcs3/Loader/Loader.cpp | 3 +- rpcs3/Loader/Loader.h | 1 + rpcs3/rpcs3.vcxproj | 1 + rpcs3/rpcs3.vcxproj.filters | 3 + 31 files changed, 475 insertions(+), 177 deletions(-) create mode 100644 rpcs3/Emu/ARM9/ARM9Decoder.h create mode 100644 rpcs3/Emu/ARM9/ARM9DisAsm.h create mode 100644 rpcs3/Emu/ARM9/ARM9Interpreter.h create mode 100644 rpcs3/Emu/ARM9/ARM9Opcodes.h create mode 100644 rpcs3/Emu/Cell/PPCDecoder.cpp diff --git a/rpcs3/Emu/ARM9/ARM9Decoder.h b/rpcs3/Emu/ARM9/ARM9Decoder.h new file mode 100644 index 0000000000..7510260c60 --- /dev/null +++ b/rpcs3/Emu/ARM9/ARM9Decoder.h @@ -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; + } + } +}; diff --git a/rpcs3/Emu/ARM9/ARM9DisAsm.h b/rpcs3/Emu/ARM9/ARM9DisAsm.h new file mode 100644 index 0000000000..eaf9cda78b --- /dev/null +++ b/rpcs3/Emu/ARM9/ARM9DisAsm.h @@ -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)); + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/ARM9/ARM9Interpreter.h b/rpcs3/Emu/ARM9/ARM9Interpreter.h new file mode 100644 index 0000000000..fc23ddbd9b --- /dev/null +++ b/rpcs3/Emu/ARM9/ARM9Interpreter.h @@ -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(); + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/ARM9/ARM9Opcodes.h b/rpcs3/Emu/ARM9/ARM9Opcodes.h new file mode 100644 index 0000000000..82bafdb61f --- /dev/null +++ b/rpcs3/Emu/ARM9/ARM9Opcodes.h @@ -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; +}; diff --git a/rpcs3/Emu/ARM9/ARM9Thread.cpp b/rpcs3/Emu/ARM9/ARM9Thread.cpp index 9d2ea4c069..7cb3aef44a 100644 --- a/rpcs3/Emu/ARM9/ARM9Thread.cpp +++ b/rpcs3/Emu/ARM9/ARM9Thread.cpp @@ -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() diff --git a/rpcs3/Emu/CPU/CPUDecoder.h b/rpcs3/Emu/CPU/CPUDecoder.h index 2bb1b640cb..3ef9d4a649 100644 --- a/rpcs3/Emu/CPU/CPUDecoder.h +++ b/rpcs3/Emu/CPU/CPUDecoder.h @@ -2,6 +2,12 @@ #include "CPUInstrTable.h" #pragma warning( disable : 4800 ) +class CPUDecoder +{ +public: + virtual void DecodeMemory(const u64 address)=0; +}; + template class InstrCaller { diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index a890c3a281..1c7f7bec99 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -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) diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index d203b21940..365fc5a267 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -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(); \ No newline at end of file diff --git a/rpcs3/Emu/Cell/PPCDecoder.cpp b/rpcs3/Emu/Cell/PPCDecoder.cpp new file mode 100644 index 0000000000..285b64ea33 --- /dev/null +++ b/rpcs3/Emu/Cell/PPCDecoder.cpp @@ -0,0 +1,7 @@ +#include "stdafx.h" +#include "PPCDecoder.h" + +void PPCDecoder::DecodeMemory(const u64 address) +{ + Decode(Memory.Read32(address)); +} \ No newline at end of file diff --git a/rpcs3/Emu/Cell/PPCDecoder.h b/rpcs3/Emu/Cell/PPCDecoder.h index 9d1ad519fe..8294583035 100644 --- a/rpcs3/Emu/Cell/PPCDecoder.h +++ b/rpcs3/Emu/Cell/PPCDecoder.h @@ -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); }; diff --git a/rpcs3/Emu/Cell/PPCThread.cpp b/rpcs3/Emu/Cell/PPCThread.cpp index 789efdb945..ceb4a6988a 100644 --- a/rpcs3/Emu/Cell/PPCThread.cpp +++ b/rpcs3/Emu/Cell/PPCThread.cpp @@ -14,9 +14,7 @@ PPCThread* GetCurrentPPCThread() return (PPCThread*)thread; } -PPCThread::PPCThread(CPUThreadType type) - : CPUThread(type) - , m_dec(nullptr) +PPCThread::PPCThread(CPUThreadType type) : CPUThread(type) { } diff --git a/rpcs3/Emu/Cell/PPCThread.h b/rpcs3/Emu/Cell/PPCThread.h index 86d7bf161e..afcce87ca4 100644 --- a/rpcs3/Emu/Cell/PPCThread.h +++ b/rpcs3/Emu/Cell/PPCThread.h @@ -6,7 +6,6 @@ class PPCThread : public CPUThread { protected: - PPCDecoder* m_dec; u64 m_args[4]; Array m_argv_addr; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index fda484b112..c939c403b6 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -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; diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 050284c009..2505631ca7 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -827,8 +827,6 @@ protected: virtual void DoPause(); virtual void DoResume(); virtual void DoStop(); - - virtual void DoCode(); }; PPUThread& GetCurrentPPUThread(); \ No newline at end of file diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index c5b03df225..8ddbd4eb2f 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -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; iDecode(Memory.Read32(m_offset + PC)); -} diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 63ba2a2b47..7f9d58c13c 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -364,9 +364,6 @@ protected: virtual void DoPause(); virtual void DoResume(); virtual void DoStop(); - -protected: - virtual void DoCode(); }; SPUThread& GetCurrentSPUThread(); \ No newline at end of file diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 92e2160a24..5411e150e4 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -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 +DynamicMemoryBlockBase::DynamicMemoryBlockBase() : m_max_size(0) { } -const u32 DynamicMemoryBlock::GetUsedSize() const +template +const u32 DynamicMemoryBlockBase::GetUsedSize() const { u32 size = 0; @@ -336,17 +418,20 @@ const u32 DynamicMemoryBlock::GetUsedSize() const return size; } -bool DynamicMemoryBlock::IsInMyRange(const u64 addr) +template +bool DynamicMemoryBlockBase::IsInMyRange(const u64 addr) { return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize(); } -bool DynamicMemoryBlock::IsInMyRange(const u64 addr, const u32 size) +template +bool DynamicMemoryBlockBase::IsInMyRange(const u64 addr, const u32 size) { return IsInMyRange(addr) && IsInMyRange(addr + size - 1); } -bool DynamicMemoryBlock::IsMyAddress(const u64 addr) +template +bool DynamicMemoryBlockBase::IsMyAddress(const u64 addr) { for(u32 i=0; i +MemoryBlock* DynamicMemoryBlockBase::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 +void DynamicMemoryBlockBase::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 +bool DynamicMemoryBlockBase::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 +void DynamicMemoryBlockBase::AppendUsedMem(u64 addr, u32 size) { m_used_mem.Move(new MemBlockInfo(addr, size)); } -u64 DynamicMemoryBlock::Alloc(u32 size) +template +u64 DynamicMemoryBlockBase::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 +bool DynamicMemoryBlockBase::Alloc() { return Alloc(GetSize() - GetUsedSize()) != 0; } -bool DynamicMemoryBlock::Free(u64 addr) +template +bool DynamicMemoryBlockBase::Free(u64 addr) { for(u32 i=0; i +u8* DynamicMemoryBlockBase::GetMem(u64 addr) const { for(u32 i=0; i 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); } } } diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 94d6739090..e4bc8b5648 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -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 +class DynamicMemoryBlockBase : public PT { Array 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 DynamicMemoryBlock; +typedef DynamicMemoryBlockBase DynamicMemoryBlockLE; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index e90174a866..de8a67f565 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -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; diff --git a/rpcs3/Gui/InstructionEditor.cpp b/rpcs3/Gui/InstructionEditor.cpp index a33cf8f915..e0f2b3ef84 100644 --- a/rpcs3/Gui/InstructionEditor.cpp +++ b/rpcs3/Gui/InstructionEditor.cpp @@ -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 { diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index a7dad86be3..8618bd0e4e 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -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) diff --git a/rpcs3/Gui/InterpreterDisAsm.h b/rpcs3/Gui/InterpreterDisAsm.h index 22a8c423cd..807212e0e1 100644 --- a/rpcs3/Gui/InterpreterDisAsm.h +++ b/rpcs3/Gui/InterpreterDisAsm.h @@ -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 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); diff --git a/rpcs3/Gui/RegisterEditor.cpp b/rpcs3/Gui/RegisterEditor.cpp index 7069da3b4b..08d12378e4 100644 --- a/rpcs3/Gui/RegisterEditor.cpp +++ b/rpcs3/Gui/RegisterEditor.cpp @@ -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); diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index c6e41fc19f..2d638f5572 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -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; iLoadLE(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= 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; iLoadLE(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 + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 50c8918ded..b0ffa9690e 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -322,6 +322,9 @@ Emu\ARM9 + + Emu\Cell +