From 509d46a5442058a4c41a5d1a0bd5a84862de1b38 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Fri, 17 Jan 2014 18:56:03 +0200 Subject: [PATCH 01/12] Added Virtual Memory Block for the IO Address Space Started implementing some the memory mapping functions of libgcm --- rpcs3/Emu/Memory/Memory.cpp | 183 ++++++++++++++++++ rpcs3/Emu/Memory/Memory.h | 1 + rpcs3/Emu/Memory/MemoryBlock.h | 55 ++++++ rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 224 ++++++++++++++++------ 4 files changed, 406 insertions(+), 57 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 6fcea3252f..40622641fe 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -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<4>(u64 val) { return Reverse32(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[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[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[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(); +} \ No newline at end of file diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 34b1426e52..919f2588c4 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -24,6 +24,7 @@ public: DynamicMemoryBlock StackMem; MemoryBlock SpuRawMem; MemoryBlock SpuThrMem; + VirtualMemoryBlock RSXIOMem; struct { diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 7d497bb1c4..ad06f14c33 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -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 { protected: @@ -206,6 +223,44 @@ private: void AppendLockedMem(u64 addr, u32 size); }; +class VirtualMemoryBlock : public MemoryBlock +{ + Array 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" typedef DynamicMemoryBlockBase DynamicMemoryBlock; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 0eef3bd6c8..1458bd2da2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -6,6 +6,9 @@ void cellGcmSys_init(); Module cellGcmSys(0x0010, cellGcmSys_init); +u32 local_size = 0; +u32 local_addr = NULL; + enum { CELL_GCM_ERROR_FAILURE = 0x802100ff, @@ -19,10 +22,12 @@ CellGcmContextData current_context; gcmInfo gcm_info; struct gcm_offset { - u16 ea; - u16 offset; + mem_ptr_t io; + mem_ptr_t ea; }; +//gcm_offset offsetTable; + u32 map_offset_addr = 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) { 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); //Emu.GetGSManager().GetRender().m_ioAddress = io; 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); - const u32 local_size = 0xf900000; //TODO - const u32 local_addr = Memory.RSXFBMem.GetStartAddr(); + if(!local_size && !local_addr) + { + 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); @@ -66,8 +78,9 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) current_config.memoryFrequency = re32(650000000); current_config.coreFrequency = re32(500000000); - Memory.RSXFBMem.Alloc(local_size); 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_size = 0x6ffc; @@ -112,57 +125,6 @@ int cellGcmGetConfiguration(mem_ptr_t config) 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= 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) { 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; } +/*------------------------------------------------------------ + 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= 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 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 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 address, mem_ptr_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() { + current_config.ioAddress = NULL; + current_config.localAddress = NULL; + cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler); cellGcmSys.AddFunc(0x15bae46b, cellGcmInit); cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); - cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset); cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15); cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); @@ -622,4 +725,11 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); 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); } From 48726e8fed12f299b4af1dd5cf1e4a365cdd1437 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Sat, 18 Jan 2014 23:36:22 +0200 Subject: [PATCH 02/12] More memory mapping functions for libgcm --- rpcs3/Emu/Memory/Memory.cpp | 13 ++ rpcs3/Emu/Memory/MemoryBlock.h | 3 + rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 142 +++++++++++----------- 3 files changed, 90 insertions(+), 68 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 40622641fe..4188cb3170 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -686,6 +686,19 @@ u64 VirtualMemoryBlock::getRealAddr(u64 addr) return 0; } +u64 VirtualMemoryBlock::getMappedAddress(u64 realAddress) +{ + for(u32 i=0; i= m_mapped_memory[i].realAddress && realAddress < m_mapped_memory[i].realAddress + m_mapped_memory[i].size) + { + return m_mapped_memory[i].addr + (realAddress - m_mapped_memory[i].realAddress); + } + } + + return 0; +} + void VirtualMemoryBlock::Delete() { m_mapped_memory.Clear(); diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index ad06f14c33..793af5ca4d 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -259,6 +259,9 @@ public: // return the real address given a mapped address, if not mapped return 0 u64 getRealAddr(u64 addr); + + // return the mapped address given a real address, if not mapped return 0 + u64 getMappedAddress(u64 realAddress); }; #include "DynamicMemoryBlockBase.inl" diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 1458bd2da2..26776ad67b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -17,16 +17,29 @@ enum CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004, }; +/*------------------------------------------------------------ + Memory Mapping +------------------------------------------------------------*/ + +struct gcm_offset +{ + u64 io; + u64 ea; +}; + +void InitOffsetTable(); +int cellGcmAddressToOffset(u32 address, mem32_t offset); +u32 cellGcmGetMaxIoMapSize(); +void cellGcmGetOffsetTable(mem_ptr_t table); +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address); +int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size); + + +//------------------------------------------------------------ + CellGcmConfig current_config; CellGcmContextData current_context; gcmInfo gcm_info; -struct gcm_offset -{ - mem_ptr_t io; - mem_ptr_t ea; -}; - -//gcm_offset offsetTable; u32 map_offset_addr = 0; u32 map_offset_pos = 0; @@ -44,26 +57,14 @@ int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset) return CELL_OK; } -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); - - if(io % 0x100000 != 0 || size % 0x100000 != 0) return CELL_GCM_ERROR_FAILURE; - - //Memory.Map(io, ea, size); - //Emu.GetGSManager().GetRender().m_ioAddress = io; - Emu.GetGSManager().GetRender().m_report_main_addr = ea; - return CELL_OK; -} - 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); if(!local_size && !local_addr) { - u32 local_size = 0xf900000; //TODO - u32 local_addr = Memory.RSXFBMem.GetStartAddr(); + local_size = 0xf900000; //TODO + local_addr = Memory.RSXFBMem.GetStartAddr(); Memory.RSXFBMem.Alloc(local_size); } @@ -78,9 +79,10 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) current_config.memoryFrequency = re32(650000000); current_config.coreFrequency = re32(500000000); + InitOffsetTable(); Memory.RSXCMDMem.Alloc(cmdSize); - Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xD0000000, 0x10000000/*256MB*/)); - Memory.RSXIOMem.Map(ioAddress, ioSize); + Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase + cellGcmMapEaIoAddress(ioAddress, ioSize, 0); u32 ctx_begin = ioAddress/* + 0x1000*/; u32 ctx_size = 0x6ffc; @@ -539,6 +541,23 @@ int cellGcmSetSecondVFrequency (u32 freq) Memory Mapping ------------------------------------------------------------*/ +gcm_offset offsetTable = {0, 0}; + +void InitOffsetTable() +{ + offsetTable.io = Memory.Alloc(3072*sizeof(u16), 1); + for(int i=0; i<3072; i++) + { + Memory.Write16(offsetTable.io + sizeof(u16)*i, 0xFFFF); + } + + offsetTable.ea = Memory.Alloc(256*sizeof(u16), 1);//TODO: check flags + for(int i=0; i<256; i++) + { + Memory.Write16(offsetTable.ea + sizeof(u16)*i, 0xFFFF); + } +} + int cellGcmAddressToOffset(u32 address, mem32_t offset) { cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); @@ -598,47 +617,8 @@ u32 cellGcmGetMaxIoMapSize() void cellGcmGetOffsetTable(mem_ptr_t 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); + table->io = re(offsetTable.io); + table->ea = re(offsetTable.ea); } int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) @@ -655,12 +635,38 @@ int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) return CELL_OK; } +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); + + if((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; + + //check if the mapping was successfull + if(Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) + { + //fill the offset table + for(int i=0; i address, mem_ptr_t size) { if(!local_size && !local_addr) { - u32 local_size = 0xf900000; //TODO - u32 local_addr = Memory.RSXFBMem.GetStartAddr(); + local_size = 0xf900000; //TODO + local_addr = Memory.RSXFBMem.GetStartAddr(); Memory.RSXFBMem.Alloc(local_size); Memory.Write32(address.GetAddr(), local_addr); Memory.Write32(size.GetAddr(), local_size); @@ -685,7 +691,6 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15); cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); - cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus); cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); @@ -725,11 +730,12 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); 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); + cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); + cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); } From ab41540064bf8a3a0e8fd6f96ad841d2a61a7e81 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 19 Jan 2014 05:14:11 +0200 Subject: [PATCH 03/12] Improved ID manager. Improved MemoryBlock. --- Utilities/IdManager.h | 188 +++++++++++--------- rpcs3/Emu/CPU/CPUThread.cpp | 3 +- rpcs3/Emu/CPU/CPUThreadManager.cpp | 10 +- rpcs3/Emu/Cell/PPUInterpreter.h | 4 + rpcs3/Emu/Cell/RawSPUThread.cpp | 13 +- rpcs3/Emu/GS/GL/GLGSRender.cpp | 34 ++-- rpcs3/Emu/GS/GL/GLGSRender.h | 129 ++++++++++++-- rpcs3/Emu/GS/GL/GLProgram.cpp | 1 - rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl | 4 +- rpcs3/Emu/Memory/Memory.cpp | 40 +++-- rpcs3/Emu/Memory/Memory.h | 129 ++++++++------ rpcs3/Emu/SysCalls/Modules.cpp | 24 +-- rpcs3/Emu/SysCalls/Modules.h | 22 ++- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp | 137 +------------- rpcs3/Emu/SysCalls/Modules/cellGifDec.h | 114 ++++++++++++ rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp | 127 +------------ rpcs3/Emu/SysCalls/Modules/cellJpgDec.h | 101 +++++++++++ rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 130 +------------- rpcs3/Emu/SysCalls/Modules/cellPngDec.h | 105 +++++++++++ rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 44 ++--- rpcs3/Emu/SysCalls/SysCalls.h | 23 +-- rpcs3/Emu/SysCalls/lv2/SC_Event.cpp | 12 +- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 80 +++------ rpcs3/Emu/SysCalls/lv2/SC_Heap.cpp | 11 +- rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp | 52 +++--- rpcs3/Gui/MainFrame.cpp | 41 ----- 27 files changed, 813 insertions(+), 767 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules/cellGifDec.h create mode 100644 rpcs3/Emu/SysCalls/Modules/cellJpgDec.h create mode 100644 rpcs3/Emu/SysCalls/Modules/cellPngDec.h diff --git a/Utilities/IdManager.h b/Utilities/IdManager.h index 112788b19f..4e95b29b51 100644 --- a/Utilities/IdManager.h +++ b/Utilities/IdManager.h @@ -1,21 +1,58 @@ #pragma once -#include "Array.h" +#include typedef u32 ID_TYPE; +class IDData +{ +protected: + void* m_ptr; + std::function m_destr; + +public: + IDData(void* ptr, std::function destr) + : m_ptr(ptr) + , m_destr(destr) + { + } + + ~IDData() + { + m_destr(m_ptr); + } + + template T* get() + { + return (T*)m_ptr; + } + + template const T* get() const + { + return (const T*)m_ptr; + } +}; + struct ID { - bool m_used; wxString m_name; u8 m_attr; - void* m_data; + IDData* m_data; - ID(bool used = false, const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0) - : m_used(used) - , m_name(name) - , m_data(data) + template + ID(const wxString& name, T* data, const u8 attr) + : m_name(name) , m_attr(attr) { + m_data = new IDData(data, [](void *ptr) -> void { delete (T*)ptr; }); + } + + ID() : m_data(nullptr) + { + } + + void Kill() + { + delete m_data; } }; @@ -23,21 +60,16 @@ class IdManager { ArrayF IDs; - static const u64 first_id = 1; + static const ID_TYPE s_first_id = 1; + static const ID_TYPE s_max_id = -1; + + std::unordered_map m_id_map; + std::mutex m_mtx_main; + + ID_TYPE m_cur_id; - void Cleanup() - { - while(IDs.GetCount()) - { - const u32 num = IDs.GetCount()-1; - ID& id = IDs[num]; - if(id.m_used) break; - IDs.RemoveAt(num); - } - } - public: - IdManager() + IdManager() : m_cur_id(s_first_id) { } @@ -45,92 +77,82 @@ public: { Clear(); } - - static ID_TYPE GetMaxID() - { - return (ID_TYPE)-1; - } - - bool CheckID(const u64 id) - { - if(id == 0 || id > (u64)NumToID(IDs.GetCount()-1) || id >= GetMaxID()) return false; - return IDs[IDToNum(id)].m_used; - } - - __forceinline const ID_TYPE NumToID(const ID_TYPE num) const + bool CheckID(const ID_TYPE id) { - return num + first_id; - } - - __forceinline const ID_TYPE IDToNum(const ID_TYPE id) const - { - return id - first_id; + std::lock_guard lock(m_mtx_main); + + return m_id_map.find(id) != m_id_map.end(); } void Clear() { - IDs.Clear(); - } - - virtual ID_TYPE GetNewID(const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0) - { - for(uint i=0; i lock(m_mtx_main); + + for(auto& i : m_id_map) { - if(IDs[i].m_used) continue; - return NumToID(i); + i.second.Kill(); } - const ID_TYPE pos = IDs.GetCount(); - if(NumToID(pos) >= GetMaxID()) return 0; - IDs.Add(new ID(true, name, data, attr)); - return NumToID(pos); + m_id_map.clear(); + m_cur_id = s_first_id; } - ID& GetIDData(const ID_TYPE _id) + template + ID_TYPE GetNewID(const wxString& name = wxEmptyString, T* data = nullptr, const u8 attr = 0) { - //if(!CheckID(_id)) return IDs.Get(0); //TODO - return IDs[IDToNum(_id)]; - } - + std::lock_guard lock(m_mtx_main); - bool GetFirst(ID& dst, ID_TYPE* _id = NULL) + m_id_map[m_cur_id] = std::move(ID(name, data, attr)); + + return m_cur_id++; + } + + ID& GetID(const ID_TYPE id) { - u32 pos = 0; - return GetNext(pos, dst, _id); + std::lock_guard lock(m_mtx_main); + + return m_id_map[id]; + } + + template + bool GetIDData(const ID_TYPE id, T*& result) + { + std::lock_guard lock(m_mtx_main); + + auto f = m_id_map.find(id); + + if(f == m_id_map.end()) + { + return false; + } + + result = f->second.m_data->get(); + + return true; } bool HasID(const s64 id) { - if(id == wxID_ANY) return IDs.GetCount() != 0; + std::lock_guard lock(m_mtx_main); + + if(id == wxID_ANY) + return m_id_map.begin() != m_id_map.end(); + return CheckID(id); } - bool GetNext(u32& pos, ID& dst, ID_TYPE* _id = NULL) + bool RemoveID(const ID_TYPE id) { - while(pos < IDs.GetCount()) - { - ID& id = IDs[pos++]; - if(!id.m_used) continue; - dst = id; - if(_id) *_id = NumToID(pos - 1); - return true; - } + std::lock_guard lock(m_mtx_main); - return false; - } + auto item = m_id_map.find(id); + + if(item == m_id_map.end()) return false; + + item->second.Kill(); + m_id_map.erase(item); - virtual bool RemoveID(const ID_TYPE _id, bool free_data = true) - { - if(!CheckID(_id)) return false; - ID& id = IDs[IDToNum(_id)]; - if(!id.m_used) return false; - id.m_used = false; - id.m_attr = 0; - id.m_name.Clear(); - if(free_data) delete id.m_data; - id.m_data = NULL; - if(IDToNum(_id) == IDs.GetCount()-1) Cleanup(); return true; } -}; +}; \ No newline at end of file diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 9e915800e9..b5ab265758 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -32,14 +32,13 @@ void CPUThread::Close() if(IsAlive()) { m_free_data = true; + ThreadBase::Stop(false); } else { delete m_dec; m_dec = nullptr; } - - Stop(); } void CPUThread::Reset() diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index 049beaa3bb..612c71ea5c 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -66,20 +66,20 @@ void CPUThreadManager::RemoveThread(const u32 id) #endif if(thr->IsAlive()) { - thr->Close(); + //thr->Close(); } else { - thr->Close(); - delete thr; + //thr->Close(); + //delete thr; } m_threads.RemoveFAt(i); - i--; + break; } - Emu.GetIdManager().RemoveID(id, false); + Emu.GetIdManager().RemoveID(id); Emu.CheckStatus(); } diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index c4fda8f33a..ebc8193c96 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -70,7 +70,11 @@ private: SysCalls::DoSyscall(CPU.GPR[11]); if(enable_log) + { ConLog.Warning("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); + if(CPU.GPR[11] > 1024) + SysCalls::DoFunc(CPU.GPR[11]); + } #ifdef HLE_CALL_DEBUG ConLog.Write("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); #endif diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 006c7b28d7..27a97f63b5 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -3,22 +3,25 @@ RawSPUThread::RawSPUThread(u32 index, CPUThreadType type) : SPUThread(type) + , MemoryBlock() , m_index(index) { - Memory.MemoryBlocks.Add(MemoryBlock::SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_OFFSET)); + Memory.MemoryBlocks.push_back(SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_OFFSET)); Reset(); } RawSPUThread::~RawSPUThread() { - for(int i=0; iGetStartAddr() == GetStartAddr()) { - Memory.MemoryBlocks.RemoveFAt(i); - return; + Memory.MemoryBlocks.erase(Memory.MemoryBlocks.begin() + i); + break; } } + + Close(); } bool RawSPUThread::Read8(const u64 addr, u8* value) diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 0fbb8f2eeb..2e2695e828 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -15,6 +15,7 @@ gcmBuffer gcmBuffers[8]; int last_width = 0, last_height = 0, last_depth_format = 0; +GLenum g_last_gl_error = GL_NO_ERROR; void printGlError(GLenum err, const char* situation) { if(err != GL_NO_ERROR) @@ -24,11 +25,6 @@ void printGlError(GLenum err, const char* situation) } } -void checkForGlError(const char* situation) -{ - printGlError(glGetError(), situation); -} - #if 0 #define checkForGlError(x) /*x*/ #endif @@ -415,25 +411,6 @@ bool GLGSRender::LoadProgram() m_prog_buffer.Add(m_program, m_shader_prog, *m_cur_shader_prog, m_vertex_prog, *m_cur_vertex_prog); checkForGlError("m_prog_buffer.Add"); m_program.Use(); - - GLint r = GL_FALSE; - glGetProgramiv(m_program.id, GL_VALIDATE_STATUS, &r); - if(r != GL_TRUE) - { - glGetProgramiv(m_program.id, GL_INFO_LOG_LENGTH, &r); - - if(r) - { - char* buf = new char[r+1]; - GLsizei len; - memset(buf, 0, r+1); - glGetProgramInfoLog(m_program.id, r, &len, buf); - ConLog.Error("Failed to validate program: %s", buf); - delete[] buf; - } - - Emu.Pause(); - } } return true; @@ -639,6 +616,7 @@ void GLGSRender::OnReset() void GLGSRender::ExecCMD() { + //return; if(!LoadProgram()) { ConLog.Error("LoadProgram failed."); @@ -1085,5 +1063,13 @@ void GLGSRender::Flip() m_fbo.Bind(); } + for(uint i=0; iFlip(); + + if(m_fbo.IsCreated()) + m_fbo.Bind(); } diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 17573c677b..419f57aab3 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -10,8 +10,16 @@ #pragma comment(lib, "opengl32.lib") #pragma comment(lib, "gl.lib") +#define RSX_DEBUG 1 + +extern GLenum g_last_gl_error; void printGlError(GLenum err, const char* situation); -void checkForGlError(const char* situation); + +#if RSX_DEBUG +#define checkForGlError(sit) if((g_last_gl_error = glGetError()) != GL_NO_ERROR) printGlError(g_last_gl_error, sit) +#else +#define checkForGlError(sit) +#endif class GLTexture { @@ -324,6 +332,10 @@ public: s_is_initialized = true; Initialize(); } + else + { + m_program.Use(); + } } virtual void InitializeShaders() = 0; @@ -340,25 +352,107 @@ public: } }; -class DrawCursorObj : PostDrawObj +class DrawCursorObj : public PostDrawObj { u32 m_tex_id; + void* m_pixels; + u32 m_width, m_height; + double m_pos_x, m_pos_y, m_pos_z; + bool m_update_texture, m_update_pos; public: - DrawCursorObj() : m_tex_id(0) + DrawCursorObj() : PostDrawObj() + , m_tex_id(0) + , m_update_texture(false) + , m_update_pos(false) { } virtual void Draw() { + checkForGlError("PostDrawObj : Unknown error."); + PostDrawObj::Draw(); + checkForGlError("PostDrawObj::Draw"); + + if(!m_fbo.IsCreated()) + { + m_fbo.Create(); + checkForGlError("DrawCursorObj : m_fbo.Create"); + m_fbo.Bind(); + checkForGlError("DrawCursorObj : m_fbo.Bind"); + + m_rbo.Create(); + checkForGlError("DrawCursorObj : m_rbo.Create"); + m_rbo.Bind(); + checkForGlError("DrawCursorObj : m_rbo.Bind"); + m_rbo.Storage(GL_RGBA, m_width, m_height); + checkForGlError("DrawCursorObj : m_rbo.Storage"); + + m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId()); + checkForGlError("DrawCursorObj : m_fbo.Renderbuffer"); + } + + m_fbo.Bind(); + checkForGlError("DrawCursorObj : m_fbo.Bind"); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + checkForGlError("DrawCursorObj : glDrawBuffer"); + + m_program.Use(); + checkForGlError("DrawCursorObj : m_program.Use"); + + if(m_update_texture) + { + //m_update_texture = false; + + glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height); + checkForGlError("DrawCursorObj : glUniform2f"); + if(!m_tex_id) + { + glGenTextures(1, &m_tex_id); + checkForGlError("DrawCursorObj : glGenTextures"); + } + + glActiveTexture(GL_TEXTURE0); + checkForGlError("DrawCursorObj : glActiveTexture"); + glBindTexture(GL_TEXTURE_2D, m_tex_id); + checkForGlError("DrawCursorObj : glBindTexture"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels); + checkForGlError("DrawCursorObj : glTexImage2D"); + m_program.SetTex(0); + } + + if(m_update_pos) + { + //m_update_pos = false; + + glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f); + checkForGlError("DrawCursorObj : glUniform4f"); + } + + glDrawArrays(GL_QUADS, 0, 4); + checkForGlError("DrawCursorObj : glDrawArrays"); + + m_fbo.Bind(GL_READ_FRAMEBUFFER); + checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)"); + GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); + checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)"); + GLfbo::Blit( + 0, 0, m_width, m_height, + 0, 0, m_width, m_height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + checkForGlError("DrawCursorObj : GLfbo::Blit"); + m_fbo.Bind(); + checkForGlError("DrawCursorObj : m_fbo.Bind"); } virtual void InitializeShaders() { m_vp.shader = - "layout (location = 0) in vec4 in_pos;\n" - "layout (location = 1) in vec2 in_tc;\n" + "#version 330\n" + "\n" + "uniform vec4 in_pos;\n" + "uniform vec2 in_tc;\n" "out vec2 tc;\n" "\n" "void main()\n" @@ -371,36 +465,35 @@ public: "#version 330\n" "\n" "in vec2 tc;\n" - "uniform sampler2D tex;\n" + "uniform sampler2D tex0;\n" "layout (location = 0) out vec4 res;\n" "\n" "void main()\n" "{\n" - " res = texture(tex, tc);\n" + " res = texture(tex0, tc);\n" "}\n"; } - void SetTexture(void* pixels, int width, int hight) + void SetTexture(void* pixels, int width, int height) { - glUniform2i(1, width, hight); - if(!m_tex_id) - { - glGenTextures(1, &m_tex_id); - } + m_pixels = pixels; + m_width = width; + m_height = height; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_tex_id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, hight, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); - m_program.SetTex(0); + m_update_texture = true; } void SetPosition(float x, float y, float z = 0.0f) { - glUniform4f(0, x, y, z, 1.0f); + m_pos_x = x; + m_pos_y = y; + m_pos_z = z; + m_update_pos = true; } void InitializeLocations() { + //ConLog.Warning("tex0 location = 0x%x", m_program.GetLocation("tex0")); } }; diff --git a/rpcs3/Emu/GS/GL/GLProgram.cpp b/rpcs3/Emu/GS/GL/GLProgram.cpp index 49b00de64b..9e6a4fe5eb 100644 --- a/rpcs3/Emu/GS/GL/GLProgram.cpp +++ b/rpcs3/Emu/GS/GL/GLProgram.cpp @@ -89,7 +89,6 @@ void GLProgram::Use() void GLProgram::SetTex(u32 index) { int loc = GetLocation(wxString::Format("tex%u", index)); - checkForGlError(wxString::Format("GetLocation(tex%u)", index)); glProgramUniform1i(id, loc, index); checkForGlError(wxString::Format("SetTex(%u - %d - %d)", id, index, loc)); } diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl index d8da141b53..bbdafbd80f 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl @@ -1,7 +1,9 @@ //DynamicMemoryBlockBase template -DynamicMemoryBlockBase::DynamicMemoryBlockBase() : m_max_size(0) +DynamicMemoryBlockBase::DynamicMemoryBlockBase() + : PT() + , m_max_size(0) { } diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 4188cb3170..99834ef2e9 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Memory.h" #include "MemoryBlock.h" +#include MemoryBase Memory; @@ -27,14 +28,14 @@ void MemoryBlock::InitMemory() { if(!range_size) return; - safe_delete(mem); + if(mem) safe_free(mem); mem = (u8*)malloc(range_size); memset(mem, 0, range_size); } void MemoryBlock::Delete() { - safe_delete(mem); + if(mem) safe_free(mem); Init(); } @@ -127,7 +128,8 @@ bool MemoryBlock::Read8(const u64 addr, u8* value) return false; } - *value = FastRead8(FixAddr(addr)); + *value = std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr))); + return true; } @@ -139,7 +141,8 @@ bool MemoryBlock::Read16(const u64 addr, u16* value) return false; } - *value = FastRead16(FixAddr(addr)); + se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); + return true; } @@ -151,7 +154,7 @@ bool MemoryBlock::Read32(const u64 addr, u32* value) return false; } - *value = FastRead32(FixAddr(addr)); + se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); return true; } @@ -163,7 +166,7 @@ bool MemoryBlock::Read64(const u64 addr, u64* value) return false; } - *value = FastRead64(FixAddr(addr)); + se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); return true; } @@ -175,7 +178,9 @@ bool MemoryBlock::Read128(const u64 addr, u128* value) return false; } - *value = FastRead128(FixAddr(addr)); + u64 f_addr = FixAddr(addr); + se_t::func(value->lo, std::atomic_load((volatile std::atomic*)GetMem(f_addr))); + se_t::func(value->hi, std::atomic_load((volatile std::atomic*)GetMem(f_addr + 8))); return true; } @@ -212,7 +217,7 @@ bool MemoryBlock::Write8(const u64 addr, const u8 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - FastWrite8(FixAddr(addr), value); + std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), value); return true; } @@ -220,7 +225,9 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - FastWrite16(FixAddr(addr), value); + u16 re_value; + se_t::func(re_value, value); + std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); return true; } @@ -228,7 +235,9 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - FastWrite32(FixAddr(addr), value); + u32 re_value; + se_t::func(re_value, value); + std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); return true; } @@ -236,7 +245,9 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - FastWrite64(FixAddr(addr), value); + u64 re_value; + se_t::func(re_value, value); + std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); return true; } @@ -244,7 +255,12 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - FastWrite128(FixAddr(addr), value); + u64 f_addr = FixAddr(addr); + u64 re_value; + se_t::func(re_value, value.lo); + std::atomic_store((std::atomic*)GetMem(f_addr), re_value); + se_t::func(re_value, value.hi); + std::atomic_store((std::atomic*)GetMem(f_addr + 8), re_value); return true; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 28cb752c7d..461c4440b1 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -13,7 +13,7 @@ class MemoryBase NullMemoryBlock NullMem; public: - ArrayF MemoryBlocks; + std::vector MemoryBlocks; MemoryBlock* UserMemory; DynamicMemoryBlock MainMem; @@ -96,15 +96,15 @@ public: MemoryBlock& GetMemByNum(const u8 num) { - if(num >= MemoryBlocks.GetCount()) return NullMem; - return MemoryBlocks.Get(num); + if(num >= MemoryBlocks.size()) return NullMem; + return *MemoryBlocks[num]; } MemoryBlock& GetMemByAddr(const u64 addr) { - for(uint i=0; iIsMyAddress(addr)) return *MemoryBlocks[i]; } return NullMem; @@ -123,9 +123,9 @@ public: u64 RealToVirtualAddr(const void* addr) { const u64 raddr = (u64)addr; - for(u32 i=0; i= baddr && raddr < baddr + b.GetSize()) @@ -141,7 +141,7 @@ public: { //if(SpuRawMem.GetSize()) return false; - MemoryBlocks.Add(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw)); + MemoryBlocks.push_back(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw)); return true; } @@ -156,27 +156,27 @@ public: switch(type) { case Memory_PS3: - MemoryBlocks.Add(MainMem.SetRange(0x00010000, 0x2FFF0000)); - 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)); - MemoryBlocks.Add(StackMem.SetRange(0xD0000000, 0x10000000)); - //MemoryBlocks.Add(SpuRawMem.SetRange(0xE0000000, 0x10000000)); - //MemoryBlocks.Add(SpuThrMem.SetRange(0xF0000000, 0x10000000)); + MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x2FFF0000)); + MemoryBlocks.push_back(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000)); + MemoryBlocks.push_back(RSXCMDMem.SetRange(0x40000000, 0x10000000)); + MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000)); + MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000)); + MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000)); + //MemoryBlocks.push_back(SpuRawMem.SetRange(0xE0000000, 0x10000000)); + //MemoryBlocks.push_back(SpuThrMem.SetRange(0xF0000000, 0x10000000)); break; case Memory_PSV: - MemoryBlocks.Add(PSVMemory.RAM.SetRange(0x81000000, 0x10000000)); - MemoryBlocks.Add(UserMemory = PSVMemory.Userspace.SetRange(0x91000000, 0x10000000)); + MemoryBlocks.push_back(PSVMemory.RAM.SetRange(0x81000000, 0x10000000)); + MemoryBlocks.push_back(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)); + MemoryBlocks.push_back(PSPMemory.Scratchpad.SetRange(0x00010000, 0x00004000)); + MemoryBlocks.push_back(PSPMemory.VRAM.SetRange(0x04000000, 0x00200000)); + MemoryBlocks.push_back(PSPMemory.RAM.SetRange(0x08000000, 0x02000000)); + MemoryBlocks.push_back(PSPMemory.Kernel.SetRange(0x88000000, 0x00800000)); + MemoryBlocks.push_back(UserMemory = PSPMemory.Userspace.SetRange(0x08800000, 0x01800000)); break; } @@ -185,9 +185,9 @@ public: bool IsGoodAddr(const u64 addr) { - for(uint i=0; iIsMyAddress(addr)) return true; } return false; @@ -195,10 +195,10 @@ public: bool IsGoodAddr(const u64 addr, const u32 size) { - for(uint i=0; iIsMyAddress(addr) && + MemoryBlocks[i]->IsMyAddress(addr + size - 1) ) return true; } return false; @@ -211,12 +211,12 @@ public: ConLog.Write("Closing memory..."); - for(uint i=0; iDelete(); } - MemoryBlocks.ClearF(); + MemoryBlocks.clear(); } void Write8(const u64 addr, const u8 data); @@ -247,9 +247,7 @@ public: return; } - u32 offs = mem.FixAddr(addr); - - for(u32 i=0; i void WriteData(const u64 addr, const T* data) @@ -374,20 +366,21 @@ public: return false; } - MemoryBlocks.Add((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size)); + MemoryBlocks.push_back((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; iIsMirror()) { - if(MemoryBlocks[i].GetStartAddr() == addr) + if(MemoryBlocks[i]->GetStartAddr() == addr) { - MemoryBlocks.RemoveAt(i); + delete MemoryBlocks[i]; + MemoryBlocks.erase(MemoryBlocks.begin() + i); } } } @@ -426,9 +419,9 @@ public: return Memory.IsGoodAddr(m_addr, sizeof(T)); } - __forceinline operator u32() const + __forceinline operator bool() const { - return m_addr; + return m_addr != 0; } __forceinline bool operator != (nullptr_t) const @@ -686,6 +679,33 @@ public: void SetAddr(const u64 addr) { m_addr = addr; } }; +template +struct _func_arg +{ + __forceinline static u64 get_value(const T& arg) + { + return arg; + } +}; + +template +struct _func_arg> +{ + __forceinline static u64 get_value(const mem_base_t& arg) + { + return arg.GetAddr(); + } +}; + +template +struct _func_arg> +{ + __forceinline static u64 get_value(const be_t& arg) + { + return arg.ToLE(); + } +}; + template class mem_func_ptr_t; template @@ -717,7 +737,7 @@ class mem_func_ptr_t : public mem_base_t { Callback cb; cb.SetAddr(m_addr); - cb.Handle(a1); + cb.Handle(_get_func_arg(a1)); cb.Branch(!is_async); } @@ -740,7 +760,7 @@ class mem_func_ptr_t : public mem_base_t { Callback cb; cb.SetAddr(m_addr); - cb.Handle(a1, a2); + cb.Handle(_func_arg::get_value(a1), _func_arg::get_value(a2)); cb.Branch(!is_async); } @@ -763,7 +783,7 @@ class mem_func_ptr_t : public mem_base_t { Callback cb; cb.SetAddr(m_addr); - cb.Handle(a1, a2, a3); + cb.Handle(_func_arg::get_value(a1), _func_arg::get_value(a2), _func_arg::get_value(a3)); cb.Branch(!is_async); } @@ -786,7 +806,7 @@ class mem_func_ptr_t : public mem_base_t { Callback cb; cb.SetAddr(m_addr); - cb.Handle(a1, a2, a3, a4); + cb.Handle(_func_arg::get_value(a1), _func_arg::get_value(a2), _func_arg::get_value(a3), _func_arg::get_value(a4)); cb.Branch(!is_async); } @@ -802,7 +822,6 @@ public: } }; - template class MemoryAllocator { diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 6fe1cb5255..b31c396a9a 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -442,28 +442,12 @@ void Module::Error(wxString fmt, ...) va_end(list); } -bool Module::CheckId(u32 id) const +bool Module::CheckID(u32 id) const { - return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName()); + return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetID(id).m_name.Cmp(GetName()); } -bool Module::CheckId(u32 id, ID& _id) const +bool Module::CheckID(u32 id, ID*& _id) const { - return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName()); -} - -template bool Module::CheckId(u32 id, T*& data) -{ - ID id_data; - - if(!CheckId(id, id_data)) return false; - - data = (T*)id_data.m_data; - - return true; -} - -u32 Module::GetNewId(void* data, u8 flags) -{ - return Emu.GetIdManager().GetNewID(GetName(), data, flags); + return Emu.GetIdManager().CheckID(id) && !(_id = &Emu.GetIdManager().GetID(id))->m_name.Cmp(GetName()); } diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 1c72a92117..5b8a497d35 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -1,5 +1,8 @@ #pragma once #include "Modules/cellResc.h" +#include "Modules/cellPngDec.h" +#include "Modules/cellJpgDec.h" +#include "Modules/cellGifDec.h" #define declCPU PPUThread& CPU = GetCurrentPPUThread @@ -59,13 +62,24 @@ public: void Error(const u32 id, wxString fmt, ...); void Error(wxString fmt, ...); - bool CheckId(u32 id) const; + bool CheckID(u32 id) const; + template bool CheckId(u32 id, T*& data) + { + ID* id_data; - bool CheckId(u32 id, ID& _id) const; + if(!CheckID(id, id_data)) return false; - template bool CheckId(u32 id, T*& data); + data = id_data->m_data->get(); - u32 GetNewId(void* data = nullptr, u8 flags = 0); + return true; + } + bool CheckID(u32 id, ID*& _id) const; + + template + u32 GetNewId(T* data, u8 flags = 0) + { + return Emu.GetIdManager().GetNewID(GetName(), data, flags); + } template __forceinline void AddFunc(u32 id, T func); }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 02a3e2958b..bd71d2d0d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -81,7 +81,7 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) InitOffsetTable(); Memory.RSXCMDMem.Alloc(cmdSize); - Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase + Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase cellGcmMapEaIoAddress(ioAddress, ioSize, 0); u32 ctx_begin = ioAddress/* + 0x1000*/; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index d54629e80a..106725a816 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include "cellGifDec.h" #include "stblib/stb_image.h" #include "stblib/stb_image.c" // (TODO: Should we put this elsewhere?) @@ -8,118 +9,6 @@ void cellGifDec_init(); Module cellGifDec(0xf010, cellGifDec_init); -//Return Codes -enum -{ - CELL_GIFDEC_ERROR_OPEN_FILE = 0x80611300, - CELL_GIFDEC_ERROR_STREAM_FORMAT = 0x80611301, - CELL_GIFDEC_ERROR_SEQ = 0x80611302, - CELL_GIFDEC_ERROR_ARG = 0x80611303, - CELL_GIFDEC_ERROR_FATAL = 0x80611304, - CELL_GIFDEC_ERROR_SPU_UNSUPPORT = 0x80611305, - CELL_GIFDEC_ERROR_SPU_ERROR = 0x80611306, - CELL_GIFDEC_ERROR_CB_PARAM = 0x80611307, -}; - -enum CellGifDecStreamSrcSel -{ - CELL_GIFDEC_FILE = 0, //Input from a file - CELL_GIFDEC_BUFFER = 1, //Input from a buffer -}; - -enum CellGifDecColorSpace -{ - CELL_GIFDEC_RGBA = 10, - CELL_GIFDEC_ARGB = 20, -}; - -enum CellGifDecRecordType -{ - CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC = 1, // Image data block - CELL_GIFDEC_RECORD_TYPE_EXTENSION = 2, // Extension block - CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block -}; - -enum CellGifDecDecodeStatus -{ - CELL_GIFDEC_DEC_STATUS_FINISH = 0, //Decoding finished - CELL_GIFDEC_DEC_STATUS_STOP = 1, //Decoding halted -}; - -struct CellGifDecInfo -{ - be_t SWidth; - be_t SHeight; - be_t SGlobalColorTableFlag; - be_t SColorResolution; - be_t SSortFlag; - be_t SSizeOfGlobalColorTable; - be_t SBackGroundColor; - be_t SPixelAspectRatio; -}; - -struct CellGifDecSrc -{ - be_t srcSelect; - be_t fileName; - be_t fileOffset; - be_t fileSize; - be_t streamPtr; - be_t streamSize; - be_t spuThreadEnable; -}; - -struct CellGifDecInParam -{ - be_t commandPtr; - be_t colorSpace; // CellGifDecColorSpace - be_t outputColorAlpha1; - be_t outputColorAlpha2; - be_t reserved[2]; -}; - -struct CellGifDecOutParam -{ - be_t outputWidthByte; - be_t outputWidth; - be_t outputHeight; - be_t outputComponents; - be_t outputBitDepth; - be_t outputColorSpace; // CellGifDecColorSpace - be_t useMemorySpace; -}; - -struct CellGifDecExtension -{ - be_t label; - be_t data; -}; - -struct CellGifDecDataOutInfo -{ - be_t recordType; - CellGifDecExtension outExtension; - be_t status; -}; - -struct CellGifDecOpnInfo -{ - be_t initSpaceAllocated; -}; - -struct CellGifDecDataCtrlParam -{ - be_t outputBytesPerLine; -}; - -struct CellGifDecSubHandle //Custom struct -{ - u32 fd; - u64 fileSize; - CellGifDecInfo info; - CellGifDecOutParam outParam; -}; - int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellGifDec); @@ -184,12 +73,10 @@ int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, const mem_ptr_t info) { - ID sub_handle_id_data; - if(!cellGifDec.CheckId(subHandle, sub_handle_id_data)) + CellGifDecSubHandle* subHandle_data; + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; - auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data; - const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; CellGifDecInfo& current_info = subHandle_data->info; @@ -224,12 +111,10 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t inParam, mem_ptr_t outParam) { - ID sub_handle_id_data; - if(!cellGifDec.CheckId(subHandle, sub_handle_id_data)) + CellGifDecSubHandle* subHandle_data; + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; - auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data; - CellGifDecInfo& current_info = subHandle_data->info; CellGifDecOutParam& current_outParam = subHandle_data->outParam; @@ -255,12 +140,10 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m { dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP; - ID sub_handle_id_data; - if(!cellGifDec.CheckId(subHandle, sub_handle_id_data)) + CellGifDecSubHandle* subHandle_data; + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; - auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data; - const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; const CellGifDecOutParam& current_outParam = subHandle_data->outParam; @@ -306,12 +189,10 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m int cellGifDecClose(u32 mainHandle, u32 subHandle) { - ID sub_handle_id_data; - if(!cellGifDec.CheckId(subHandle, sub_handle_id_data)) + CellGifDecSubHandle* subHandle_data; + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; - auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data; - cellFsClose(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.h b/rpcs3/Emu/SysCalls/Modules/cellGifDec.h new file mode 100644 index 0000000000..48e36656ff --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.h @@ -0,0 +1,114 @@ +#pragma once + + +//Return Codes +enum +{ + CELL_GIFDEC_ERROR_OPEN_FILE = 0x80611300, + CELL_GIFDEC_ERROR_STREAM_FORMAT = 0x80611301, + CELL_GIFDEC_ERROR_SEQ = 0x80611302, + CELL_GIFDEC_ERROR_ARG = 0x80611303, + CELL_GIFDEC_ERROR_FATAL = 0x80611304, + CELL_GIFDEC_ERROR_SPU_UNSUPPORT = 0x80611305, + CELL_GIFDEC_ERROR_SPU_ERROR = 0x80611306, + CELL_GIFDEC_ERROR_CB_PARAM = 0x80611307, +}; + +enum CellGifDecStreamSrcSel +{ + CELL_GIFDEC_FILE = 0, //Input from a file + CELL_GIFDEC_BUFFER = 1, //Input from a buffer +}; + +enum CellGifDecColorSpace +{ + CELL_GIFDEC_RGBA = 10, + CELL_GIFDEC_ARGB = 20, +}; + +enum CellGifDecRecordType +{ + CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC = 1, // Image data block + CELL_GIFDEC_RECORD_TYPE_EXTENSION = 2, // Extension block + CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block +}; + +enum CellGifDecDecodeStatus +{ + CELL_GIFDEC_DEC_STATUS_FINISH = 0, //Decoding finished + CELL_GIFDEC_DEC_STATUS_STOP = 1, //Decoding halted +}; + +struct CellGifDecInfo +{ + be_t SWidth; + be_t SHeight; + be_t SGlobalColorTableFlag; + be_t SColorResolution; + be_t SSortFlag; + be_t SSizeOfGlobalColorTable; + be_t SBackGroundColor; + be_t SPixelAspectRatio; +}; + +struct CellGifDecSrc +{ + be_t srcSelect; + be_t fileName; + be_t fileOffset; + be_t fileSize; + be_t streamPtr; + be_t streamSize; + be_t spuThreadEnable; +}; + +struct CellGifDecInParam +{ + be_t commandPtr; + be_t colorSpace; // CellGifDecColorSpace + be_t outputColorAlpha1; + be_t outputColorAlpha2; + be_t reserved[2]; +}; + +struct CellGifDecOutParam +{ + be_t outputWidthByte; + be_t outputWidth; + be_t outputHeight; + be_t outputComponents; + be_t outputBitDepth; + be_t outputColorSpace; // CellGifDecColorSpace + be_t useMemorySpace; +}; + +struct CellGifDecExtension +{ + be_t label; + be_t data; +}; + +struct CellGifDecDataOutInfo +{ + be_t recordType; + CellGifDecExtension outExtension; + be_t status; +}; + +struct CellGifDecOpnInfo +{ + be_t initSpaceAllocated; +}; + +struct CellGifDecDataCtrlParam +{ + be_t outputBytesPerLine; +}; + +struct CellGifDecSubHandle //Custom struct +{ + u32 fd; + u64 fileSize; + CellGifDecInfo info; + CellGifDecOutParam outParam; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 13b478810a..3b78ca94da 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -1,113 +1,12 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" - +#include "cellJpgDec.h" #include "stblib/stb_image.h" void cellJpgDec_init(); Module cellJpgDec(0x000f, cellJpgDec_init); -//Return Codes -enum -{ - CELL_JPGDEC_ERROR_HEADER = 0x80611101, - CELL_JPGDEC_ERROR_STREAM_FORMAT = 0x80611102, - CELL_JPGDEC_ERROR_ARG = 0x80611103, - CELL_JPGDEC_ERROR_SEQ = 0x80611104, - CELL_JPGDEC_ERROR_BUSY = 0x80611105, - CELL_JPGDEC_ERROR_FATAL = 0x80611106, - CELL_JPGDEC_ERROR_OPEN_FILE = 0x80611107, - CELL_JPGDEC_ERROR_SPU_UNSUPPORT = 0x80611108, - CELL_JPGDEC_ERROR_CB_PARAM = 0x80611109, -}; - -enum CellJpgDecColorSpace -{ - CELL_JPG_UNKNOWN = 0, - CELL_JPG_GRAYSCALE = 1, - CELL_JPG_RGB = 2, - CELL_JPG_YCbCr = 3, - CELL_JPG_RGBA = 10, - CELL_JPG_UPSAMPLE_ONLY = 11, - CELL_JPG_ARGB = 20, - CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA = 40, - CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41, -}; - -enum CellJpgDecDecodeStatus -{ - CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished - CELL_JPGDEC_DEC_STATUS_STOP = 1, //Decoding halted -}; - -struct CellJpgDecInfo -{ - be_t imageWidth; - be_t imageHeight; - be_t numComponents; - be_t colorSpace; // CellJpgDecColorSpace -}; - -struct CellJpgDecSrc -{ - be_t srcSelect; // CellJpgDecStreamSrcSel - be_t fileName; // const char* - be_t fileOffset; // int64_t - be_t fileSize; - be_t streamPtr; - be_t streamSize; - be_t spuThreadEnable; // CellJpgDecSpuThreadEna -}; - -struct CellJpgDecInParam -{ - be_t commandPtr; - be_t downScale; - be_t method; // CellJpgDecMethod - be_t outputMode; // CellJpgDecOutputMode - be_t outputColorSpace; // CellJpgDecColorSpace - be_t outputColorAlpha; - be_t reserved[3]; -}; - -struct CellJpgDecOutParam -{ - be_t outputWidthByte; - be_t outputWidth; - be_t outputHeight; - be_t outputComponents; - be_t outputMode; // CellJpgDecOutputMode - be_t outputColorSpace; // CellJpgDecColorSpace - be_t downScale; - be_t useMemorySpace; -}; - -struct CellJpgDecOpnInfo -{ - be_t initSpaceAllocated; -}; - -struct CellJpgDecDataCtrlParam -{ - be_t outputBytesPerLine; -}; - -struct CellJpgDecDataOutInfo -{ - be_t mean; - be_t outputLines; - be_t status; -}; - - -struct CellJpgDecSubHandle //Custom struct -{ - u32 fd; - u64 fileSize; - CellJpgDecInfo info; - CellJpgDecOutParam outParam; -}; - int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellJpgDec); @@ -153,12 +52,10 @@ int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t s int cellJpgDecClose(u32 mainHandle, u32 subHandle) { - ID sub_handle_id_data; - if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data)) + CellJpgDecSubHandle* subHandle_data; + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; - auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data; - cellFsClose(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); @@ -168,12 +65,10 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle) int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t info) { cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); - ID sub_handle_id_data; - if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data)) + CellJpgDecSubHandle* subHandle_data; + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; - auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data; - const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; CellJpgDecInfo& current_info = subHandle_data->info; @@ -227,12 +122,10 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t dataCtrlParam, mem_ptr_t dataOutInfo) { dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP; - ID sub_handle_id_data; - if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data)) + CellJpgDecSubHandle* subHandle_data; + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; - auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data; - const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; const CellJpgDecOutParam& current_outParam = subHandle_data->outParam; @@ -292,12 +185,10 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t inParam, mem_ptr_t outParam) { - ID sub_handle_id_data; - if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data)) + CellJpgDecSubHandle* subHandle_data; + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; - auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data; - CellJpgDecInfo& current_info = subHandle_data->info; CellJpgDecOutParam& current_outParam = subHandle_data->outParam; diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h new file mode 100644 index 0000000000..6a6c5a8c13 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.h @@ -0,0 +1,101 @@ +#pragma once + +//Return Codes +enum +{ + CELL_JPGDEC_ERROR_HEADER = 0x80611101, + CELL_JPGDEC_ERROR_STREAM_FORMAT = 0x80611102, + CELL_JPGDEC_ERROR_ARG = 0x80611103, + CELL_JPGDEC_ERROR_SEQ = 0x80611104, + CELL_JPGDEC_ERROR_BUSY = 0x80611105, + CELL_JPGDEC_ERROR_FATAL = 0x80611106, + CELL_JPGDEC_ERROR_OPEN_FILE = 0x80611107, + CELL_JPGDEC_ERROR_SPU_UNSUPPORT = 0x80611108, + CELL_JPGDEC_ERROR_CB_PARAM = 0x80611109, +}; + +enum CellJpgDecColorSpace +{ + CELL_JPG_UNKNOWN = 0, + CELL_JPG_GRAYSCALE = 1, + CELL_JPG_RGB = 2, + CELL_JPG_YCbCr = 3, + CELL_JPG_RGBA = 10, + CELL_JPG_UPSAMPLE_ONLY = 11, + CELL_JPG_ARGB = 20, + CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA = 40, + CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41, +}; + +enum CellJpgDecDecodeStatus +{ + CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished + CELL_JPGDEC_DEC_STATUS_STOP = 1, //Decoding halted +}; + +struct CellJpgDecInfo +{ + be_t imageWidth; + be_t imageHeight; + be_t numComponents; + be_t colorSpace; // CellJpgDecColorSpace +}; + +struct CellJpgDecSrc +{ + be_t srcSelect; // CellJpgDecStreamSrcSel + be_t fileName; // const char* + be_t fileOffset; // int64_t + be_t fileSize; + be_t streamPtr; + be_t streamSize; + be_t spuThreadEnable; // CellJpgDecSpuThreadEna +}; + +struct CellJpgDecInParam +{ + be_t commandPtr; + be_t downScale; + be_t method; // CellJpgDecMethod + be_t outputMode; // CellJpgDecOutputMode + be_t outputColorSpace; // CellJpgDecColorSpace + be_t outputColorAlpha; + be_t reserved[3]; +}; + +struct CellJpgDecOutParam +{ + be_t outputWidthByte; + be_t outputWidth; + be_t outputHeight; + be_t outputComponents; + be_t outputMode; // CellJpgDecOutputMode + be_t outputColorSpace; // CellJpgDecColorSpace + be_t downScale; + be_t useMemorySpace; +}; + +struct CellJpgDecOpnInfo +{ + be_t initSpaceAllocated; +}; + +struct CellJpgDecDataCtrlParam +{ + be_t outputBytesPerLine; +}; + +struct CellJpgDecDataOutInfo +{ + be_t mean; + be_t outputLines; + be_t status; +}; + +struct CellJpgDecSubHandle //Custom struct +{ + u32 fd; + u64 fileSize; + CellJpgDecInfo info; + CellJpgDecOutParam outParam; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index c33cf97d30..71bf06d477 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -1,116 +1,12 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" - +#include "cellPngDec.h" #include "stblib/stb_image.h" void cellPngDec_init(); Module cellPngDec(0x0018, cellPngDec_init); -//Return Codes -enum -{ - CELL_PNGDEC_ERROR_HEADER = 0x80611201, - CELL_PNGDEC_ERROR_STREAM_FORMAT = 0x80611202, - CELL_PNGDEC_ERROR_ARG = 0x80611203, - CELL_PNGDEC_ERROR_SEQ = 0x80611204, - CELL_PNGDEC_ERROR_BUSY = 0x80611205, - CELL_PNGDEC_ERROR_FATAL = 0x80611206, - CELL_PNGDEC_ERROR_OPEN_FILE = 0x80611207, - CELL_PNGDEC_ERROR_SPU_UNSUPPORT = 0x80611208, - CELL_PNGDEC_ERROR_SPU_ERROR = 0x80611209, - CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a, -}; - -enum CellPngDecColorSpace -{ - CELL_PNGDEC_GRAYSCALE = 1, - CELL_PNGDEC_RGB = 2, - CELL_PNGDEC_PALETTE = 4, - CELL_PNGDEC_GRAYSCALE_ALPHA = 9, - CELL_PNGDEC_RGBA = 10, - CELL_PNGDEC_ARGB = 20, -}; - -enum CellPngDecDecodeStatus -{ - CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished - CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted -}; - -enum CellPngDecStreamSrcSel -{ - CELL_PNGDEC_FILE = 0, - CELL_PNGDEC_BUFFER = 1 -}; - -struct CellPngDecDataOutInfo -{ - be_t chunkInformation; - be_t numText; - be_t numUnknownChunk; - be_t status; -}; - -struct CellPngDecDataCtrlParam -{ - be_t outputBytesPerLine; -}; - -struct CellPngDecInfo -{ - be_t imageWidth; - be_t imageHeight; - be_t numComponents; - be_t colorSpace; // CellPngDecColorSpace - be_t bitDepth; - be_t interlaceMethod; // CellPngDecInterlaceMode - be_t chunkInformation; -}; - -struct CellPngDecSrc -{ - be_t srcSelect; // CellPngDecStreamSrcSel - be_t fileName; // const char* - be_t fileOffset; // int64_t - be_t fileSize; - be_t streamPtr; - be_t streamSize; - be_t spuThreadEnable; // CellPngDecSpuThreadEna -}; - -struct CellPngDecInParam -{ - be_t commandPtr; - be_t outputMode; // CellPngDecOutputMode - be_t outputColorSpace; // CellPngDecColorSpace - be_t outputBitDepth; - be_t outputPackFlag; // CellPngDecPackFlag - be_t outputAlphaSelect; // CellPngDecAlphaSelect - be_t outputColorAlpha; -}; - -struct CellPngDecOutParam -{ - be_t outputWidthByte; - be_t outputWidth; - be_t outputHeight; - be_t outputComponents; - be_t outputBitDepth; - be_t outputMode; // CellPngDecOutputMode - be_t outputColorSpace; // CellPngDecColorSpace - be_t useMemorySpace; -}; - -struct CellPngDecSubHandle //Custom struct -{ - u32 fd; - u64 fileSize; - CellPngDecInfo info; - CellPngDecOutParam outParam; - CellPngDecSrc src; -}; - int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellPngDec); @@ -164,12 +60,10 @@ int cellPngDecClose(u32 mainHandle, u32 subHandle) { cellPngDec.Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle); - ID sub_handle_id_data; - if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) + CellPngDecSubHandle* subHandle_data; + if(!cellPngDec.CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; - auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; - cellFsClose(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); @@ -179,12 +73,10 @@ int cellPngDecClose(u32 mainHandle, u32 subHandle) int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t info) { cellPngDec.Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); - ID sub_handle_id_data; - if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) + CellPngDecSubHandle* subHandle_data; + if(!cellPngDec.CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; - auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; - const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; CellPngDecInfo& current_info = subHandle_data->info; @@ -238,12 +130,10 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t dataCtrlParam, mem_ptr_t dataOutInfo) { dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP; - ID sub_handle_id_data; - if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) + CellPngDecSubHandle* subHandle_data; + if(!cellPngDec.CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; - auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; - const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; const CellPngDecOutParam& current_outParam = subHandle_data->outParam; @@ -306,12 +196,10 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t inParam, mem_ptr_t outParam) { - ID sub_handle_id_data; - if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) + CellPngDecSubHandle* subHandle_data; + if(!cellPngDec.CheckId(subHandle, subHandle_data)) return CELL_PNGDEC_ERROR_FATAL; - auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data; - CellPngDecInfo& current_info = subHandle_data->info; CellPngDecOutParam& current_outParam = subHandle_data->outParam; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h new file mode 100644 index 0000000000..68a5d4113f --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -0,0 +1,105 @@ +#pragma once + +//Return Codes +enum +{ + CELL_PNGDEC_ERROR_HEADER = 0x80611201, + CELL_PNGDEC_ERROR_STREAM_FORMAT = 0x80611202, + CELL_PNGDEC_ERROR_ARG = 0x80611203, + CELL_PNGDEC_ERROR_SEQ = 0x80611204, + CELL_PNGDEC_ERROR_BUSY = 0x80611205, + CELL_PNGDEC_ERROR_FATAL = 0x80611206, + CELL_PNGDEC_ERROR_OPEN_FILE = 0x80611207, + CELL_PNGDEC_ERROR_SPU_UNSUPPORT = 0x80611208, + CELL_PNGDEC_ERROR_SPU_ERROR = 0x80611209, + CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a, +}; + +enum CellPngDecColorSpace +{ + CELL_PNGDEC_GRAYSCALE = 1, + CELL_PNGDEC_RGB = 2, + CELL_PNGDEC_PALETTE = 4, + CELL_PNGDEC_GRAYSCALE_ALPHA = 9, + CELL_PNGDEC_RGBA = 10, + CELL_PNGDEC_ARGB = 20, +}; + +enum CellPngDecDecodeStatus +{ + CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished + CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted +}; + +enum CellPngDecStreamSrcSel +{ + CELL_PNGDEC_FILE = 0, + CELL_PNGDEC_BUFFER = 1, +}; + +struct CellPngDecDataOutInfo +{ + be_t chunkInformation; + be_t numText; + be_t numUnknownChunk; + be_t status; +}; + +struct CellPngDecDataCtrlParam +{ + be_t outputBytesPerLine; +}; + +struct CellPngDecInfo +{ + be_t imageWidth; + be_t imageHeight; + be_t numComponents; + be_t colorSpace; // CellPngDecColorSpace + be_t bitDepth; + be_t interlaceMethod; // CellPngDecInterlaceMode + be_t chunkInformation; +}; + +struct CellPngDecSrc +{ + be_t srcSelect; // CellPngDecStreamSrcSel + be_t fileName; // const char* + be_t fileOffset; // int64_t + be_t fileSize; + be_t streamPtr; + be_t streamSize; + be_t spuThreadEnable; // CellPngDecSpuThreadEna +}; + +struct CellPngDecInParam +{ + be_t commandPtr; + be_t outputMode; // CellPngDecOutputMode + be_t outputColorSpace; // CellPngDecColorSpace + be_t outputBitDepth; + be_t outputPackFlag; // CellPngDecPackFlag + be_t outputAlphaSelect; // CellPngDecAlphaSelect + be_t outputColorAlpha; +}; + +struct CellPngDecOutParam +{ + be_t outputWidthByte; + be_t outputWidth; + be_t outputHeight; + be_t outputComponents; + be_t outputBitDepth; + be_t outputMode; // CellPngDecOutputMode + be_t outputColorSpace; // CellPngDecColorSpace + be_t useMemorySpace; +}; + +struct CellPngDecSubHandle //Custom struct +{ + u32 fd; + u64 fileSize; + CellPngDecInfo info; + CellPngDecOutParam outParam; + CellPngDecSrc src; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index cf4b158db2..cd0d747ba3 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -3,10 +3,9 @@ #include "Emu/SysCalls/SC_FUNC.h" void sys_fs_init(); -void sys_fs_unload(); -Module sys_fs(0x000e, sys_fs_init, nullptr, sys_fs_unload); +Module sys_fs(0x000e, sys_fs_init); + std::atomic g_FsAioReadID = 0; -Array FDs; bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) { @@ -138,10 +137,12 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_OK; } -void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_t func) +void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { - vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd]; - const wxString path = orig_file.GetPath().AfterFirst('/'); + vfsFileBase* orig_file; + if(!sys_fs.CheckId(fd, orig_file)) return; + + const wxString path = orig_file->GetPath().AfterFirst('/'); u64 nbytes = (u64)aio->size; const u32 buf_addr = (u32)aio->buf_addr; @@ -171,22 +172,18 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_toffset, buf_addr, (u64)aio->size, res, xid, path.c_str()); } -int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t func) +int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { sys_fs.Warning("cellFsAioRead(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.GetAddr(), aio_id.GetAddr(), func.GetAddr()); - //ID id; - u32 fd = (u32)aio->fd; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; - vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd]; + vfsFileBase* orig_file; + u32 fd = aio->fd; + if(!sys_fs.CheckId(fd, orig_file)) return CELL_ESRCH; //get a unique id for the callback const u32 xid = g_FsAioReadID++; @@ -202,13 +199,13 @@ int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_tClose(); - delete FDs[i]; - } - } - FDs.Clear(); -} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 0342c60861..21885708cc 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -5,6 +5,8 @@ #include "lv2/SC_Timer.h" #include "lv2/SC_Rwlock.h" #include "lv2/SC_SPU_Thread.h" +#include "Emu/event.h" + //#define SYSCALLS_DEBUG #define declCPU PPUThread& CPU = GetCurrentPPUThread @@ -86,28 +88,29 @@ public: bool CheckId(u32 id) const { - return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName()); - } - - bool CheckId(u32 id, ID& _id) const - { - return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName()); + return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetID(id).m_name.Cmp(GetName()); } template bool CheckId(u32 id, T*& data) { - ID id_data; + ID* id_data; if(!CheckId(id, id_data)) return false; - data = (T*)id_data.m_data; + data = id_data->m_data->get(); return true; } - u32 GetNewId(void* data = nullptr, u8 flags = 0) + template<> bool CheckId(u32 id, ID*& _id) { - return Emu.GetIdManager().GetNewID(GetName(), data, flags); + return Emu.GetIdManager().CheckID(id) && !(_id = &Emu.GetIdManager().GetID(id))->m_name.Cmp(GetName()); + } + + template + u32 GetNewId(T* data, u8 flags = 0) + { + return Emu.GetIdManager().GetNewID(GetName(), data, flags); } }; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index f423c778fa..1f1461b86c 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -150,7 +150,8 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout) return false; } - EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data; + EventQueue* equeue; + Emu.GetIdManager().GetIDData(equeue_id, equeue); for(int i=0; ipos; ++i) { if(!equeue->ports[i]->has_data && equeue->ports[i]->thread) @@ -225,8 +226,10 @@ int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id) return CELL_ESRCH; } - EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data; - EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(event_queue_id).m_data; + EventPort* eport; + EventQueue* equeue; + Emu.GetIdManager().GetIDData(event_port_id, eport); + Emu.GetIdManager().GetIDData(event_queue_id, equeue); equeue->ports[equeue->pos++] = eport; eport->queue[eport->pos++] = equeue; @@ -243,7 +246,8 @@ int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3) return CELL_ESRCH; } - EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data; + EventPort* eport; + Emu.GetIdManager().GetIDData(event_port_id, eport); if(!eport->pos) { diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 01e6e8a8b3..480264c8bd 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -3,7 +3,6 @@ #include "Emu/SysCalls/SysCalls.h" extern Module sys_fs; -extern Array FDs; int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) { @@ -95,8 +94,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_ENOENT; } - fd = FDs.AddCpy(stream); - //fd = sys_fs.GetNewId(stream, flags); + fd = sys_fs.GetNewId(stream, flags); ConLog.Warning("*** cellFsOpen(path: %s): fd=%d", path.mb_str(), fd.GetValue()); return CELL_OK; @@ -106,12 +104,8 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread) { sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)", fd, buf_addr, nbytes, nread.GetAddr()); - //ID id; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsStream& file = *(vfsStream*)id.m_data; - vfsStream& file = *(vfsStream*)FDs[fd]; + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) { @@ -119,7 +113,7 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread) nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); } - const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; + const u64 res = nbytes ? file->Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; if(nread.IsGood()) nread = res; @@ -131,12 +125,8 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite) { sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)", fd, buf_addr, nbytes, nwrite.GetAddr()); - //ID id; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsStream& file = *(vfsStream*)id.m_data; - vfsStream& file = *(vfsStream*)FDs[fd]; + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) { @@ -144,7 +134,7 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite) nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); } - const u64 res = nbytes ? file.Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; + const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; if(nwrite.IsGood()) nwrite = res; @@ -155,16 +145,10 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite) int cellFsClose(u32 fd) { sys_fs.Warning("cellFsClose(fd: %d)", fd); - //ID id; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsStream& file = *(vfsStream*)id.m_data; - vfsStream& file = *(vfsStream*)FDs[fd]; - file.Close(); - delete FDs[fd]; - //Emu.GetIdManager().RemoveID(fd); - FDs[fd] = nullptr; + + if(!Emu.GetIdManager().RemoveID(fd)) + return CELL_ESRCH; + return CELL_OK; } @@ -246,12 +230,9 @@ int cellFsStat(const u32 path_addr, mem_ptr_t sb) int cellFsFstat(u32 fd, mem_ptr_t sb) { sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr()); - //ID id; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsStream& file = *(vfsStream*)id.m_data; - vfsStream& file = *(vfsStream*)FDs[fd]; + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; sb->st_mode = CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | @@ -264,7 +245,7 @@ int cellFsFstat(u32 fd, mem_ptr_t sb) sb->st_atime_ = 0; //TODO sb->st_mtime_ = 0; //TODO sb->st_ctime_ = 0; //TODO - sb->st_size = file.GetSize(); + sb->st_size = file->GetSize(); sb->st_blksize = 4096; return CELL_OK; @@ -330,35 +311,28 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos) sys_fs.Error(fd, "Unknown seek whence! (%d)", whence); return CELL_EINVAL; } - //ID id; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsStream& file = *(vfsStream*)id.m_data; - vfsStream& file = *(vfsStream*)FDs[fd]; - pos = file.Seek(offset, seek_mode); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + pos = file->Seek(offset, seek_mode); return CELL_OK; } int cellFsFtruncate(u32 fd, u64 size) { sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size); - //ID id; - //if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; - if (fd >= FDs.GetCount()) return CELL_ESRCH; - if (FDs[fd] == nullptr) return CELL_ESRCH; - //vfsStream& file = *(vfsStream*)id.m_data; - vfsStream& file = *(vfsStream*)FDs[fd]; - u64 initialSize = file.GetSize(); + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + u64 initialSize = file->GetSize(); if (initialSize < size) { - u64 last_pos = file.Tell(); - file.Seek(0, vfsSeekEnd); + u64 last_pos = file->Tell(); + file->Seek(0, vfsSeekEnd); static const char nullbyte = 0; - file.Seek(size-initialSize-1, vfsSeekCur); - file.Write(&nullbyte, sizeof(char)); - file.Seek(last_pos, vfsSeekSet); + file->Seek(size-initialSize-1, vfsSeekCur); + file->Write(&nullbyte, sizeof(char)); + file->Seek(last_pos, vfsSeekSet); } if (initialSize > size) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Heap.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Heap.cpp index d415ad86e8..ff80ed4700 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Heap.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Heap.cpp @@ -20,16 +20,15 @@ struct HeapInfo int sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size) { sc_heap.Warning("sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); - return Emu.GetIdManager().GetNewID(sc_heap.GetName(), new HeapInfo(heap_addr, align, size)); + return sc_heap.GetNewId(new HeapInfo(heap_addr, align, size)); } int sys_heap_malloc(const u32 heap_id, const u32 size) { sc_heap.Warning("sys_heap_malloc(heap_id=0x%x, size=0x%x)", heap_id, size); - if(!Emu.GetIdManager().CheckID(heap_id)) return CELL_ESRCH; - const ID& id = Emu.GetIdManager().GetIDData(heap_id); - if(!!id.m_name.Cmp(sc_heap.GetName())) return CELL_ESRCH; - const HeapInfo& heap = *(HeapInfo*)id.m_data; - return Memory.Alloc(size, heap.align); + HeapInfo* heap; + if(!sc_heap.CheckId(heap_id, heap)) return CELL_ESRCH; + + return Memory.Alloc(size, heap->align); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 543e72d975..f79ce5cf7b 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -86,13 +86,12 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< sc_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)", thread.GetAddr(), group, spu_num, img.GetAddr(), attr.GetAddr(), arg.GetAddr()); - if(!Emu.GetIdManager().CheckID(group)) + SpuGroupInfo* group_info; + if(!Emu.GetIdManager().GetIDData(group, group_info)) { return CELL_ESRCH; } - SpuGroupInfo& group_info = *(SpuGroupInfo*)Emu.GetIdManager().GetIDData(group).m_data; - if(!thread.IsGood() || !img.IsGood() || !attr.IsGood() || !attr.IsGood()) { return CELL_EFAULT; @@ -108,7 +107,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< return CELL_EINVAL; } - if(group_info.threads[spu_num]) + if(group_info->threads[spu_num]) { return CELL_EBUSY; } @@ -136,7 +135,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< thread = new_thread.GetId(); - group_info.threads[spu_num] = &new_thread; + group_info->threads[spu_num] = &new_thread; /*ConLog.Write("New SPU Thread:"); ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr); @@ -186,15 +185,18 @@ int sys_spu_thread_group_start(u32 id) return CELL_ESRCH; } - ID& id_data = Emu.GetIdManager().GetIDData(id); - SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data; + SpuGroupInfo* group_info; + if(!Emu.GetIdManager().GetIDData(id, group_info)) + { + return CELL_ESRCH; + } //Emu.Pause(); for(int i=0; ithreads[i]) { - group_info.threads[i]->Exec(); + group_info->threads[i]->Exec(); } } @@ -206,20 +208,18 @@ int sys_spu_thread_group_suspend(u32 id) { sc_spu.Warning("sys_spu_thread_group_suspend(id=0x%x)", id); - if(!Emu.GetIdManager().CheckID(id)) + SpuGroupInfo* group_info; + if(!Emu.GetIdManager().GetIDData(id, group_info)) { return CELL_ESRCH; } - ID& id_data = Emu.GetIdManager().GetIDData(id); - SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data; - //Emu.Pause(); for(int i=0; ithreads[i]) { - group_info.threads[i]->Pause(); + group_info->threads[i]->Pause(); } } @@ -253,15 +253,13 @@ int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status) { sc_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr()); - if(!Emu.GetIdManager().CheckID(id)) + SpuGroupInfo* group_info; + if(!Emu.GetIdManager().GetIDData(id, group_info)) { return CELL_ESRCH; } - ID& id_data = Emu.GetIdManager().GetIDData(id); - SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data; - - if (_InterlockedCompareExchange(&group_info.lock, 1, 0)) //get lock + if (_InterlockedCompareExchange(&group_info->lock, 1, 0)) //get lock { return CELL_EBUSY; } @@ -271,13 +269,13 @@ int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status) for(int i=0; ithreads[i]) { - while (!group_info.threads[i]->IsStopped()) Sleep(1); + while (!group_info->threads[i]->IsStopped()) Sleep(1); } } - _InterlockedExchange(&group_info.lock, 0); //release lock + _InterlockedExchange(&group_info->lock, 0); //release lock return CELL_OK; } @@ -490,7 +488,7 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 id, eq, req, spup_addr); EventQueue* equeue; - if(!Emu.GetIdManager().CheckID(id) || !sys_event.CheckId(eq, equeue)) + if(!sys_event.CheckId(eq, equeue)) { return CELL_ESRCH; } @@ -500,7 +498,11 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 return CELL_EINVAL; } - SpuGroupInfo* group = (SpuGroupInfo*)Emu.GetIdManager().GetIDData(id).m_data; + SpuGroupInfo* group; + if(!Emu.GetIdManager().GetIDData(id, group)) + { + return CELL_ESRCH; + } for(int i=0; iExit(); } -struct state_hdr -{ - u32 magic; - u16 version; - u32 mem_count; - u32 mem_offset; - u32 mem_size; - u32 hle_count; - u32 hle_offset; -}; - -static const u32 state_magic = *(u32*)"R3SS"; -static const u32 state_version = 0x1000; - -void MakeSaveState(wxFile& f) -{ - const ArrayF& mb = Memory.MemoryBlocks; - - state_hdr state; - memset(&state, 0, sizeof(state_hdr)); - - state.magic = state_magic; - state.version = state_version; - state.mem_count = mb.GetCount(); - //state.hle_count = mb.GetCount(); - - state.mem_offset = sizeof(state_hdr) + 4; - - f.Seek(state.mem_offset); - for(u32 i=0; i Date: Sun, 19 Jan 2014 18:05:27 +0200 Subject: [PATCH 04/12] Improved vfsDevice. Minor fixes. --- Utilities/BEType.h | 2 +- rpcs3/Emu/FS/vfsDevice.cpp | 11 ++++++++- rpcs3/Emu/FS/vfsLocalFile.cpp | 29 ++++++++++++++++++++---- rpcs3/Emu/GS/RSXThread.cpp | 6 +++-- rpcs3/Emu/Memory/Memory.h | 6 ++--- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 25 +------------------- rpcs3/rpcs3.cpp | 1 + rpcs3/rpcs3.vcxproj | 2 +- 8 files changed, 46 insertions(+), 36 deletions(-) diff --git a/Utilities/BEType.h b/Utilities/BEType.h index 7f6745b949..cc6a6fed62 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -63,7 +63,7 @@ public: FromBE(value.ToBE()); } - T ToBE() const + const T& ToBE() const { return m_data; } diff --git a/rpcs3/Emu/FS/vfsDevice.cpp b/rpcs3/Emu/FS/vfsDevice.cpp index d7fbc464a1..f9e8af0eeb 100644 --- a/rpcs3/Emu/FS/vfsDevice.cpp +++ b/rpcs3/Emu/FS/vfsDevice.cpp @@ -42,12 +42,18 @@ u32 vfsDevice::CmpPs3Path(const wxString& ps3_path) u32 vfsDevice::CmpLocalPath(const wxString& local_path) { + if(local_path.Len() < m_local_path.Len()) + return 0; + const u32 lim = min(m_local_path.Len(), local_path.Len()); u32 ret = 0; for(u32 i=0; iget); - const u32 put = re(m_ctrl->put); + u32 put, get; + se_t::func(put, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, put)))); + se_t::func(get, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, get)))); + if(put == get || !Emu.IsRunning()) { if(put == get) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 461c4440b1..f8ebb5e112 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -305,12 +305,12 @@ public: if(len) memcpy(wxStringBuffer(ret, len), GetMemFromAddr(addr), len); - return ret; + return wxString(ret, wxConvUTF8); } wxString ReadString(const u64 addr) { - return wxString((const char*)GetMemFromAddr(addr)); + return wxString((const char*)GetMemFromAddr(addr), wxConvUTF8); } void WriteString(const u64 addr, const wxString& str) @@ -737,7 +737,7 @@ class mem_func_ptr_t : public mem_base_t { Callback cb; cb.SetAddr(m_addr); - cb.Handle(_get_func_arg(a1)); + cb.Handle(_func_arg::get_value(a1)); cb.Branch(!is_async); } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 480264c8bd..d78c3bc5c7 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -6,7 +6,7 @@ extern Module sys_fs; int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) { - const wxString& path = wxString(Memory.ReadString(path_addr), wxConvUTF8); + const wxString& path = Memory.ReadString(path_addr); sys_fs.Log("cellFsOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)", path.mb_str(), flags, fd.GetAddr(), arg.GetAddr(), size); @@ -17,29 +17,6 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) if(flags & CELL_O_CREAT) { _oflags &= ~CELL_O_CREAT; - /* - //create path - for(uint p=1;pShow(); m_MainFrame->DoSettings(true); + return true; } diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index b8f4753d1e..a90474b87e 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -131,7 +131,7 @@ false - $(SolutionDir)\Utilities\git-version-gen.cmd + "$(SolutionDir)\Utilities\git-version-gen.cmd" From 5f9bc138980668c5f5583f6898bb362ef67c9375 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 21 Jan 2014 03:34:16 +0400 Subject: [PATCH 05/12] Some bugs fixed --- rpcs3/Emu/FS/vfsDevice.cpp | 4 +- rpcs3/Emu/GS/RSXThread.cpp | 8 ++-- rpcs3/Emu/Memory/Memory.cpp | 87 +++++++++++++++++++++---------------- 3 files changed, 55 insertions(+), 44 deletions(-) diff --git a/rpcs3/Emu/FS/vfsDevice.cpp b/rpcs3/Emu/FS/vfsDevice.cpp index f9e8af0eeb..084269e50d 100644 --- a/rpcs3/Emu/FS/vfsDevice.cpp +++ b/rpcs3/Emu/FS/vfsDevice.cpp @@ -93,8 +93,7 @@ wxString vfsDevice::ErasePath(const wxString& path, u32 start_dir_count, u32 end wxString vfsDevice::GetRoot(const wxString& path) { - return wxFileName(path, wxPATH_UNIX).GetPath(); - /* + //return wxFileName(path, wxPATH_UNIX).GetPath(); if(path.IsEmpty()) return wxEmptyString; u32 first_dir = path.Len() - 1; @@ -119,7 +118,6 @@ wxString vfsDevice::GetRoot(const wxString& path) } return path(0, first_dir + 1); - */ } wxString vfsDevice::GetRootPs3(const wxString& path) diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index de48ee2cf7..78b398f586 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -1452,9 +1452,11 @@ void RSXThread::Task() { wxCriticalSectionLocker lock(m_cs_main); - u32 put, get; - se_t::func(put, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, put)))); - se_t::func(get, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, get)))); + //u32 put, get; + //se_t::func(put, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, put)))); + //se_t::func(get, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, get)))); + const u32 put = re(m_ctrl->put); + const u32 get = re(m_ctrl->get); if(put == get || !Emu.IsRunning()) { diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 99834ef2e9..343bab55c2 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -99,24 +99,28 @@ __forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const __forceinline const u16 MemoryBlock::FastRead16(const u64 addr) const { - return ((u16)FastRead8(addr) << 8) | (u16)FastRead8(addr + 1); + volatile const u16 data = *(u16*)GetMem(addr); + return re(data); } __forceinline const u32 MemoryBlock::FastRead32(const u64 addr) const { - return ((u32)FastRead16(addr) << 16) | (u32)FastRead16(addr + 2); + volatile const u32 data = *(u32*)GetMem(addr); + return re(data); } __forceinline const u64 MemoryBlock::FastRead64(const u64 addr) const { - return ((u64)FastRead32(addr) << 32) | (u64)FastRead32(addr + 4); + volatile const u64 data = *(u64*)GetMem(addr); + return re(data); } __forceinline const u128 MemoryBlock::FastRead128(const u64 addr) { + volatile const u128 data = *(u128*)GetMem(addr); u128 ret; - ret.lo = FastRead64(addr); - ret.hi = FastRead64(addr + 8); + ret.lo = re(data.hi); + ret.hi = re(data.lo); return ret; } @@ -128,8 +132,8 @@ bool MemoryBlock::Read8(const u64 addr, u8* value) return false; } - *value = std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr))); - + //*value = std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr))); + *value = FastRead8(FixAddr(addr)); return true; } @@ -141,8 +145,8 @@ bool MemoryBlock::Read16(const u64 addr, u16* value) return false; } - se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); - + //se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); + *value = FastRead16(FixAddr(addr)); return true; } @@ -154,7 +158,8 @@ bool MemoryBlock::Read32(const u64 addr, u32* value) return false; } - se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); + //se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); + *value = FastRead32(FixAddr(addr)); return true; } @@ -166,7 +171,8 @@ bool MemoryBlock::Read64(const u64 addr, u64* value) return false; } - se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); + //se_t::func(*value, std::atomic_load((volatile std::atomic*)GetMem(FixAddr(addr)))); + *value = FastRead64(FixAddr(addr)); return true; } @@ -178,9 +184,10 @@ bool MemoryBlock::Read128(const u64 addr, u128* value) return false; } - u64 f_addr = FixAddr(addr); - se_t::func(value->lo, std::atomic_load((volatile std::atomic*)GetMem(f_addr))); - se_t::func(value->hi, std::atomic_load((volatile std::atomic*)GetMem(f_addr + 8))); + //u64 f_addr = FixAddr(addr); + //se_t::func(value->lo, std::atomic_load((volatile std::atomic*)GetMem(f_addr))); + //se_t::func(value->hi, std::atomic_load((volatile std::atomic*)GetMem(f_addr + 8))); + *value = FastRead128(FixAddr(addr)); return true; } @@ -191,33 +198,33 @@ __forceinline void MemoryBlock::FastWrite8(const u64 addr, const u8 value) __forceinline void MemoryBlock::FastWrite16(const u64 addr, const u16 value) { - FastWrite8(addr, (u8)(value >> 8)); - FastWrite8(addr+1, (u8)value); + *(u16*)GetMem(addr) = re(value); } __forceinline void MemoryBlock::FastWrite32(const u64 addr, const u32 value) { - FastWrite16(addr, (u16)(value >> 16)); - FastWrite16(addr+2, (u16)value); + *(u32*)GetMem(addr) = re(value); } __forceinline void MemoryBlock::FastWrite64(const u64 addr, const u64 value) { - FastWrite32(addr, (u32)(value >> 32)); - FastWrite32(addr+4, (u32)value); + *(u64*)GetMem(addr) = re(value); } __forceinline void MemoryBlock::FastWrite128(const u64 addr, const u128 value) { - FastWrite64(addr, value.lo); - FastWrite64(addr+8, value.hi); + u128 res; + res.lo = re(value.hi); + res.hi = re(value.lo); + *(u128*)GetMem(addr) = res; } bool MemoryBlock::Write8(const u64 addr, const u8 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), value); + //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), value); + FastWrite8(FixAddr(addr), value); return true; } @@ -225,9 +232,10 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - u16 re_value; - se_t::func(re_value, value); - std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); + //u16 re_value; + //se_t::func(re_value, value); + //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); + FastWrite16(FixAddr(addr), value); return true; } @@ -235,9 +243,10 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - u32 re_value; - se_t::func(re_value, value); - std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); + //u32 re_value; + //se_t::func(re_value, value); + //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); + FastWrite32(FixAddr(addr), value); return true; } @@ -245,9 +254,10 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - u64 re_value; - se_t::func(re_value, value); - std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); + //u64 re_value; + //se_t::func(re_value, value); + //std::atomic_store((std::atomic*)GetMem(FixAddr(addr)), re_value); + FastWrite64(FixAddr(addr), value); return true; } @@ -255,12 +265,13 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value) { if(!IsMyAddress(addr) || IsLocked(addr)) return false; - u64 f_addr = FixAddr(addr); - u64 re_value; - se_t::func(re_value, value.lo); - std::atomic_store((std::atomic*)GetMem(f_addr), re_value); - se_t::func(re_value, value.hi); - std::atomic_store((std::atomic*)GetMem(f_addr + 8), re_value); + //u64 f_addr = FixAddr(addr); + //u64 re_value; + //se_t::func(re_value, value.lo); + //std::atomic_store((std::atomic*)GetMem(f_addr), re_value); + //se_t::func(re_value, value.hi); + //std::atomic_store((std::atomic*)GetMem(f_addr + 8), re_value); + FastWrite128(FixAddr(addr), value); return true; } From 66a481d4bc1f82ade37a3100a74ccddf968774d1 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Tue, 21 Jan 2014 19:55:48 +0200 Subject: [PATCH 06/12] Implement reserved memory in virtual memory block --- rpcs3/Emu/Memory/Memory.cpp | 32 ++++++++++++++++++++++++++++---- rpcs3/Emu/Memory/MemoryBlock.h | 10 ++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 4188cb3170..44b5fa408f 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -516,7 +516,7 @@ VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock() bool VirtualMemoryBlock::IsInMyRange(const u64 addr) { - return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize(); + return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize() - GetResevedAmount(); } bool VirtualMemoryBlock::IsInMyRange(const u64 addr, const u32 size) @@ -549,10 +549,11 @@ u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) } else { - for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - size;) + for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetResevedAmount() - size;) { bool is_good_addr = true; + // check if address is already mapped for(u32 i=0; i= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) || @@ -579,7 +580,7 @@ bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr) { for(u32 i=0; i GetEndAddr() - GetStartAddr()) + return false; + + m_reserve_size += size; + return true; +} + +bool VirtualMemoryBlock::Unreserve(u32 size) +{ + if(size > GetResevedAmount()) + return false; + + m_reserve_size -= size; + return true; +} + +u32 VirtualMemoryBlock::GetResevedAmount() +{ + return m_reserve_size; } \ No newline at end of file diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 793af5ca4d..f9d7c6fefd 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -226,6 +226,7 @@ private: class VirtualMemoryBlock : public MemoryBlock { Array m_mapped_memory; + u32 m_reserve_size; public: VirtualMemoryBlock(); @@ -245,6 +246,15 @@ public: // Unmap address (please specify only starting point, no midway memory will be unmapped) virtual bool UnmapAddress(u64 addr); + // Reserve a certain amount so no one can use it, returns true on succces, false on failure + virtual bool Reserve(u32 size); + + // Unreserve a certain amount of bytes, returns true on succcess, false if size is bigger than the reserved amount + virtual bool Unreserve(u32 size); + + // Return the total amount of reserved memory + virtual u32 GetResevedAmount(); + virtual bool Read8(const u64 addr, u8* value); virtual bool Read16(const u64 addr, u16* value); virtual bool Read32(const u64 addr, u32* value); From 6504ddede45a6f4420c49a5993236000e0c7ec90 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Tue, 21 Jan 2014 20:08:33 +0200 Subject: [PATCH 07/12] fixed some memory mapping functions --- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 145 +++++++++++----------- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 2 +- 2 files changed, 73 insertions(+), 74 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 02a3e2958b..c81f3a911c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -12,9 +12,11 @@ u32 local_addr = NULL; enum { CELL_GCM_ERROR_FAILURE = 0x802100ff, + CELL_GCM_ERROR_NO_IO_PAGE_TABLE = 0x80210001, CELL_GCM_ERROR_INVALID_ENUM = 0x80210002, CELL_GCM_ERROR_INVALID_VALUE = 0x80210003, CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004, + CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005 }; /*------------------------------------------------------------ @@ -28,11 +30,12 @@ struct gcm_offset }; void InitOffsetTable(); -int cellGcmAddressToOffset(u32 address, mem32_t offset); -u32 cellGcmGetMaxIoMapSize(); +int32_t cellGcmAddressToOffset(u64 address, mem32_t offset); +uint32_t cellGcmGetMaxIoMapSize(); void cellGcmGetOffsetTable(mem_ptr_t table); -int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address); -int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size); +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address); +int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size); +int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset); //------------------------------------------------------------ @@ -44,19 +47,6 @@ gcmInfo gcm_info; u32 map_offset_addr = 0; u32 map_offset_pos = 0; -int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset) -{ - cellGcmSys.Warning("cellGcmMapMainMemory(address=0x%x,size=0x%x,offset_addr=0x%x)", address, size, offset.GetAddr()); - if(!offset.IsGood()) return CELL_EFAULT; - - Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; - - offset = address - Emu.GetGSManager().GetRender().m_main_mem_addr; - Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(address, size)); - - return CELL_OK; -} - 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); @@ -82,7 +72,7 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) InitOffsetTable(); Memory.RSXCMDMem.Alloc(cmdSize); Memory.MemoryBlocks.Add(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase - cellGcmMapEaIoAddress(ioAddress, ioSize, 0); + cellGcmMapEaIoAddress(ioAddress, 0, ioSize); u32 ctx_begin = ioAddress/* + 0x1000*/; u32 ctx_size = 0x6ffc; @@ -596,61 +586,43 @@ void InitOffsetTable() } } -int cellGcmAddressToOffset(u32 address, mem32_t offset) +int32_t cellGcmAddressToOffset(u64 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); - } + cellGcmSys.Warning("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr()); - u32 sa; - bool is_main_mem = false; - const auto& main_mem_info = Emu.GetGSManager().GetRender().m_main_mem_info; - for(u32 i=0; i= 0xD0000000/*not on main memory or local*/) + return CELL_GCM_ERROR_FAILURE; + + u32 result; + + // If address is in range of local memory + if(Memory.RSXFBMem.IsInMyRange(address)) { - //main memory - if(address >= main_mem_info[i].addr && address < main_mem_info[i].addr + main_mem_info[i].size) + result = address - Memory.RSXFBMem.GetStartAddr(); + } + // else check if the adress (main memory) is mapped in IO + else + { + u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20)); + + if(upper12Bits != 0xFFFF) { - is_main_mem = true; - break; + result = (((u64)upper12Bits << 20) | (address & (0xFFFFF))); + } + // address is not mapped in IO + else + { + return CELL_GCM_ERROR_FAILURE; } } - 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; - + offset = result; return CELL_OK; } -u32 cellGcmGetMaxIoMapSize() +uint32_t cellGcmGetMaxIoMapSize() { - UNIMPLEMENTED_FUNC(cellGcmSys); - return 0x10000000;//256MB TODO + return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetResevedAmount(); } void cellGcmGetOffsetTable(mem_ptr_t table) @@ -659,7 +631,7 @@ void cellGcmGetOffsetTable(mem_ptr_t table) table->ea = re(offsetTable.ea); } -int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) +int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) { u64 realAddr; @@ -673,7 +645,7 @@ int32_t cellGcmIoOffsetToAddress(u32 ioOffset, mem_ptr_t address) return CELL_OK; } -int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) +int32_t 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); @@ -683,10 +655,10 @@ int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) if(Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io)) { //fill the offset table - for(int i=0; i> 20); i++) { - Memory.Write16(offsetTable.io + ea/(1024*1024) + i, io/(1024*1024) + i); - Memory.Write16(offsetTable.ea + io/(1024*1024) + i, ea/(1024*1024) + i); + Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); } } else @@ -694,20 +666,18 @@ int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size) return CELL_GCM_ERROR_FAILURE; } - //Emu.GetGSManager().GetRender().m_ioAddress = io; - Emu.GetGSManager().GetRender().m_report_main_addr = ea; return CELL_OK; } -int32_t cellGcmMapLocalMemory(mem_ptr_t address, mem_ptr_t size) +int32_t cellGcmMapLocalMemory(u64 address, u64 size) { if(!local_size && !local_addr) { local_size = 0xf900000; //TODO local_addr = Memory.RSXFBMem.GetStartAddr(); Memory.RSXFBMem.Alloc(local_size); - Memory.Write32(address.GetAddr(), local_addr); - Memory.Write32(size.GetAddr(), local_size); + Memory.Write32(address, local_addr); + Memory.Write32(size, local_size); } else { @@ -718,6 +688,35 @@ int32_t cellGcmMapLocalMemory(mem_ptr_t address, mem_ptr_t size return CELL_OK; } +int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) +{ + cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.GetAddr()); + + u64 io; + + if((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; + + //check if the mapping was successfull + if(io = Memory.RSXIOMem.Map(ea, size, 0)) + { + //fill the offset table + for(u32 i=0; i<(size >> 20); i++) + { + Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); + Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); + } + } + else + { + return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; + } + + Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress; + Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(ea, size)); + + return CELL_OK; +} + void cellGcmSys_init() { current_config.ioAddress = NULL; @@ -745,7 +744,6 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile); cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull); cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); - cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory); cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress); cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor); cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition); @@ -777,4 +775,5 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress); cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); + cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 55700fd4fc..24c8971206 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -76,7 +76,7 @@ CCellRescInternal* s_rescInternalInstance = new CCellRescInternal(); // Extern Functions extern int cellGcmSetFlipMode(u32 mode); extern int cellGcmSetFlipHandler(u32 handler_addr); -extern int cellGcmAddressToOffset(u32 address, mem32_t offset); +extern int32_t cellGcmAddressToOffset(u64 address, mem32_t offset); extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); extern int cellGcmSetPrepareFlip(mem_ptr_t ctx, u32 id); extern int cellGcmSetSecondVFrequency(u32 freq); From 8514a14cf4704feeed62955170ef5a6c29aa9805 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Tue, 21 Jan 2014 20:29:16 +0200 Subject: [PATCH 08/12] small change to unmapping functions --- rpcs3/Emu/Memory/Memory.cpp | 14 ++++++++------ rpcs3/Emu/Memory/MemoryBlock.h | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 44b5fa408f..2f4c3dd4bf 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -576,32 +576,34 @@ u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) } } -bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr) +u32 VirtualMemoryBlock::UnmapRealAddress(u64 realaddr) { for(u32 i=0; i Date: Tue, 21 Jan 2014 21:10:44 +0200 Subject: [PATCH 09/12] finished all memory mapping functions of libgcm --- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 81 ++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index c81f3a911c..9a6f0fc686 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -36,7 +36,10 @@ void cellGcmGetOffsetTable(mem_ptr_t table); int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address); int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size); int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset); - +int32_t cellGcmReserveIoMapSize(const u32 size); +int32_t cellGcmUnmapEaIoAddress(u64 ea); +int32_t cellGcmUnmapIoAddress(u64 io); +int32_t cellGcmUnreserveIoMapSize(u32 size); //------------------------------------------------------------ @@ -717,6 +720,78 @@ int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) return CELL_OK; } +int32_t cellGcmReserveIoMapSize(const u32 size) +{ + if(size & 0xFFFFF) + return CELL_GCM_ERROR_INVALID_ALIGNMENT; + + if(size > cellGcmGetMaxIoMapSize()) + return CELL_GCM_ERROR_INVALID_VALUE; + + Memory.RSXIOMem.Reserve(size); + return CELL_OK; +} + +int32_t cellGcmUnmapEaIoAddress(u64 ea) +{ + u32 size; + if(size = Memory.RSXIOMem.UnmapRealAddress(ea)) + { + u64 io; + ea = ea >> 20; + io = Memory.Read16(offsetTable.io + (ea*sizeof(u16))); + + for(int i=0; i> 20; + ea = Memory.Read16(offsetTable.ea + (io*sizeof(u16))); + + for(int i=0; i Memory.RSXIOMem.GetResevedAmount()) + return CELL_GCM_ERROR_INVALID_VALUE; + + Memory.RSXIOMem.Unreserve(size); + return CELL_OK; +} + +//------------------------------------------------------------ + void cellGcmSys_init() { current_config.ioAddress = NULL; @@ -776,4 +851,8 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory); + cellGcmSys.AddFunc(0xa7ede268, cellGcmReserveIoMapSize); + cellGcmSys.AddFunc(0xefd00f54, cellGcmUnmapEaIoAddress); + cellGcmSys.AddFunc(0xdb23e867, cellGcmUnmapIoAddress); + cellGcmSys.AddFunc(0x3b9bd5bd, cellGcmUnreserveIoMapSize); } From 14c7c63e3463dc75e2431d03bd84da19524555f2 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Tue, 21 Jan 2014 22:23:28 +0200 Subject: [PATCH 10/12] small fix --- rpcs3/Emu/Memory/Memory.cpp | 8 ++++++++ rpcs3/Emu/Memory/MemoryBlock.h | 1 + 2 files changed, 9 insertions(+) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 3069864685..df8178826e 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -541,6 +541,14 @@ VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock() { } +MemoryBlock* VirtualMemoryBlock::SetRange(const u64 start, const u32 size) +{ + range_start = start; + range_size = size; + + return this; +} + bool VirtualMemoryBlock::IsInMyRange(const u64 addr) { return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize() - GetResevedAmount(); diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 76c4891e05..8fe58bdcfd 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -231,6 +231,7 @@ class VirtualMemoryBlock : public MemoryBlock public: VirtualMemoryBlock(); + virtual MemoryBlock* SetRange(const u64 start, const u32 size); virtual bool IsInMyRange(const u64 addr); virtual bool IsInMyRange(const u64 addr, const u32 size); virtual bool IsMyAddress(const u64 addr); From f260d1c60236a60a8042de4ecd65128ce6dae370 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Wed, 22 Jan 2014 20:04:11 +0200 Subject: [PATCH 11/12] fix cellGcmMapMainMemory --- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 998df1d900..eb12d007a1 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -74,7 +74,7 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) InitOffsetTable(); Memory.RSXCMDMem.Alloc(cmdSize); - Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0xE0000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase + Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0x50000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase cellGcmMapEaIoAddress(ioAddress, 0, ioSize); u32 ctx_begin = ioAddress/* + 0x1000*/; @@ -702,12 +702,17 @@ int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset) //check if the mapping was successfull if(io = Memory.RSXIOMem.Map(ea, size, 0)) { + // convert to offset + io = io - Memory.RSXIOMem.GetStartAddr(); + //fill the offset table for(u32 i=0; i<(size >> 20); i++) { Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i); Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i); } + + offset = io; } else { From ec942f26572800949a7456e8b2c0a2db1ff00a46 Mon Sep 17 00:00:00 2001 From: elisha464 Date: Wed, 22 Jan 2014 21:53:11 +0200 Subject: [PATCH 12/12] fixed getId and create thread (the id was written using write32 instead of write64) --- rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp index 0c80602a76..092d5102a2 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp @@ -141,7 +141,7 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - Memory.Write32(thread_id_addr, new_thread.GetId()); + Memory.Write64(thread_id_addr, new_thread.GetId()); new_thread.SetEntry(entry); new_thread.SetArg(0, arg); new_thread.SetPrio(prio); @@ -175,6 +175,6 @@ int sys_ppu_thread_get_id(const u32 id_addr) { sysPrxForUser.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr); - Memory.Write32(id_addr, GetCurrentPPUThread().GetId()); + Memory.Write64(id_addr, GetCurrentPPUThread().GetId()); return CELL_OK; }