From bcde8570b6bb9109b18c462553cba02a83a8512c Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Mon, 22 Aug 2022 19:54:56 +0200 Subject: [PATCH] Fix windows + Implement some RDP reads and writes --- external/imgui/CMakeLists.txt | 3 +- external/parallel-rdp/CMakeLists.txt | 4 ++ external/portable_endian_bswap.h | 59 +++++++++------------------- src/frontend/imgui/CMakeLists.txt | 5 ++- src/main.cpp | 6 +-- src/n64/core/CMakeLists.txt | 8 +++- src/n64/core/MMIO.cpp | 2 +- src/n64/core/RDP.cpp | 47 +++++++++++++++++++--- src/n64/core/RDP.hpp | 6 ++- src/n64/core/rsp/instructions.cpp | 2 +- 10 files changed, 85 insertions(+), 57 deletions(-) diff --git a/external/imgui/CMakeLists.txt b/external/imgui/CMakeLists.txt index ebeb86f1..1e0b5faa 100644 --- a/external/imgui/CMakeLists.txt +++ b/external/imgui/CMakeLists.txt @@ -17,4 +17,5 @@ add_library(imgui imgui/backends/imgui_impl_vulkan.h imgui/backends/imgui_impl_vulkan.cpp) -target_include_directories(imgui PUBLIC ${SDL2_INCLUDE_DIRS} imgui imgui/backends) \ No newline at end of file +target_include_directories(imgui PUBLIC ${SDL2_INCLUDE_DIRS} imgui imgui/backends) +target_link_libraries(imgui PUBLIC SDL2main SDL2) \ No newline at end of file diff --git a/external/parallel-rdp/CMakeLists.txt b/external/parallel-rdp/CMakeLists.txt index 44d08b3b..8592ae27 100644 --- a/external/parallel-rdp/CMakeLists.txt +++ b/external/parallel-rdp/CMakeLists.txt @@ -3,6 +3,8 @@ project(parallel-rdp) file(GLOB_RECURSE parallel-rdp-cpp parallel-rdp-standalone/parallel-rdp/*.cpp) +find_package(SDL2 REQUIRED) + add_library(parallel-rdp ${parallel-rdp-cpp} ParallelRDPWrapper.cpp @@ -70,6 +72,8 @@ target_include_directories(parallel-rdp PUBLIC . ) +target_link_libraries(parallel-rdp SDL2main SDL2) + if(WIN32) target_compile_definitions(parallel-rdp PUBLIC VK_USE_PLATFORM_WIN32_KHR) else() diff --git a/external/portable_endian_bswap.h b/external/portable_endian_bswap.h index 101058ec..bfee0cf9 100644 --- a/external/portable_endian_bswap.h +++ b/external/portable_endian_bswap.h @@ -5,7 +5,11 @@ // an example on how to get the endian conversion functions on different platforms. #pragma once -#include +#include + +#define bswap_16(x) (((x) & 0xFF00u) >> 8) | (((x) & 0x00FFu) << 8) +#define bswap_32(x) (((x) & 0xFF000000u) >> 24u) | (((x) & 0x00FF0000u) >> 8u) | (((x) & 0x0000FF00u) << 8u) | (((x) & 0x000000FFu) << 24u) +#define bswap_64(x) (((x) & 0xFF00000000000000u) >> 56u) | (((x) & 0x00FF000000000000u) >> 40u) | (((x) & 0x0000FF0000000000u) >> 24u) | (((x) & 0x000000FF00000000u) >> 8u) | (((x) & 0x00000000FF000000u) << 8u) | (((x) & 0x0000000000FF0000u) << 24u) | (((x) & 0x000000000000FF00u) << 40u) | (((x) & 0x00000000000000FFu) << 56u) #if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) @@ -60,52 +64,40 @@ #elif defined(__WINDOWS__) -# include -# include - - -#if __BIG_ENDIAN__ - #define htonll(x) (x) - #define ntohll(x) (x) -#else - #define htonll(x) ((((uint64_t)htonl(x&0xFFFFFFFF)) << 32) + htonl(x >> 32)) - #define ntohll(x) ((((uint64_t)ntohl(x&0xFFFFFFFF)) << 32) + ntohl(x >> 32)) -#endif - # if BYTE_ORDER == LITTLE_ENDIAN -# define htobe16(x) htons(x) +# define htobe16(x) bswap_16(x) # define htole16(x) (x) -# define be16toh(x) ntohs(x) +# define be16toh(x) bswap_16(x) # define le16toh(x) (x) -# define htobe32(x) htonl(x) +# define htobe32(x) bswap_32(x) # define htole32(x) (x) -# define be32toh(x) ntohl(x) +# define be32toh(x) bswap_32(x) # define le32toh(x) (x) -# define htobe64(x) htonll(x) +# define htobe64(x) bswap_64(x) # define htole64(x) (x) -# define be64toh(x) ntohll(x) +# define be64toh(x) bswap_64(x) # define le64toh(x) (x) # elif BYTE_ORDER == BIG_ENDIAN /* that would be xbox 360 */ # define htobe16(x) (x) -# define htole16(x) __builtin_bswap16(x) +# define htole16(x) bswap_16(x) # define be16toh(x) (x) -# define le16toh(x) __builtin_bswap16(x) +# define le16toh(x) bswap_16(x) # define htobe32(x) (x) -# define htole32(x) __builtin_bswap32(x) +# define htole32(x) bswap_32(x) # define be32toh(x) (x) -# define le32toh(x) __builtin_bswap32(x) +# define le32toh(x) bswap_32(x) # define htobe64(x) (x) -# define htole64(x) __builtin_bswap64(x) +# define htole64(x) bswap_64(x) # define be64toh(x) (x) -# define le64toh(x) __builtin_bswap64(x) +# define le64toh(x) bswap_64(x) # else @@ -122,19 +114,4 @@ # error platform not supported -#endif - -#define bswap_16(x) (((x) & 0xFF00u) >> 8) | \ - (((x) & 0x00FFu) << 8) -#define bswap_32(x) (((x) & 0xFF000000u) >> 24u) | \ - (((x) & 0x00FF0000u) >> 8u) | \ - (((x) & 0x0000FF00u) << 8u) | \ - (((x) & 0x000000FFu) << 24u) -#define bswap_64(x) (((x) & 0xFF00000000000000u) >> 56u) | \ - (((x) & 0x00FF000000000000u) >> 40u) | \ - (((x) & 0x0000FF0000000000u) >> 24u) | \ - (((x) & 0x000000FF00000000u) >> 8u) | \ - (((x) & 0x00000000FF000000u) << 8u) | \ - (((x) & 0x0000000000FF0000u) << 24u) | \ - (((x) & 0x000000000000FF00u) << 40u) | \ - (((x) & 0x00000000000000FFu) << 56u) +#endif \ No newline at end of file diff --git a/src/frontend/imgui/CMakeLists.txt b/src/frontend/imgui/CMakeLists.txt index 30ed6267..58f6ea63 100644 --- a/src/frontend/imgui/CMakeLists.txt +++ b/src/frontend/imgui/CMakeLists.txt @@ -5,8 +5,9 @@ add_subdirectory(../../../external/imgui temp) add_subdirectory(../../../external/nativefiledialog-extended temp1) find_package(SDL2 REQUIRED) +find_package(fmt REQUIRED) -add_library(frontend-imgui +add_library(frontend-imgui STATIC Window.cpp Window.hpp) @@ -23,4 +24,4 @@ target_include_directories(frontend-imgui PUBLIC ../../../external/parallel-rdp/parallel-rdp-standalone/vulkan ../../../external/parallel-rdp/parallel-rdp-standalone/util ../../../external/parallel-rdp/parallel-rdp-standalone/volk) -target_link_libraries(frontend-imgui PUBLIC SDL2 imgui nfd) \ No newline at end of file +target_link_libraries(frontend-imgui PUBLIC SDL2main SDL2 imgui nfd fmt) \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 21dacc5d..0b09dc85 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,10 +2,10 @@ #include int main(int argc, char* argv[]) { - App app; + App* app = new App; if(argc > 1) { - app.LoadROM(argv[1]); + app->LoadROM(argv[1]); } - app.Run(); + app->Run(); return 0; } \ No newline at end of file diff --git a/src/n64/core/CMakeLists.txt b/src/n64/core/CMakeLists.txt index f915537a..108e9960 100644 --- a/src/n64/core/CMakeLists.txt +++ b/src/n64/core/CMakeLists.txt @@ -6,6 +6,9 @@ add_subdirectory(cpu) add_subdirectory(../../../external/parallel-rdp temp) add_subdirectory(../../../external/capstone temp1) +find_package(fmt REQUIRED) +find_package(SDL2 REQUIRED) + add_library(core Cpu.hpp Cpu.cpp @@ -48,4 +51,7 @@ target_include_directories(core PUBLIC ../../../external/capstone/include mmio) -target_link_libraries(core PUBLIC cpu parallel-rdp capstone) +target_link_libraries(core PUBLIC SDL2main SDL2 fmt cpu parallel-rdp capstone) +if(WIN32) + +endif() diff --git a/src/n64/core/MMIO.cpp b/src/n64/core/MMIO.cpp index 9decf402..4f8c54fc 100644 --- a/src/n64/core/MMIO.cpp +++ b/src/n64/core/MMIO.cpp @@ -36,7 +36,7 @@ u32 MMIO::Read(u32 addr) { void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { switch (addr) { case 0x04040000 ... 0x040FFFFF: rsp.Write(mem, regs, addr, val); break; - case 0x04100000 ... 0x041FFFFF: rdp.Write(addr, val); break; + case 0x04100000 ... 0x041FFFFF: rdp.Write(mi, regs, rsp, addr, val); break; case 0x04300000 ... 0x043FFFFF: mi.Write(regs, addr, val); break; case 0x04400000 ... 0x044FFFFF: vi.Write(mi, regs, addr, val); break; case 0x04500000 ... 0x045FFFFF: ai.Write(mem, regs, addr, val); break; diff --git a/src/n64/core/RDP.cpp b/src/n64/core/RDP.cpp index 288b6f49..2cd163de 100644 --- a/src/n64/core/RDP.cpp +++ b/src/n64/core/RDP.cpp @@ -25,25 +25,62 @@ static const int cmd_lens[64] = { auto RDP::Read(u32 addr) const -> u32{ switch(addr) { + case 0x04100000: return dpc.start; + case 0x04100004: return dpc.end; + case 0x04100008: return dpc.current; case 0x0410000C: return dpc.status.raw; + case 0x04100010: return dpc.clock; + case 0x04100014: return dpc.status.cmdBusy; + case 0x04100018: return dpc.status.pipeBusy; + case 0x0410001C: return dpc.tmem; default: util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr); } return 0; } -void RDP::Write(u32 addr, u32 val) { +void RDP::Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val) { switch(addr) { - case 0x0410000C: StatusWrite(val); break; - default: util::panic("Unhandled DP Command Registers read (addr: {:08X}, val: {:08X})\n", addr, val); + case 0x04100000: + if(dpc.status.startValid) { + dpc.start = val & 0xFFFFF8; + } + dpc.status.startValid = true; + break; + case 0x04100004: + dpc.end = val & 0xFFFFF8; + if(dpc.status.startValid) { + dpc.current = dpc.start; + dpc.status.startValid = false; + } + RunCommand(mi, regs, rsp); + break; + case 0x0410000C: StatusWrite(mi, regs, rsp, val); break; + default: util::panic("Unhandled DP Command Registers write (addr: {:08X}, val: {:08X})\n", addr, val); } } -void RDP::StatusWrite(u32 val) { +void RDP::StatusWrite(MI& mi, Registers& regs, RSP& rsp, u32 val) { DPCStatusWrite temp{}; temp.raw = val; + bool rdpUnfrozen = false; CLEAR_SET(dpc.status.xbusDmemDma, temp.clearXbusDmemDma, temp.setXbusDmemDma); - CLEAR_SET(dpc.status.freeze, temp.clearFreeze, false); // Setting it seems to break games? Avoid for now (TODO) + if(temp.clearFreeze) { + dpc.status.freeze = false; + rdpUnfrozen = true; + } + + if(temp.setFreeze) { + dpc.status.freeze = true; + } CLEAR_SET(dpc.status.flush, temp.clearFlush, temp.setFlush); + CLEAR_SET(dpc.status.cmdBusy, temp.clearCmd, false); + CLEAR_SET(dpc.clock, temp.clearClock, false); + CLEAR_SET(dpc.status.pipeBusy, temp.clearPipe, false); + CLEAR_SET(dpc.status.tmemBusy, temp.clearTmem, false); + + if(rdpUnfrozen) { + RunCommand(mi, regs, rsp); + } } void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) { diff --git a/src/n64/core/RDP.hpp b/src/n64/core/RDP.hpp index f7b22c25..3452f97c 100644 --- a/src/n64/core/RDP.hpp +++ b/src/n64/core/RDP.hpp @@ -46,6 +46,8 @@ struct DPC { u32 start; u32 current; u32 end; + u32 clock; + u32 tmem; }; struct RDP { @@ -57,8 +59,8 @@ struct RDP { std::vector dram; [[nodiscard]] auto Read(u32 addr) const -> u32; - void Write(u32 addr, u32 val); - void StatusWrite(u32 val); + void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val); + void StatusWrite(MI& mi, Registers& regs, RSP& rsp, u32 val); void RunCommand(MI& mi, Registers& regs, RSP& rsp); void OnFullSync(); }; diff --git a/src/n64/core/rsp/instructions.cpp b/src/n64/core/rsp/instructions.cpp index ea0b1114..c9932744 100644 --- a/src/n64/core/rsp/instructions.cpp +++ b/src/n64/core/rsp/instructions.cpp @@ -52,7 +52,7 @@ inline void SetCop0Reg(MI& mi, Registers& regs, RSP& rsp, RDP& rdp, u8 index, u3 rdp.dpc.end = val & 0xFFFFF8; rdp.RunCommand(mi, regs, rsp); break; - case 11: rdp.StatusWrite(val); break; + case 11: rdp.StatusWrite(mi, regs, rsp, val); break; default: util::panic("Unhandled RSP COP0 register write at index {}\n", index); } }