mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 04:32:35 +01:00
Added Virtual Memory Block for the IO Address Space
Started implementing some the memory mapping functions of libgcm
This commit is contained in:
parent
40f2e679ec
commit
509d46a544
@ -509,3 +509,186 @@ template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; }
|
|||||||
template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); }
|
template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); }
|
||||||
template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); }
|
template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); }
|
||||||
template<> __forceinline u64 MemoryBase::ReverseData<8>(u64 val) { return Reverse64(val); }
|
template<> __forceinline u64 MemoryBase::ReverseData<8>(u64 val) { return Reverse64(val); }
|
||||||
|
|
||||||
|
VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::IsInMyRange(const u64 addr)
|
||||||
|
{
|
||||||
|
return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::IsInMyRange(const u64 addr, const u32 size)
|
||||||
|
{
|
||||||
|
return IsInMyRange(addr) && IsInMyRange(addr + size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::IsMyAddress(const u64 addr)
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr)
|
||||||
|
{
|
||||||
|
if(addr)
|
||||||
|
{
|
||||||
|
if(!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
m_mapped_memory.Move(new VirtualMemInfo(addr, realaddr, size));
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - size;)
|
||||||
|
{
|
||||||
|
bool is_good_addr = true;
|
||||||
|
|
||||||
|
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) ||
|
||||||
|
(m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size))
|
||||||
|
{
|
||||||
|
is_good_addr = false;
|
||||||
|
addr = m_mapped_memory[i].addr + m_mapped_memory[i].size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_good_addr) continue;
|
||||||
|
|
||||||
|
m_mapped_memory.Move(new VirtualMemInfo(addr, realaddr, size));
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr)
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(m_mapped_memory[i].realAddress == realaddr)
|
||||||
|
{
|
||||||
|
m_mapped_memory.RemoveAt(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::UnmapAddress(u64 addr)
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(m_mapped_memory[i].addr == addr)
|
||||||
|
{
|
||||||
|
m_mapped_memory.RemoveAt(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Read8(const u64 addr, u8* value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
*value = Memory.Read8(realAddr = getRealAddr(addr));
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Read16(const u64 addr, u16* value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
*value = Memory.Read16(realAddr = getRealAddr(addr));
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Read32(const u64 addr, u32* value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
*value = Memory.Read32(realAddr = getRealAddr(addr));
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Read64(const u64 addr, u64* value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
*value = Memory.Read64(realAddr = getRealAddr(addr));
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Read128(const u64 addr, u128* value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
*value = Memory.Read128(realAddr = getRealAddr(addr));
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Write8(const u64 addr, const u8 value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
Memory.Write8(realAddr = getRealAddr(addr), value);
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Write16(const u64 addr, const u16 value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
Memory.Write16(realAddr = getRealAddr(addr), value);
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Write32(const u64 addr, const u32 value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
Memory.Write32(realAddr = getRealAddr(addr), value);
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Write64(const u64 addr, const u64 value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
Memory.Write64(realAddr = getRealAddr(addr), value);
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VirtualMemoryBlock::Write128(const u64 addr, const u128 value)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
Memory.Write128(realAddr = getRealAddr(addr), value);
|
||||||
|
return realAddr != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 VirtualMemoryBlock::getRealAddr(u64 addr)
|
||||||
|
{
|
||||||
|
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size)
|
||||||
|
{
|
||||||
|
return m_mapped_memory[i].realAddress + (addr - m_mapped_memory[i].addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualMemoryBlock::Delete()
|
||||||
|
{
|
||||||
|
m_mapped_memory.Clear();
|
||||||
|
|
||||||
|
MemoryBlock::Delete();
|
||||||
|
}
|
@ -24,6 +24,7 @@ public:
|
|||||||
DynamicMemoryBlock StackMem;
|
DynamicMemoryBlock StackMem;
|
||||||
MemoryBlock SpuRawMem;
|
MemoryBlock SpuRawMem;
|
||||||
MemoryBlock SpuThrMem;
|
MemoryBlock SpuThrMem;
|
||||||
|
VirtualMemoryBlock RSXIOMem;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,23 @@ struct MemBlockInfo : public MemInfo
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VirtualMemInfo : public MemInfo
|
||||||
|
{
|
||||||
|
u64 realAddress;
|
||||||
|
|
||||||
|
VirtualMemInfo(u64 _addr, u64 _realaddr, u32 _size)
|
||||||
|
: MemInfo(_addr, _size)
|
||||||
|
, realAddress(_realaddr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VirtualMemInfo()
|
||||||
|
: MemInfo(0, 0)
|
||||||
|
, realAddress(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class MemoryBlock
|
class MemoryBlock
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -206,6 +223,44 @@ private:
|
|||||||
void AppendLockedMem(u64 addr, u32 size);
|
void AppendLockedMem(u64 addr, u32 size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VirtualMemoryBlock : public MemoryBlock
|
||||||
|
{
|
||||||
|
Array<VirtualMemInfo> m_mapped_memory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VirtualMemoryBlock();
|
||||||
|
|
||||||
|
virtual bool IsInMyRange(const u64 addr);
|
||||||
|
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
||||||
|
virtual bool IsMyAddress(const u64 addr);
|
||||||
|
virtual void Delete();
|
||||||
|
|
||||||
|
// maps real address to virtual address space, returns the mapped address or 0 on failure (if no address is specified the
|
||||||
|
// first mappable space is used)
|
||||||
|
virtual u64 Map(u64 realaddr, u32 size, u64 addr = 0);
|
||||||
|
|
||||||
|
// Unmap real address (please specify only starting point, no midway memory will be unmapped)
|
||||||
|
virtual bool UnmapRealAddress(u64 realaddr);
|
||||||
|
|
||||||
|
// Unmap address (please specify only starting point, no midway memory will be unmapped)
|
||||||
|
virtual bool UnmapAddress(u64 addr);
|
||||||
|
|
||||||
|
virtual bool Read8(const u64 addr, u8* value);
|
||||||
|
virtual bool Read16(const u64 addr, u16* value);
|
||||||
|
virtual bool Read32(const u64 addr, u32* value);
|
||||||
|
virtual bool Read64(const u64 addr, u64* value);
|
||||||
|
virtual bool Read128(const u64 addr, u128* value);
|
||||||
|
|
||||||
|
virtual bool Write8(const u64 addr, const u8 value);
|
||||||
|
virtual bool Write16(const u64 addr, const u16 value);
|
||||||
|
virtual bool Write32(const u64 addr, const u32 value);
|
||||||
|
virtual bool Write64(const u64 addr, const u64 value);
|
||||||
|
virtual bool Write128(const u64 addr, const u128 value);
|
||||||
|
|
||||||
|
// return the real address given a mapped address, if not mapped return 0
|
||||||
|
u64 getRealAddr(u64 addr);
|
||||||
|
};
|
||||||
|
|
||||||
#include "DynamicMemoryBlockBase.inl"
|
#include "DynamicMemoryBlockBase.inl"
|
||||||
|
|
||||||
typedef DynamicMemoryBlockBase<MemoryBlock> DynamicMemoryBlock;
|
typedef DynamicMemoryBlockBase<MemoryBlock> DynamicMemoryBlock;
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
void cellGcmSys_init();
|
void cellGcmSys_init();
|
||||||
Module cellGcmSys(0x0010, cellGcmSys_init);
|
Module cellGcmSys(0x0010, cellGcmSys_init);
|
||||||
|
|
||||||
|
u32 local_size = 0;
|
||||||
|
u32 local_addr = NULL;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CELL_GCM_ERROR_FAILURE = 0x802100ff,
|
CELL_GCM_ERROR_FAILURE = 0x802100ff,
|
||||||
@ -19,10 +22,12 @@ CellGcmContextData current_context;
|
|||||||
gcmInfo gcm_info;
|
gcmInfo gcm_info;
|
||||||
struct gcm_offset
|
struct gcm_offset
|
||||||
{
|
{
|
||||||
u16 ea;
|
mem_ptr_t<u16> io;
|
||||||
u16 offset;
|
mem_ptr_t<u16> ea;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//gcm_offset offsetTable;
|
||||||
|
|
||||||
u32 map_offset_addr = 0;
|
u32 map_offset_addr = 0;
|
||||||
u32 map_offset_pos = 0;
|
u32 map_offset_pos = 0;
|
||||||
|
|
||||||
@ -42,6 +47,9 @@ int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset)
|
|||||||
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
|
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
|
||||||
{
|
{
|
||||||
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
|
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
|
||||||
|
|
||||||
|
if(io % 0x100000 != 0 || size % 0x100000 != 0) return CELL_GCM_ERROR_FAILURE;
|
||||||
|
|
||||||
//Memory.Map(io, ea, size);
|
//Memory.Map(io, ea, size);
|
||||||
//Emu.GetGSManager().GetRender().m_ioAddress = io;
|
//Emu.GetGSManager().GetRender().m_ioAddress = io;
|
||||||
Emu.GetGSManager().GetRender().m_report_main_addr = ea;
|
Emu.GetGSManager().GetRender().m_report_main_addr = ea;
|
||||||
@ -52,8 +60,12 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
|||||||
{
|
{
|
||||||
cellGcmSys.Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
|
cellGcmSys.Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
|
||||||
|
|
||||||
const u32 local_size = 0xf900000; //TODO
|
if(!local_size && !local_addr)
|
||||||
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
|
{
|
||||||
|
u32 local_size = 0xf900000; //TODO
|
||||||
|
u32 local_addr = Memory.RSXFBMem.GetStartAddr();
|
||||||
|
Memory.RSXFBMem.Alloc(local_size);
|
||||||
|
}
|
||||||
|
|
||||||
cellGcmSys.Warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size);
|
cellGcmSys.Warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size);
|
||||||
|
|
||||||
@ -66,8 +78,9 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
|||||||
current_config.memoryFrequency = re32(650000000);
|
current_config.memoryFrequency = re32(650000000);
|
||||||
current_config.coreFrequency = re32(500000000);
|
current_config.coreFrequency = re32(500000000);
|
||||||
|
|
||||||
Memory.RSXFBMem.Alloc(local_size);
|
|
||||||
Memory.RSXCMDMem.Alloc(cmdSize);
|
Memory.RSXCMDMem.Alloc(cmdSize);
|
||||||
|
Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xD0000000, 0x10000000/*256MB*/));
|
||||||
|
Memory.RSXIOMem.Map(ioAddress, ioSize);
|
||||||
|
|
||||||
u32 ctx_begin = ioAddress/* + 0x1000*/;
|
u32 ctx_begin = ioAddress/* + 0x1000*/;
|
||||||
u32 ctx_size = 0x6ffc;
|
u32 ctx_size = 0x6ffc;
|
||||||
@ -112,57 +125,6 @@ int cellGcmGetConfiguration(mem_ptr_t<CellGcmConfig> config)
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGcmAddressToOffset(u32 address, mem32_t offset)
|
|
||||||
{
|
|
||||||
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr());
|
|
||||||
if(!offset.IsGood()) return CELL_EFAULT;
|
|
||||||
|
|
||||||
if(!map_offset_addr)
|
|
||||||
{
|
|
||||||
map_offset_addr = Memory.Alloc(4*50, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 sa;
|
|
||||||
bool is_main_mem = false;
|
|
||||||
const auto& main_mem_info = Emu.GetGSManager().GetRender().m_main_mem_info;
|
|
||||||
for(u32 i=0; i<Emu.GetGSManager().GetRender().m_main_mem_info.GetCount(); ++i)
|
|
||||||
{
|
|
||||||
//main memory
|
|
||||||
if(address >= main_mem_info[i].addr && address < main_mem_info[i].addr + main_mem_info[i].size)
|
|
||||||
{
|
|
||||||
is_main_mem = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(is_main_mem)
|
|
||||||
{
|
|
||||||
//main
|
|
||||||
sa = Emu.GetGSManager().GetRender().m_main_mem_addr;
|
|
||||||
//ConLog.Warning("cellGcmAddressToOffset: main memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
|
||||||
}
|
|
||||||
else if(Memory.RSXFBMem.IsMyAddress(address))
|
|
||||||
{
|
|
||||||
//local
|
|
||||||
sa = Emu.GetGSManager().GetRender().m_local_mem_addr;
|
|
||||||
//ConLog.Warning("cellGcmAddressToOffset: local memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//io
|
|
||||||
sa = Emu.GetGSManager().GetRender().m_ioAddress;
|
|
||||||
//ConLog.Warning("cellGcmAddressToOffset: io memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = address - sa;
|
|
||||||
//ConLog.Warning("Address To Offset: 0x%x -> 0x%x", address, address - sa);
|
|
||||||
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
|
|
||||||
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
|
|
||||||
//map_offset_pos += 4;
|
|
||||||
|
|
||||||
return CELL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
|
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
|
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
|
||||||
@ -573,13 +535,154 @@ int cellGcmSetSecondVFrequency (u32 freq)
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------
|
||||||
|
Memory Mapping
|
||||||
|
------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int cellGcmAddressToOffset(u32 address, mem32_t offset)
|
||||||
|
{
|
||||||
|
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr());
|
||||||
|
if(!offset.IsGood()) return CELL_EFAULT;
|
||||||
|
|
||||||
|
if(!map_offset_addr)
|
||||||
|
{
|
||||||
|
map_offset_addr = Memory.Alloc(4*50, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 sa;
|
||||||
|
bool is_main_mem = false;
|
||||||
|
const auto& main_mem_info = Emu.GetGSManager().GetRender().m_main_mem_info;
|
||||||
|
for(u32 i=0; i<Emu.GetGSManager().GetRender().m_main_mem_info.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
//main memory
|
||||||
|
if(address >= main_mem_info[i].addr && address < main_mem_info[i].addr + main_mem_info[i].size)
|
||||||
|
{
|
||||||
|
is_main_mem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_main_mem)
|
||||||
|
{
|
||||||
|
//main
|
||||||
|
sa = Emu.GetGSManager().GetRender().m_main_mem_addr;
|
||||||
|
//ConLog.Warning("cellGcmAddressToOffset: main memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
||||||
|
}
|
||||||
|
else if(Memory.RSXFBMem.IsMyAddress(address))
|
||||||
|
{
|
||||||
|
//local
|
||||||
|
sa = Emu.GetGSManager().GetRender().m_local_mem_addr;
|
||||||
|
//ConLog.Warning("cellGcmAddressToOffset: local memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//io
|
||||||
|
sa = Emu.GetGSManager().GetRender().m_ioAddress;
|
||||||
|
//ConLog.Warning("cellGcmAddressToOffset: io memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = address - sa;
|
||||||
|
//ConLog.Warning("Address To Offset: 0x%x -> 0x%x", address, address - sa);
|
||||||
|
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
|
||||||
|
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
|
||||||
|
//map_offset_pos += 4;
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 cellGcmGetMaxIoMapSize()
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||||
|
return 0x10000000;//256MB TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void cellGcmGetOffsetTable(mem_ptr_t<gcm_offset> table)
|
||||||
|
{
|
||||||
|
static gcm_offset temp = {NULL, NULL};
|
||||||
|
|
||||||
|
if(!temp.io.IsGood())
|
||||||
|
{
|
||||||
|
u32 mem = Memory.Alloc(sizeof(u16) * 0xBFF, 1);
|
||||||
|
|
||||||
|
for(int i=0; i<0xBFF; i++)
|
||||||
|
{
|
||||||
|
Memory.Write16(mem + i*sizeof(u16), 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.io = re(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!temp.ea.IsGood())
|
||||||
|
{
|
||||||
|
u32 mem = Memory.Alloc(sizeof(u16) * 511, 1);
|
||||||
|
|
||||||
|
for(int i=0; i<511; i++)
|
||||||
|
{
|
||||||
|
Memory.Write16(mem + i*sizeof(u16), 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp.ea = re(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
*table = temp;
|
||||||
|
|
||||||
|
if(!current_config.localAddress)
|
||||||
|
{
|
||||||
|
/*Memory.Write16((table->io), 0xFFFF);
|
||||||
|
Memory.Write16(table->io + (uint)2, 0xFFFF);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!current_config.ioAddress)
|
||||||
|
{
|
||||||
|
/*Memory.Write16(table->ea, 0xFFFF);
|
||||||
|
Memory.Write16(table->ea + (uint)2, 0xFFFF);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
UNIMPLEMENTED_FUNC(cellGcmSys);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t<void*> address)
|
||||||
|
{
|
||||||
|
u64 realAddr;
|
||||||
|
|
||||||
|
realAddr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset);
|
||||||
|
|
||||||
|
if(!realAddr)
|
||||||
|
return CELL_GCM_ERROR_FAILURE;
|
||||||
|
|
||||||
|
Memory.Write64(address, realAddr);
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t cellGcmMapLocalMemory(mem_ptr_t<void*> address, mem_ptr_t<uint32_t> size)
|
||||||
|
{
|
||||||
|
if(!local_size && !local_addr)
|
||||||
|
{
|
||||||
|
u32 local_size = 0xf900000; //TODO
|
||||||
|
u32 local_addr = Memory.RSXFBMem.GetStartAddr();
|
||||||
|
Memory.RSXFBMem.Alloc(local_size);
|
||||||
|
Memory.Write32(address.GetAddr(), local_addr);
|
||||||
|
Memory.Write32(size.GetAddr(), local_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("RSX local memory already mapped");
|
||||||
|
return CELL_GCM_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CELL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void cellGcmSys_init()
|
void cellGcmSys_init()
|
||||||
{
|
{
|
||||||
|
current_config.ioAddress = NULL;
|
||||||
|
current_config.localAddress = NULL;
|
||||||
|
|
||||||
cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
|
cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
|
||||||
cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler);
|
cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler);
|
||||||
cellGcmSys.AddFunc(0x15bae46b, cellGcmInit);
|
cellGcmSys.AddFunc(0x15bae46b, cellGcmInit);
|
||||||
cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand);
|
cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand);
|
||||||
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
|
|
||||||
cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15);
|
cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15);
|
||||||
cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode);
|
cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode);
|
||||||
cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress);
|
cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress);
|
||||||
@ -622,4 +725,11 @@ void cellGcmSys_init()
|
|||||||
cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency);
|
cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency);
|
||||||
cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip);
|
cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip);
|
||||||
cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip);
|
cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip);
|
||||||
|
cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory);
|
||||||
|
|
||||||
|
//Memory Mapping
|
||||||
|
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
|
||||||
|
cellGcmSys.AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize);
|
||||||
|
cellGcmSys.AddFunc(0x2922aed0, cellGcmGetOffsetTable);
|
||||||
|
cellGcmSys.AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user