diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp new file mode 100644 index 0000000000..a475b85eb7 --- /dev/null +++ b/rpcs3/Emu/Memory/vm.cpp @@ -0,0 +1,44 @@ +#include "stdafx.h" + +namespace vm +{ + //TODO + bool check_addr(u32 addr) + { + return false; + } + + bool map(u32 addr, u32 size, u32 flags) + { + return false; + } + + bool unmap(u32 addr, u32 size, u32 flags) + { + return false; + } + + u32 alloc(u32 size) + { + return 0; + } + + void unalloc(u32 addr) + { + } + + u32 read32(u32 addr) + { + return 0; + } + + bool read32(u32 addr, u32& value) + { + return false; + } + + bool write32(u32 addr, u32 value) + { + return false; + } +} \ No newline at end of file diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index b1858c4597..97a43cb78a 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -2,45 +2,28 @@ namespace vm { + bool check_addr(u32 addr); + bool map(u32 addr, u32 size, u32 flags); + bool unmap(u32 addr, u32 size = 0, u32 flags = 0); + u32 alloc(u32 size); + void unalloc(u32 addr); + + template + T* get_ptr(u32 addr) + { + return (T*)&Memory[addr]; + } + + template + T& get_ref(u32 addr) + { + return (T&)Memory[addr]; + } + //TODO - bool check_addr(u32 addr) - { - return false; - } - - bool map(u32 addr, u32 size, u32 flags) - { - return false; - } - - bool unmap(u32 addr, u32 size = 0, u32 flags = 0) - { - return false; - } - - u32 alloc(u32 size) - { - return 0; - } - - void unalloc(u32 addr) - { - } - - u32 read32(u32 addr) - { - return 0; - } - - bool read32(u32 addr, u32& value) - { - return false; - } - - bool write32(u32 addr, u32 value) - { - return false; - } + u32 read32(u32 addr); + bool read32(u32 addr, u32& value); + bool write32(u32 addr, u32 value); } #include "vm_ptr.h" diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 629a59dc91..3003f11e66 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -2,5 +2,385 @@ namespace vm { - //TODO + template + class ptr + { + AT m_addr; + + public: + ptr operator++ (int) + { + AT result = m_addr; + m_addr += sizeof(AT); + return { result }; + } + + ptr& operator++ () + { + m_addr += sizeof(AT); + return *this; + } + + ptr operator-- (int) + { + AT result = m_addr; + m_addr -= sizeof(AT); + return { result }; + } + + ptr& operator-- () + { + m_addr -= sizeof(AT); + return *this; + } + + ptr& operator += (int count) + { + m_addr += count * sizeof(AT); + return *this; + } + + ptr& operator -= (int count) + { + m_addr -= count * sizeof(AT); + return *this; + } + + ptr operator + (int count) const + { + return { m_addr + count * sizeof(AT) }; + } + + ptr operator - (int count) const + { + return { m_addr - count * sizeof(AT) }; + } + + __forceinline ptr& operator *() + { + return get_ref>(m_addr); + } + + __forceinline const ptr& operator *() const + { + return get_ref>(m_addr); + } + + __forceinline ptr& operator [](int index) + { + return get_ref>(m_addr + sizeof(AT) * index); + } + + __forceinline const ptr& operator [](int index) const + { + return get_ref>(m_addr + sizeof(AT) * index); + } + + operator bool() const + { + return m_addr != 0; + } + + AT addr() const + { + return m_addr; + } + + bool check() const + { + return Memory.IsGoodAddr(m_addr, sizeof(AT)); + } + + static ptr make(u32 addr) + { + return (ptr&)addr; + } + }; + + template + class ptr + { + AT m_addr; + + public: + __forceinline T* operator -> () + { + return get_ptr(m_addr); + } + + __forceinline const T* operator -> () const + { + return get_ptr(m_addr); + } + + ptr operator++ (int) + { + AT result = m_addr; + m_addr += sizeof(T); + return { result }; + } + + ptr& operator++ () + { + m_addr += sizeof(T); + return *this; + } + + ptr operator-- (int) + { + AT result = m_addr; + m_addr -= sizeof(T); + return { result }; + } + + ptr& operator-- () + { + m_addr -= sizeof(T); + return *this; + } + + ptr& operator += (int count) + { + m_addr += count * sizeof(T); + return *this; + } + + ptr& operator -= (int count) + { + m_addr -= count * sizeof(T); + return *this; + } + + ptr operator + (int count) const + { + return { m_addr + count * sizeof(T) }; + } + + ptr operator - (int count) const + { + return { m_addr - count * sizeof(T) }; + } + + __forceinline T& operator *() + { + return get_ref(m_addr); + } + + __forceinline const T& operator *() const + { + return get_ref(m_addr); + } + + __forceinline T& operator [](int index) + { + return get_ref(m_addr + sizeof(T) * index); + } + + __forceinline const T& operator [](int index) const + { + return get_ref(m_addr + sizeof(T) * index); + } + + /* + operator ref() + { + return { m_addr }; + } + + operator const ref() const + { + return { m_addr }; + } + */ + + AT addr() const + { + return m_addr; + } + + operator bool() const + { + return m_addr != 0; + } + + T* get_ptr() const + { + return vm::get_ptr(m_addr); + } + + bool check() const + { + return Memory.IsGoodAddr(m_addr, sizeof(T)); + } + + static ptr make(u32 addr) + { + return (ptr&)addr; + } + }; + + template + class ptr + { + AT m_addr; + + public: + AT addr() const + { + return m_addr; + } + + void* get_ptr() const + { + return vm::get_ptr(m_addr); + } + + bool check() const + { + return Memory.IsGoodAddr(m_addr); + } + + operator bool() const + { + return m_addr != 0; + } + + static ptr make(u32 addr) + { + return (ptr&)addr; + } + }; + + template + class ptr + { + AT m_addr; + + __forceinline RT call_func(bool is_async) const + { + Callback cb; + cb.SetAddr(m_addr); + return (RT)cb.Branch(!is_async); + } + + public: + typedef RT(*type)(); + + __forceinline RT operator()() const + { + return call_func(false); + } + + __forceinline void async() const + { + call_func(true); + } + + AT addr() const + { + return m_addr; + } + + type get_ptr() const + { + return *((type*)vm::get_ptr(m_addr)); + } + + bool check() const + { + return Memory.IsGoodAddr(m_addr); + } + + operator bool() const + { + return m_addr != 0; + } + + static ptr make(u32 addr) + { + return (ptr&)addr; + } + }; + + template + class ptr + { + AT m_addr; + + __forceinline RT call_func(bool is_async, T... args) const + { + template + struct _func_arg + { + __forceinline static u64 get_value(const T& arg) + { + return arg; + } + }; + + template + struct _func_arg> + { + __forceinline static u64 get_value(const ptr arg) + { + return arg.addr(); + } + }; + + template + struct _func_arg> + { + __forceinline static u64 get_value(const ref arg) + { + return arg.addr(); + } + }; + + Callback cb; + cb.SetAddr(m_addr); + cb.Handle(_func_arg::get_value(args)...); + return (RT)cb.Branch(!is_async); + } + + public: + typedef RT(*type)(T...); + + __forceinline RT operator()(T... args) const + { + return call_func(false, args...); + } + + __forceinline void async(T... args) const + { + call_func(true, args...); + } + + AT addr() const + { + return m_addr; + } + + type get_ptr() const + { + return *((type*)vm::get_ptr(m_addr)); + } + + bool check() const + { + return Memory.IsGoodAddr(m_addr); + } + + operator bool() const + { + return m_addr != 0; + } + + static ptr make(u32 addr) + { + return (ptr&)addr; + } + }; + + template + class beptr : public ptr> {}; } \ No newline at end of file diff --git a/rpcs3/Emu/Memory/vm_ref.h b/rpcs3/Emu/Memory/vm_ref.h index 629a59dc91..797c6da784 100644 --- a/rpcs3/Emu/Memory/vm_ref.h +++ b/rpcs3/Emu/Memory/vm_ref.h @@ -2,5 +2,62 @@ namespace vm { - //TODO + template + class _ref_base + { + AT m_addr; + + public: + operator T&() + { + return get_ref(m_addr); + } + + operator const T&() const + { + return get_ref(m_addr); + } + + AT addr() const + { + return m_addr; + } + + bool check() const + { + return Memory.IsGoodAddr(m_addr, sizeof(T)); + } + + static ref make(u32 addr) + { + return (ref&)addr; + } + }; + + //BE reference to LE data + template class brefl : public _ref_base> {}; + + //BE reference to BE data + template class brefb : public _ref_base, be_t> {}; + + //LE reference to BE data + template class lrefb : public _ref_base, AT> {}; + + //LE reference to LE data + template class lrefl : public _ref_base {}; + + namespace ps3 + { + //default reference for HLE functions (LE reference to BE data) + template class ref : public lrefb {}; + + //default reference for HLE structures (BE reference to BE data) + template class bref : public brefb {}; + } + + namespace psv + { + //default reference for HLE functions & structures (LE reference to LE data) + template class ref : public lrefl {}; + } } \ No newline at end of file diff --git a/rpcs3/Emu/Memory/vm_var.h b/rpcs3/Emu/Memory/vm_var.h index bc4a99422c..adb4338c0d 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -34,7 +34,7 @@ namespace vm void alloc() { m_addr = Memory.Alloc(size(), m_align); - m_ptr = Memory.IsGoodAddr(m_addr, size()) ? (T*)&Memory[m_addr] : nullptr; + m_ptr = Memory.IsGoodAddr(m_addr, size()) ? get_ptr(m_addr) : nullptr; } void dealloc() @@ -46,16 +46,6 @@ namespace vm m_ptr = nullptr; } } - - void clear() - { - if (check()) - { - Memory.Free(m_addr); - m_addr = 0; - m_ptr = nullptr; - } - } static var make(u32 addr, u32 size = sizeof(T), u32 align = sizeof(T)) { @@ -64,7 +54,7 @@ namespace vm res.m_addr = addr; res.m_size = size; res.m_align = align; - res.m_ptr = Memory.IsGoodAddr(m_addr, sizeof(T)) ? (T*)&Memory[m_addr] : nullptr; + res.m_ptr = Memory.IsGoodAddr(addr, size) ? get_ptr(addr) : nullptr; return res; } @@ -166,7 +156,7 @@ namespace vm void alloc() { m_addr = Memory.Alloc(size(), m_align); - m_ptr = Memory.IsGoodAddr(m_addr, size()) ? (T*)&Memory[m_addr] : nullptr; + m_ptr = Memory.IsGoodAddr(m_addr, size()) ? get_ptr(m_addr) : nullptr; } void dealloc() @@ -187,7 +177,7 @@ namespace vm res.m_count = count; res.m_size = size; res.m_align = align; - res.m_ptr = Memory.IsGoodAddr(m_addr, size()) ? (T*)&Memory[m_addr] : nullptr; + res.m_ptr = Memory.IsGoodAddr(addr, size * count) ? get_ptr(addr) : nullptr; return res; } @@ -297,17 +287,17 @@ namespace vm T& at(uint index) { if (index >= count()) - throw std::out_of_range(); + throw std::out_of_range(std::to_string(index) + " >= " + count()); - return *(m_ptr + index); + return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index); } const T& at(uint index) const { if (index >= count()) - throw std::out_of_range(); + throw std::out_of_range(std::to_string(index) + " >= " + count()); - return *(m_ptr + index); + return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index); } T* ptr() @@ -365,7 +355,7 @@ namespace vm void alloc() { m_addr = Memory.Alloc(size(), m_align); - m_ptr = Memory.IsGoodAddr(m_addr, size()) ? (T*)&Memory[m_addr] : nullptr; + m_ptr = Memory.IsGoodAddr(m_addr, size()) ? get_ptr(m_addr) : nullptr; } void dealloc() @@ -479,23 +469,23 @@ namespace vm const T& operator [](uint index) const { assert(index < count()); - return return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index); + return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index); } T& at(uint index) { if (index >= count()) - throw std::out_of_range(); + throw std::out_of_range(std::to_string(index) + " >= " + count()); - return *(m_ptr + index); + return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index); } const T& at(uint index) const { if (index >= count()) - throw std::out_of_range(); + throw std::out_of_range(std::to_string(index) + " >= " + count()); - return *(m_ptr + index); + return *(T*)((u8*)m_ptr + (m_size < m_align ? m_align : m_size) * index); } /* diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index f576cfabe6..8029d613c3 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -90,6 +90,7 @@ + @@ -518,7 +519,7 @@ - Level3 + Level2 Disabled false Use diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 44c5720d14..ac5d371cdb 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -584,6 +584,9 @@ Emu\SysCalls\Modules + + Emu\Memory +