From 22b14000184c2a78b29e1b3478cfd9993b37535c Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 1 Oct 2016 14:13:15 -0500 Subject: [PATCH] Revamp PFIFO command submission emulation (#2179) --- rpcs3/Emu/Cell/Modules/cellGcmSys.cpp | 2 +- rpcs3/Emu/RSX/GCM.h | 2 +- rpcs3/Emu/RSX/RSXThread.cpp | 20 ++++++++++------ rpcs3/Emu/RSX/gcm_enums.h | 27 ++++++++++++++++++++++ rpcs3/Gui/RSXDebugger.cpp | 33 +++++++++++++++++++-------- 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp index 6a8c3ad8bd..caa8ddf312 100644 --- a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp @@ -1297,7 +1297,7 @@ s32 cellGcmCallback(vm::ptr context, u32 count) std::pair newCommandBuffer = getNextCommandBufferBeginEnd(context->current.addr()); u32 offset = getOffsetFromAddress(newCommandBuffer.first); // Write jump instruction - *context->current = CELL_GCM_METHOD_FLAG_JUMP | offset; + *context->current = RSX_METHOD_OLD_JUMP_CMD | offset; // Update current command buffer context->begin.set(newCommandBuffer.first); context->current.set(newCommandBuffer.first); diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index d2ab97634b..a65b6c1ca5 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -177,7 +177,7 @@ namespace rsx template static inline u32 make_jump(vm::_ptr_base, AT>& dst, u32 offset) { - *dst++ = CELL_GCM_METHOD_FLAG_JUMP | offset; + *dst++ = RSX_METHOD_OLD_JUMP_CMD | offset; return SIZE_32(u32); } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 56f05debc1..af22e7aec7 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -403,14 +403,21 @@ namespace rsx const u32 cmd = ReadIO32(get); const u32 count = (cmd >> 18) & 0x7ff; - if (cmd & CELL_GCM_METHOD_FLAG_JUMP) + if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) { - u32 offs = cmd & 0x1fffffff; + u32 offs = cmd & 0x1ffffffc; //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); ctrl->get = offs; continue; } - if (cmd & CELL_GCM_METHOD_FLAG_CALL) + if ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) + { + u32 offs = cmd & 0xfffffffc; + //LOG_WARNING(RSX, "rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", offs, m_ioAddress + get, cmd, get, put); + ctrl->get = offs; + continue; + } + if ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD) { m_call_stack.push(get + 4); u32 offs = cmd & ~3; @@ -418,7 +425,7 @@ namespace rsx ctrl->get = offs; continue; } - if (cmd == CELL_GCM_METHOD_FLAG_RETURN) + if (cmd == RSX_METHOD_RETURN_CMD) { u32 get = m_call_stack.top(); m_call_stack.pop(); @@ -426,7 +433,6 @@ namespace rsx ctrl->get = get; continue; } - if (cmd == 0) //nop { ctrl->get = get + 4; @@ -435,7 +441,7 @@ namespace rsx auto args = vm::ptr::make((u32)RSXIOMem.RealAddr(get + 4)); - u32 first_cmd = (cmd & 0xffff) >> 2; + u32 first_cmd = (cmd & 0xfffc) >> 2; if (cmd & 0x3) { @@ -444,7 +450,7 @@ namespace rsx for (u32 i = 0; i < count; i++) { - u32 reg = cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT ? first_cmd : first_cmd + i; + u32 reg = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? first_cmd : first_cmd + i; u32 value = args[i]; //LOG_NOTICE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); diff --git a/rpcs3/Emu/RSX/gcm_enums.h b/rpcs3/Emu/RSX/gcm_enums.h index dc30e7012b..f25d2e610b 100644 --- a/rpcs3/Emu/RSX/gcm_enums.h +++ b/rpcs3/Emu/RSX/gcm_enums.h @@ -992,8 +992,35 @@ enum enum Method { + /* CELL_GCM_METHOD_FLAG_NON_INCREMENT = 0x40000000, CELL_GCM_METHOD_FLAG_JUMP = 0x20000000, CELL_GCM_METHOD_FLAG_CALL = 0x00000002, CELL_GCM_METHOD_FLAG_RETURN = 0x00020000, + */ + RSX_METHOD_OLD_JUMP_CMD_MASK = 0xe0000003, + RSX_METHOD_OLD_JUMP_CMD = 0x20000000, + RSX_METHOD_OLD_JUMP_OFFSET_MASK = 0x1ffffffc, + + RSX_METHOD_INCREMENT_CMD_MASK = 0xe0030003, + RSX_METHOD_INCREMENT_CMD = 0, + RSX_METHOD_INCREMENT_COUNT_MASK = 0x0ffc0000, + RSX_METHOD_INCREMENT_COUNT_SHIFT = 18, + RSX_METHOD_INCREMENT_METHOD_MASK = 0x00001ffc, + + RSX_METHOD_NON_INCREMENT_CMD_MASK = 0xe0030003, + RSX_METHOD_NON_INCREMENT_CMD = 0x40000000, + RSX_METHOD_NON_INCREMENT_COUNT_MASK = 0x0ffc0000, + RSX_METHOD_NON_INCREMENT_COUNT_SHIFT = 18, + RSX_METHOD_NON_INCREMENT_METHOD_MASK = 0x00001ffc, + + RSX_METHOD_NEW_JUMP_CMD_MASK = 0x00000003, + RSX_METHOD_NEW_JUMP_CMD = 0x00000001, + RSX_METHOD_NEW_JUMP_OFFSET_MASK = 0xfffffffc, + + RSX_METHOD_CALL_CMD_MASK = 0x00000003, + RSX_METHOD_CALL_CMD = 0x00000002, + RSX_METHOD_CALL_OFFSET_MASK = 0xfffffffc, + + RSX_METHOD_RETURN_CMD = 0x00020000, }; diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index b32c722ec2..7d0e213b3a 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -297,8 +297,10 @@ void RSXDebugger::OnScrollMemory(wxMouseEvent& event) if(vm::check_addr(m_addr)) { u32 cmd = vm::ps3::read32(m_addr); - u32 count = (cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL)) - || cmd == CELL_GCM_METHOD_FLAG_RETURN ? 0 : (cmd >> 18) & 0x7ff; + u32 count = ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) + || ((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) + || ((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD) + || cmd == RSX_METHOD_RETURN_CMD ? 0 : (cmd >> 18) & 0x7ff; offset = 1 + count; } @@ -642,7 +644,10 @@ void RSXDebugger::GetMemory() m_list_commands->SetItem(i, 3, wxString::Format("%d", count)); m_list_commands->SetItem(i, 2, DisAsmCommand(cmd, count, addr, 0)); - if(!(cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL)) && cmd != CELL_GCM_METHOD_FLAG_RETURN) + if((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) != RSX_METHOD_OLD_JUMP_CMD + && (cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) != RSX_METHOD_NEW_JUMP_CMD + && (cmd & RSX_METHOD_CALL_CMD_MASK) != RSX_METHOD_CALL_CMD + && cmd != RSX_METHOD_RETURN_CMD) { addr += 4 * count; } @@ -1092,17 +1097,22 @@ wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA wxString disasm = wxEmptyString; #define DISASM(string, ...) { if(disasm.IsEmpty()) disasm = wxString::Format((string), ##__VA_ARGS__); else disasm += (wxString(' ') + wxString::Format((string), ##__VA_ARGS__)); } - if(cmd & CELL_GCM_METHOD_FLAG_JUMP) + if((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD) { - u32 jumpAddr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT); + u32 jumpAddr = cmd & RSX_METHOD_OLD_JUMP_OFFSET_MASK; DISASM("JUMP: %08x -> %08x", currentAddr, ioAddr+jumpAddr); } - else if(cmd & CELL_GCM_METHOD_FLAG_CALL) + else if((cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD) { - u32 callAddr = cmd & ~CELL_GCM_METHOD_FLAG_CALL; + u32 jumpAddr = cmd & RSX_METHOD_NEW_JUMP_OFFSET_MASK; + DISASM("JUMP: %08x -> %08x", currentAddr, ioAddr + jumpAddr); + } + else if((cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD) + { + u32 callAddr = cmd & RSX_METHOD_CALL_OFFSET_MASK; DISASM("CALL: %08x -> %08x", currentAddr, ioAddr+callAddr); } - if(cmd == CELL_GCM_METHOD_FLAG_RETURN) + if(cmd == RSX_METHOD_RETURN_CMD) { DISASM("RETURN"); } @@ -1111,7 +1121,10 @@ wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA { DISASM("Null cmd"); } - else if(!(cmd & (CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_CALL)) && cmd != CELL_GCM_METHOD_FLAG_RETURN) + else if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) != RSX_METHOD_OLD_JUMP_CMD + && (cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) != RSX_METHOD_NEW_JUMP_CMD + && (cmd & RSX_METHOD_CALL_CMD_MASK) != RSX_METHOD_CALL_CMD + && cmd != RSX_METHOD_RETURN_CMD) { auto args = vm::ps3::ptr::make(currentAddr + 4); @@ -1147,7 +1160,7 @@ wxString RSXDebugger::DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioA } } - if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) + if((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) { DISASM("Non Increment cmd"); }