diff --git a/rpcs3/Emu/Cell/MFC.h b/rpcs3/Emu/Cell/MFC.h index ca8235c05a..6016924ae5 100644 --- a/rpcs3/Emu/Cell/MFC.h +++ b/rpcs3/Emu/Cell/MFC.h @@ -168,11 +168,11 @@ struct DMAC switch(cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK)) { case MFC_PUT_CMD: - memcpy(Memory + ea, Memory + ls_offset + lsa, size); + Memory.Copy(ea, ls_offset + lsa, size); return true; case MFC_GET_CMD: - memcpy(Memory + ls_offset + lsa, Memory + ea, size); + Memory.Copy(ls_offset + lsa, ea, size); return true; default: diff --git a/rpcs3/Emu/DbgConsole.cpp b/rpcs3/Emu/DbgConsole.cpp index 1b5858bcf6..3bdbbf4197 100644 --- a/rpcs3/Emu/DbgConsole.cpp +++ b/rpcs3/Emu/DbgConsole.cpp @@ -26,7 +26,14 @@ DbgConsole::~DbgConsole() void DbgConsole::Write(int ch, const wxString& text) { - while(m_dbg_buffer.IsBusy()) Sleep(1); + while (m_dbg_buffer.IsBusy()) + { + if (Emu.IsStopped()) + { + return; + } + Sleep(1); + } m_dbg_buffer.Push(DbgPacket(ch, text)); if(!IsAlive()) Start(); @@ -43,11 +50,11 @@ void DbgConsole::Task() { if(!m_dbg_buffer.HasNewPacket()) { - Sleep(1); if (Emu.IsStopped()) { break; } + Sleep(1); continue; } diff --git a/rpcs3/Emu/FS/vfsStreamMemory.cpp b/rpcs3/Emu/FS/vfsStreamMemory.cpp index 8bb08090e6..feecb51330 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.cpp +++ b/rpcs3/Emu/FS/vfsStreamMemory.cpp @@ -32,7 +32,7 @@ u64 vfsStreamMemory::Write(const void* src, u64 size) if(!size || !Memory.IsGoodAddr(m_addr + Tell(), size)) return 0; - memcpy(&Memory[m_addr + Tell()], src, size); + Memory.CopyFromReal(m_addr + Tell(), (void*)src, size); return vfsStream::Write(src, size); } @@ -46,7 +46,7 @@ u64 vfsStreamMemory::Read(void* dst, u64 size) if(!size || !Memory.IsGoodAddr(m_addr + Tell(), size)) return 0; - memcpy(dst, &Memory[m_addr + Tell()], size); + Memory.CopyToReal(dst, m_addr + Tell(), size); return vfsStream::Read(dst, size); } diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index e46b81e32c..c16bc64cef 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -56,7 +56,7 @@ void RSXVertexData::Load(u32 start, u32 count) { case 1: { - memcpy(dst, src, size); + memcpy(dst, src, size); // may be dangerous } break; diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index df8178826e..8bf12506dc 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -48,18 +48,16 @@ bool MemoryBlock::GetMemFromAddr(void* dst, const u64 addr, const u32 size) { if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; - memcpy(dst, GetMem(FixAddr(addr)), size); - - return true; + // mem cpy(dst, GetMem(FixAddr(addr)), size); + return Memory.CopyToReal(dst, (u32)addr, size); } bool MemoryBlock::SetMemFromAddr(void* src, const u64 addr, const u32 size) { if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; - memcpy(GetMem(FixAddr(addr)), src, size); - - return true; + // mem cpy(GetMem(FixAddr(addr)), src, size); + return Memory.CopyFromReal((u32)addr, src, size); } bool MemoryBlock::GetMemFFromAddr(void* dst, const u64 addr) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 5e9ae0e863..ea670cb846 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -238,6 +238,106 @@ public: u64 Read64(const u64 addr); u128 Read128(const u64 addr); + bool CopyToReal(void* real, u32 from, u32 count) // (4K pages) copy from virtual to real memory + { + if (!count) return true; + + u8* to = (u8*)real; + + if (u32 frag = from & 4095) + { + if (!IsGoodAddr(from)) return false; + u32 num = 4096 - frag; + if (count < num) num = count; + memcpy(to, GetMemFromAddr(from), num); + to += num; + from += num; + count -= num; + } + + for (u32 page = count / 4096; page > 0; page--) + { + if (!IsGoodAddr(from)) return false; + memcpy(to, GetMemFromAddr(from), 4096); + to += 4096; + from += 4096; + count -= 4096; + } + + if (count) + { + if (!IsGoodAddr(from)) return false; + memcpy(to, GetMemFromAddr(from), count); + } + + return true; + } + + bool CopyFromReal(u32 to, void* real, u32 count) // (4K pages) copy from real to virtual memory + { + if (!count) return true; + + u8* from = (u8*)real; + + if (u32 frag = to & 4095) + { + if (!IsGoodAddr(to)) return false; + u32 num = 4096 - frag; + if (count < num) num = count; + memcpy(GetMemFromAddr(to), from, num); + to += num; + from += num; + count -= num; + } + + for (u32 page = count / 4096; page > 0; page--) + { + if (!IsGoodAddr(to)) return false; + memcpy(GetMemFromAddr(to), from, 4096); + to += 4096; + from += 4096; + count -= 4096; + } + + if (count) + { + if (!IsGoodAddr(to)) return false; + memcpy(GetMemFromAddr(to), from, count); + } + + return true; + + } + + bool Copy(u32 to, u32 from, u32 count) // (4K pages) copy from virtual to virtual memory through real + { + if (u8* buf = (u8*)malloc(count)) + { + if (CopyToReal(buf, from, count)) + { + if (CopyFromReal(to, buf, count)) + { + free(buf); + return true; + } + else + { + free(buf); + return false; + } + } + else + { + free(buf); + return false; + } + } + else + { + return false; + } + } + void ReadLeft(u8* dst, const u64 addr, const u32 size) { MemoryBlock& mem = GetMemByAddr(addr); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index 3379d18275..d83e1fc754 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -565,7 +565,7 @@ public: u32 data_addr = last_addr + 128 + last_size; last_size += size; - memcpy(Memory + data_addr, Memory + stream.addr, size); + Memory.Copy(data_addr, stream.addr, size); stream.skip(size); mem_ptr_t info(last_addr); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index 106725a816..b86104187c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -164,7 +164,7 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m switch(current_outParam.outputColorSpace) { case CELL_GIFDEC_RGBA: - memcpy(data, image.get(), image_size); + Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); break; case CELL_GIFDEC_ARGB: diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 3b78ca94da..45e3ac79fb 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -148,7 +148,7 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m case CELL_JPG_RGBA: case CELL_JPG_RGB: image_size *= current_outParam.outputColorSpace == CELL_JPG_RGBA ? 4 : 3; - memcpy(data, image.get(), image_size); + Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); break; case CELL_JPG_ARGB: diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index d0e95c310e..6f5284e061 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -116,7 +116,7 @@ int cellPamfGetHeaderSize(mem_ptr_t pAddr, u64 fileSize, mem64_t pSi //return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; - pSize = offset /*? offset : 2048*/; //hack + pSize = offset; return CELL_OK; } @@ -129,12 +129,10 @@ int cellPamfGetHeaderSize2(mem_ptr_t pAddr, u64 fileSize, u32 attrib //return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; - pSize = offset /*? offset : 2048*/; //hack + pSize = offset; return CELL_OK; } -//u32 hack_LastHeader = 0; - int cellPamfGetStreamOffsetAndSize(mem_ptr_t pAddr, u64 fileSize, mem64_t pOffset, mem64_t pSize) { cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", @@ -144,10 +142,9 @@ int cellPamfGetStreamOffsetAndSize(mem_ptr_t pAddr, u64 fileSize, me //return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; - pOffset = offset /*? offset : 2048*/; //hack + pOffset = offset; const u64 size = (u64)pAddr->data_size << 11; - pSize = size /*? size : (fileSize - 2048)*/; //hack - //if (!(u32)pAddr->magic) hack_LastHeader = pAddr.GetAddr(); + pSize = size; return CELL_OK; } @@ -171,7 +168,7 @@ int cellPamfReaderInitialize(mem_ptr_t pSelf, mem_ptr_tfileSize = ((u64)pAddr->data_offset << 11) + ((u64)pAddr->data_size << 11); } pSelf->pAddr = pAddr.GetAddr(); - //if (hack_LastHeader) memcpy(Memory + pAddr.GetAddr(), Memory + hack_LastHeader, 2048); + if (attribute & CELL_PAMF_ATTRIBUTE_VERIFY_ON) { //TODO diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 35b1f8ab79..64d83d5b92 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -91,7 +91,7 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_tsrc.srcSelect.ToLE()) { case CELL_PNGDEC_BUFFER: - memcpy(Memory.VirtualToRealAddr(buffer.GetAddr()), Memory.VirtualToRealAddr(subHandle_data->src.streamPtr.ToLE()), buffer.GetSize()); + Memory.Copy(buffer.GetAddr(), subHandle_data->src.streamPtr.ToLE(), buffer.GetSize()); break; case CELL_PNGDEC_FILE: cellFsLseek(fd, 0, CELL_SEEK_SET, pos); @@ -145,7 +145,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m switch(subHandle_data->src.srcSelect.ToLE()) { case CELL_PNGDEC_BUFFER: - memcpy(Memory.VirtualToRealAddr(png.GetAddr()), Memory.VirtualToRealAddr(subHandle_data->src.streamPtr.ToLE()), png.GetSize()); + Memory.Copy(png.GetAddr(), subHandle_data->src.streamPtr.ToLE(), png.GetSize()); break; case CELL_PNGDEC_FILE: cellFsLseek(fd, 0, CELL_SEEK_SET, pos); @@ -164,7 +164,7 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m case CELL_PNGDEC_RGB: case CELL_PNGDEC_RGBA: image_size *= current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 3; - memcpy(data, image.get(), image_size); + Memory.CopyFromReal(data.GetAddr(), image.get(), image_size); break; case CELL_PNGDEC_ARGB: diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 9a3c233faa..0d4042799c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -124,7 +124,7 @@ int sys_raw_spu_image_load(int id, mem_ptr_t img) { sysPrxForUser.Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.GetAddr()); - memcpy(Memory + RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, Memory + (u32)img->segs_addr, 256 * 1024); + Memory.Copy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, (u32)img->segs_addr, 256 * 1024); Memory.Write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, (u32)img->entry_point); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp index 520883fecf..5206dc5627 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp @@ -14,7 +14,7 @@ int cellGcmCallback(u32 context_addr, u32 count) const s32 res = ctx.current - ctx.begin - ctrl.put; - if(res > 0) memcpy(&Memory[ctx.begin], &Memory[ctx.current - res], res); + if(res > 0) Memory.Copy(ctx.begin, ctx.current - res, res); ctx.current = ctx.begin + res; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 4b3c858264..02b898207e 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -134,7 +134,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t< CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU); //copy SPU image: u32 spu_offset = Memory.MainMem.AllocAlign(256 * 1024); - memcpy(Memory + spu_offset, Memory + (u32)img->segs_addr, 256 * 1024); + Memory.CopyToReal(Memory + spu_offset, (u32)img->segs_addr, 256 * 1024); //initialize from new place: new_thread.SetOffset(spu_offset); new_thread.SetEntry(spu_ep); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index d4279bb665..8b9eee4f67 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -350,6 +350,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 366b3c5864..6f0a993820 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -603,5 +603,8 @@ Utilities + + Include + \ No newline at end of file