#pragma once #include "MemoryBlock.h" class MemoryBase { NullMemoryBlock NullMem; public: ArrayF MemoryBlocks; DynamicMemoryBlock MainMem; DynamicMemoryBlock PRXMem; DynamicMemoryBlock RSXCMDMem; DynamicMemoryBlock MmaperMem; DynamicMemoryBlock RSXFBMem; DynamicMemoryBlock StackMem; MemoryBlock SpuRawMem; MemoryBlock SpuThrMem; bool m_inited; MemoryBase() { m_inited = false; } ~MemoryBase() { Close(); } static __forceinline u16 Reverse16(const u16 val) { return _byteswap_ushort(val); //return ((val >> 8) & 0xff) | ((val << 8) & 0xff00); } static __forceinline u32 Reverse32(const u32 val) { return _byteswap_ulong(val); /* return ((val >> 24) & 0x000000ff) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | ((val << 24) & 0xff000000); */ } static __forceinline u64 Reverse64(const u64 val) { return _byteswap_uint64(val); /* return ((val >> 56) & 0x00000000000000ff) | ((val >> 40) & 0x000000000000ff00) | ((val >> 24) & 0x0000000000ff0000) | ((val >> 8) & 0x00000000ff000000) | ((val << 8) & 0x000000ff00000000) | ((val << 24) & 0x0000ff0000000000) | ((val << 40) & 0x00ff000000000000) | ((val << 56) & 0xff00000000000000); */ } template static __forceinline u64 ReverseData(u64 val); template<> static __forceinline u64 ReverseData<1>(u64 val) { return val; } template<> static __forceinline u64 ReverseData<2>(u64 val) { return Reverse16(val); } template<> static __forceinline u64 ReverseData<4>(u64 val) { return Reverse32(val); } template<> static __forceinline u64 ReverseData<8>(u64 val) { return Reverse64(val); } template static __forceinline T Reverse(T val) { return (T)ReverseData(val); }; MemoryBlock& GetMemByNum(const u8 num) { if(num >= MemoryBlocks.GetCount()) return NullMem; return MemoryBlocks.Get(num); } MemoryBlock& GetMemByAddr(const u64 addr) { for(uint i=0; i= baddr && raddr < baddr + b.GetSize()) { return b.GetStartAddr() + (raddr - baddr); } } return 0; } bool InitSpuRawMem(const u32 max_spu_raw) { //if(SpuRawMem.GetSize()) return false; MemoryBlocks.Add(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw)); return true; } void Init() { if(m_inited) return; m_inited = true; ConLog.Write("Initing memory..."); MemoryBlocks.Add(MainMem.SetRange(0x00010000, 0x2FFF0000)); MemoryBlocks.Add(PRXMem.SetRange(0x30000000, 0x10000000)); MemoryBlocks.Add(RSXCMDMem.SetRange(0x40000000, 0x10000000)); MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000)); MemoryBlocks.Add(RSXFBMem.SetRange(0xC0000000, 0x10000000)); MemoryBlocks.Add(StackMem.SetRange(0xD0000000, 0x10000000)); //MemoryBlocks.Add(SpuRawMem.SetRange(0xE0000000, 0x10000000)); //MemoryBlocks.Add(SpuThrMem.SetRange(0xF0000000, 0x10000000)); ConLog.Write("Memory initialized."); } bool IsGoodAddr(const u64 addr) { for(uint i=0; i void WriteData(const u64 addr, const T* data) { memcpy(GetMemFromAddr(addr), data, sizeof(T)); } template void WriteData(const u64 addr, const T data) { *(T*)GetMemFromAddr(addr) = data; } wxString ReadString(const u64 addr, const u64 len) { wxString ret = wxEmptyString; if(len) memcpy(wxStringBuffer(ret, len), GetMemFromAddr(addr), len); return ret; } wxString ReadString(const u64 addr) { return wxString((const char*)GetMemFromAddr(addr)); } void WriteString(const u64 addr, const wxString& str) { if(!IsGoodAddr(addr, str.Len())) { ConLog.Error("Memory::WriteString error: bad address (0x%llx)", addr); return; } strcpy((char*)GetMemFromAddr(addr), str); } static u64 AlignAddr(const u64 addr, const u64 align) { return (addr + (align-1)) & ~(align-1); } u32 GetUserMemTotalSize() { return PRXMem.GetSize(); } u32 GetUserMemAvailSize() { return PRXMem.GetSize() - PRXMem.GetUsedSize(); } u64 Alloc(const u32 size, const u32 align) { return PRXMem.Alloc(AlignAddr(size, align)); } bool Free(const u64 addr) { return PRXMem.Free(addr); } bool Map(const u64 dst_addr, const u64 src_addr, const u32 size) { if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) { return false; } MemoryBlocks.Add((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size)); ConLog.Warning("memory mapped 0x%llx to 0x%llx size=0x%x", src_addr, dst_addr, size); return true; } bool Unmap(const u64 addr) { for(uint i=0; i class mem_t { const u32 m_addr; public: mem_t(u64 addr) : m_addr(addr) { } mem_t& operator = (T right) { switch(sizeof(T)) { case 1: Memory.Write8(m_addr, right); return *this; case 2: Memory.Write16(m_addr, right); return *this; case 4: Memory.Write32(m_addr, right); return *this; case 8: Memory.Write64(m_addr, right); return *this; } assert(0); return *this; } operator const T() const { switch(sizeof(T)) { case 1: return Memory.Read8(m_addr); case 2: return Memory.Read16(m_addr); case 4: return Memory.Read32(m_addr); case 8: return Memory.Read64(m_addr); } assert(0); } mem_t& operator += (T right) { return *this = (*this) + right; } mem_t& operator -= (T right) { return *this = (*this) - right; } mem_t& operator *= (T right) { return *this = (*this) * right; } mem_t& operator /= (T right) { return *this = (*this) / right; } mem_t& operator %= (T right) { return *this = (*this) % right; } mem_t& operator &= (T right) { return *this = (*this) & right; } mem_t& operator |= (T right) { return *this = (*this) | right; } mem_t& operator ^= (T right) { return *this = (*this) ^ right; } mem_t& operator <<= (T right) { return *this = (*this) << right; } mem_t& operator >>= (T right) { return *this = (*this) >> right; } u64 GetAddr() const { return m_addr; } bool IsGood() const { return Memory.IsGoodAddr(m_addr, sizeof(T)); } }; template class mem_ptr_t { u64 m_addr; const u64 m_iaddr; public: mem_ptr_t(u64 addr) : m_addr(addr) , m_iaddr(addr) { } void operator = (T right) { switch(sizeof(T)) { case 1: Memory.Write8(m_addr, right); return; case 2: Memory.Write16(m_addr, right); return; case 4: Memory.Write32(m_addr, right); return; case 8: Memory.Write64(m_addr, right); return; } ConLog.Error("Bad mem_t size! (%d : 0x%llx)", sizeof(T), m_addr); } operator u8() const { return Memory.Read8(m_addr); } operator u16() const { return Memory.Read16(m_addr); } operator u32() const { return Memory.Read32(m_addr); } operator u64() const { return Memory.Read64(m_addr); } u64 operator += (T right) { *this = right; m_addr += sizeof(T); return m_addr; } const T operator [] (u64 i) const { const u64 offset = i*sizeof(T); (*(mem_ptr_t*)this).m_addr += offset; const T ret = *this; (*(mem_ptr_t*)this).m_addr -= offset; return ret; } void Reset() { m_addr = m_iaddr; } u64 GetCurAddr() const { return m_addr; } u64 GetAddr() const { return m_iaddr; } u64 SetOffset(const u32 offset) { return m_addr += offset; } }; class mem_class_t { u64 addr; const u64 iaddr; public: mem_class_t(u64 _addr) : addr(_addr) , iaddr(_addr) { } template u64 operator += (T right) { mem_t m(addr); m = right; addr += sizeof(T); return addr; } template operator T() { mem_t m(addr); const T ret = m; addr += sizeof(T); return ret; } void Reset() { addr = iaddr; } u64 GetCurAddr() const { return addr; } u64 GetAddr() const { return iaddr; } void SetAddr(const u64 _addr) { addr = _addr; } }; typedef mem_t mem8_t; typedef mem_t mem16_t; typedef mem_t mem32_t; typedef mem_t mem64_t; typedef mem_ptr_t mem8_ptr_t; typedef mem_ptr_t mem16_ptr_t; typedef mem_ptr_t mem32_ptr_t; typedef mem_ptr_t mem64_ptr_t;