diff options
| author | 2014-04-27 21:25:16 -0400 | |
|---|---|---|
| committer | 2014-04-27 21:25:16 -0400 | |
| commit | 438dba40c1def91e9de252ef05f8650464e5c0c2 (patch) | |
| tree | 8f323d6095dfefe9d00f34cc4d7229be58a9f409 /src | |
| parent | Merge pull request #4 from cpp3ds/master (diff) | |
| parent | removed DISALLOW_COPY_AND_ASSIGN in favor of NonCopyable class (diff) | |
| download | yuzu-438dba40c1def91e9de252ef05f8650464e5c0c2.tar.gz yuzu-438dba40c1def91e9de252ef05f8650464e5c0c2.tar.xz yuzu-438dba40c1def91e9de252ef05f8650464e5c0c2.zip | |
Merge branch 'hle-interface-updates'
Diffstat (limited to 'src')
31 files changed, 623 insertions, 175 deletions
diff --git a/src/common/common.h b/src/common/common.h index a281b21cc..418757855 100644 --- a/src/common/common.h +++ b/src/common/common.h | |||
| @@ -159,9 +159,4 @@ enum EMUSTATE_CHANGE | |||
| 159 | EMUSTATE_CHANGE_STOP | 159 | EMUSTATE_CHANGE_STOP |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | // This should be used in the private: declarations for a class | ||
| 163 | #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ | ||
| 164 | TypeName(const TypeName&); \ | ||
| 165 | void operator=(const TypeName&) | ||
| 166 | |||
| 167 | #endif // _COMMON_H_ | 162 | #endif // _COMMON_H_ |
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3ba3afa70..314f6e64c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -18,6 +18,7 @@ set(SRCS core.cpp | |||
| 18 | file_sys/directory_file_system.cpp | 18 | file_sys/directory_file_system.cpp |
| 19 | file_sys/meta_file_system.cpp | 19 | file_sys/meta_file_system.cpp |
| 20 | hle/hle.cpp | 20 | hle/hle.cpp |
| 21 | hle/mrc.cpp | ||
| 21 | hle/syscall.cpp | 22 | hle/syscall.cpp |
| 22 | hle/service/apt.cpp | 23 | hle/service/apt.cpp |
| 23 | hle/service/gsp.cpp | 24 | hle/service/gsp.cpp |
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index eee4726db..4dfe0570b 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | 9 | ||
| 10 | /// Generic ARM11 CPU interface | 10 | /// Generic ARM11 CPU interface |
| 11 | class ARM_Interface { | 11 | class ARM_Interface : NonCopyable { |
| 12 | public: | 12 | public: |
| 13 | ARM_Interface() { | 13 | ARM_Interface() { |
| 14 | m_num_instructions = 0; | 14 | m_num_instructions = 0; |
| @@ -75,5 +75,4 @@ private: | |||
| 75 | 75 | ||
| 76 | u64 m_num_instructions; ///< Number of instructions executed | 76 | u64 m_num_instructions; ///< Number of instructions executed |
| 77 | 77 | ||
| 78 | DISALLOW_COPY_AND_ASSIGN(ARM_Interface); | ||
| 79 | }; | 78 | }; |
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h index f3c86f8dd..625c0c652 100644 --- a/src/core/arm/interpreter/arm_interpreter.h +++ b/src/core/arm/interpreter/arm_interpreter.h | |||
| @@ -63,5 +63,4 @@ private: | |||
| 63 | 63 | ||
| 64 | ARMul_State* m_state; | 64 | ARMul_State* m_state; |
| 65 | 65 | ||
| 66 | DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter); | ||
| 67 | }; | 66 | }; |
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 6074ff480..a35c5c8dc 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -4467,7 +4467,6 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 4467 | } | 4467 | } |
| 4468 | /* Drop through. */ | 4468 | /* Drop through. */ |
| 4469 | 4469 | ||
| 4470 | case 0xe0: | ||
| 4471 | case 0xe4: | 4470 | case 0xe4: |
| 4472 | case 0xe6: | 4471 | case 0xe6: |
| 4473 | case 0xe8: | 4472 | case 0xe8: |
| @@ -4502,6 +4501,7 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 4502 | 4501 | ||
| 4503 | 4502 | ||
| 4504 | /* Co-Processor Register Transfers (MRC) and Data Ops. */ | 4503 | /* Co-Processor Register Transfers (MRC) and Data Ops. */ |
| 4504 | case 0xe0: | ||
| 4505 | case 0xe1: | 4505 | case 0xe1: |
| 4506 | case 0xe3: | 4506 | case 0xe3: |
| 4507 | case 0xe5: | 4507 | case 0xe5: |
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 101b9807a..b2bbedc18 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp | |||
| @@ -17,9 +17,11 @@ | |||
| 17 | 17 | ||
| 18 | #include "armdefs.h" | 18 | #include "armdefs.h" |
| 19 | #include "armemu.h" | 19 | #include "armemu.h" |
| 20 | |||
| 20 | //#include "ansidecl.h" | 21 | //#include "ansidecl.h" |
| 21 | #include "skyeye_defs.h" | 22 | #include "skyeye_defs.h" |
| 22 | #include "core/hle/hle.h" | 23 | #include "core/hle/mrc.h" |
| 24 | #include "core/arm/disassembler/arm_disasm.h" | ||
| 23 | 25 | ||
| 24 | unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, | 26 | unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, |
| 25 | unsigned cpnum); | 27 | unsigned cpnum); |
| @@ -736,7 +738,8 @@ ARMword | |||
| 736 | ARMul_MRC (ARMul_State * state, ARMword instr) | 738 | ARMul_MRC (ARMul_State * state, ARMword instr) |
| 737 | { | 739 | { |
| 738 | unsigned cpab; | 740 | unsigned cpab; |
| 739 | ARMword result = HLE::CallGetThreadCommandBuffer(); | 741 | |
| 742 | ARMword result = HLE::CallMRC((HLE::ARM11_MRC_OPERATION)BITS(20, 27)); | ||
| 740 | 743 | ||
| 741 | ////printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr); | 744 | ////printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr); |
| 742 | //if (!CP_ACCESS_ALLOWED (state, CPNum)) { | 745 | //if (!CP_ACCESS_ALLOWED (state, CPNum)) { |
| @@ -846,7 +849,10 @@ ARMul_CDP (ARMul_State * state, ARMword instr) | |||
| 846 | void | 849 | void |
| 847 | ARMul_UndefInstr (ARMul_State * state, ARMword instr) | 850 | ARMul_UndefInstr (ARMul_State * state, ARMword instr) |
| 848 | { | 851 | { |
| 849 | ERROR_LOG(ARM11, "Undefined instruction!! Instr: 0x%x", instr); | 852 | char buff[512]; |
| 853 | ARM_Disasm disasm = ARM_Disasm(); | ||
| 854 | disasm.disasm(state->pc, instr, buff); | ||
| 855 | ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", buff, instr); | ||
| 850 | ARMul_Abort (state, ARMul_UndefinedInstrV); | 856 | ARMul_Abort (state, ARMul_UndefinedInstrV); |
| 851 | } | 857 | } |
| 852 | 858 | ||
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index b6fc604c6..be8448969 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj | |||
| @@ -153,6 +153,7 @@ | |||
| 153 | <ClCompile Include="file_sys\directory_file_system.cpp" /> | 153 | <ClCompile Include="file_sys\directory_file_system.cpp" /> |
| 154 | <ClCompile Include="file_sys\meta_file_system.cpp" /> | 154 | <ClCompile Include="file_sys\meta_file_system.cpp" /> |
| 155 | <ClCompile Include="hle\hle.cpp" /> | 155 | <ClCompile Include="hle\hle.cpp" /> |
| 156 | <ClCompile Include="hle\mrc.cpp" /> | ||
| 156 | <ClCompile Include="hle\service\apt.cpp" /> | 157 | <ClCompile Include="hle\service\apt.cpp" /> |
| 157 | <ClCompile Include="hle\service\gsp.cpp" /> | 158 | <ClCompile Include="hle\service\gsp.cpp" /> |
| 158 | <ClCompile Include="hle\service\hid.cpp" /> | 159 | <ClCompile Include="hle\service\hid.cpp" /> |
| @@ -192,6 +193,7 @@ | |||
| 192 | <ClInclude Include="file_sys\meta_file_system.h" /> | 193 | <ClInclude Include="file_sys\meta_file_system.h" /> |
| 193 | <ClInclude Include="hle\function_wrappers.h" /> | 194 | <ClInclude Include="hle\function_wrappers.h" /> |
| 194 | <ClInclude Include="hle\hle.h" /> | 195 | <ClInclude Include="hle\hle.h" /> |
| 196 | <ClInclude Include="hle\mrc.h" /> | ||
| 195 | <ClInclude Include="hle\service\apt.h" /> | 197 | <ClInclude Include="hle\service\apt.h" /> |
| 196 | <ClInclude Include="hle\service\gsp.h" /> | 198 | <ClInclude Include="hle\service\gsp.h" /> |
| 197 | <ClInclude Include="hle\service\hid.h" /> | 199 | <ClInclude Include="hle\service\hid.h" /> |
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index ff7877feb..b5473bc41 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters | |||
| @@ -105,6 +105,9 @@ | |||
| 105 | <ClCompile Include="hw\lcd.cpp"> | 105 | <ClCompile Include="hw\lcd.cpp"> |
| 106 | <Filter>hw</Filter> | 106 | <Filter>hw</Filter> |
| 107 | </ClCompile> | 107 | </ClCompile> |
| 108 | <ClCompile Include="hle\mrc.cpp"> | ||
| 109 | <Filter>hle</Filter> | ||
| 110 | </ClCompile> | ||
| 108 | </ItemGroup> | 111 | </ItemGroup> |
| 109 | <ItemGroup> | 112 | <ItemGroup> |
| 110 | <ClInclude Include="arm\disassembler\arm_disasm.h"> | 113 | <ClInclude Include="arm\disassembler\arm_disasm.h"> |
| @@ -205,6 +208,9 @@ | |||
| 205 | <ClInclude Include="hw\lcd.h"> | 208 | <ClInclude Include="hw\lcd.h"> |
| 206 | <Filter>hw</Filter> | 209 | <Filter>hw</Filter> |
| 207 | </ClInclude> | 210 | </ClInclude> |
| 211 | <ClInclude Include="hle\mrc.h"> | ||
| 212 | <Filter>hle</Filter> | ||
| 213 | </ClInclude> | ||
| 208 | </ItemGroup> | 214 | </ItemGroup> |
| 209 | <ItemGroup> | 215 | <ItemGroup> |
| 210 | <Text Include="CMakeLists.txt" /> | 216 | <Text Include="CMakeLists.txt" /> |
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp index 5672a659f..aae9a3943 100644 --- a/src/core/hle/hle.cpp +++ b/src/core/hle/hle.cpp | |||
| @@ -80,14 +80,6 @@ void CallSyscall(u32 opcode) { | |||
| 80 | } | 80 | } |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /// Returns the coprocessor (in this case, syscore) command buffer pointer | ||
| 84 | Addr CallGetThreadCommandBuffer() { | ||
| 85 | // Called on insruction: mrc p15, 0, r0, c13, c0, 3 | ||
| 86 | // Returns an address in OSHLE memory for the CPU to read/write to | ||
| 87 | RETURN(CMD_BUFFER_ADDR); | ||
| 88 | return CMD_BUFFER_ADDR; | ||
| 89 | } | ||
| 90 | |||
| 91 | void RegisterModule(std::string name, int num_functions, const FunctionDef* func_table) { | 83 | void RegisterModule(std::string name, int num_functions, const FunctionDef* func_table) { |
| 92 | ModuleDef module = {name, num_functions, func_table}; | 84 | ModuleDef module = {name, num_functions, func_table}; |
| 93 | g_module_db.push_back(module); | 85 | g_module_db.push_back(module); |
diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h index 628a1da89..907e2d741 100644 --- a/src/core/hle/hle.h +++ b/src/core/hle/hle.h | |||
| @@ -57,8 +57,6 @@ void RegisterModule(std::string name, int num_functions, const FunctionDef *func | |||
| 57 | 57 | ||
| 58 | void CallSyscall(u32 opcode); | 58 | void CallSyscall(u32 opcode); |
| 59 | 59 | ||
| 60 | Addr CallGetThreadCommandBuffer(); | ||
| 61 | |||
| 62 | void Init(); | 60 | void Init(); |
| 63 | 61 | ||
| 64 | void Shutdown(); | 62 | void Shutdown(); |
diff --git a/src/core/hle/mrc.cpp b/src/core/hle/mrc.cpp new file mode 100644 index 000000000..5223be7c9 --- /dev/null +++ b/src/core/hle/mrc.cpp | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/mrc.h" | ||
| 6 | #include "core/hle/hle.h" | ||
| 7 | #include "core/mem_map.h" | ||
| 8 | #include "core/core.h" | ||
| 9 | |||
| 10 | namespace HLE { | ||
| 11 | |||
| 12 | enum { | ||
| 13 | CMD_GX_REQUEST_DMA = 0x00000000, | ||
| 14 | }; | ||
| 15 | |||
| 16 | /// Data synchronization barrier | ||
| 17 | u32 DataSynchronizationBarrier(u32* command_buffer) { | ||
| 18 | u32 command = command_buffer[0]; | ||
| 19 | |||
| 20 | switch (command) { | ||
| 21 | |||
| 22 | case CMD_GX_REQUEST_DMA: | ||
| 23 | { | ||
| 24 | u32* src = (u32*)Memory::GetPointer(command_buffer[1]); | ||
| 25 | u32* dst = (u32*)Memory::GetPointer(command_buffer[2]); | ||
| 26 | u32 size = command_buffer[3]; | ||
| 27 | memcpy(dst, src, size); | ||
| 28 | } | ||
| 29 | break; | ||
| 30 | |||
| 31 | default: | ||
| 32 | ERROR_LOG(OSHLE, "MRC::DataSynchronizationBarrier unknown command 0x%08X", command); | ||
| 33 | return -1; | ||
| 34 | } | ||
| 35 | |||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | /// Returns the coprocessor (in this case, syscore) command buffer pointer | ||
| 40 | Addr GetThreadCommandBuffer() { | ||
| 41 | // Called on insruction: mrc p15, 0, r0, c13, c0, 3 | ||
| 42 | // Returns an address in OSHLE memory for the CPU to read/write to | ||
| 43 | RETURN(CMD_BUFFER_ADDR); | ||
| 44 | return CMD_BUFFER_ADDR; | ||
| 45 | } | ||
| 46 | |||
| 47 | /// Call an MRC operation in HLE | ||
| 48 | u32 CallMRC(ARM11_MRC_OPERATION operation) { | ||
| 49 | switch (operation) { | ||
| 50 | |||
| 51 | case DATA_SYNCHRONIZATION_BARRIER: | ||
| 52 | return DataSynchronizationBarrier((u32*)Memory::GetPointer(PARAM(0))); | ||
| 53 | |||
| 54 | case CALL_GET_THREAD_COMMAND_BUFFER: | ||
| 55 | return GetThreadCommandBuffer(); | ||
| 56 | |||
| 57 | default: | ||
| 58 | ERROR_LOG(OSHLE, "unimplemented MRC operation 0x%02X", operation); | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | return -1; | ||
| 62 | } | ||
| 63 | |||
| 64 | } // namespace | ||
diff --git a/src/core/hle/mrc.h b/src/core/hle/mrc.h new file mode 100644 index 000000000..d6b9f162f --- /dev/null +++ b/src/core/hle/mrc.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace HLE { | ||
| 10 | |||
| 11 | /// MRC operations (ARM register from coprocessor), decoded as instr[20:27] | ||
| 12 | enum ARM11_MRC_OPERATION { | ||
| 13 | DATA_SYNCHRONIZATION_BARRIER = 0xE0, | ||
| 14 | CALL_GET_THREAD_COMMAND_BUFFER = 0xE1, | ||
| 15 | }; | ||
| 16 | |||
| 17 | /// Call an MRC operation in HLE | ||
| 18 | u32 CallMRC(ARM11_MRC_OPERATION operation); | ||
| 19 | |||
| 20 | } // namespace | ||
diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp index 4f8d7248d..4a1e8c992 100644 --- a/src/core/hle/service/apt.cpp +++ b/src/core/hle/service/apt.cpp | |||
| @@ -13,16 +13,16 @@ | |||
| 13 | 13 | ||
| 14 | namespace APT_U { | 14 | namespace APT_U { |
| 15 | 15 | ||
| 16 | void Initialize() { | 16 | void Initialize(Service::Interface* self) { |
| 17 | NOTICE_LOG(OSHLE, "APT_U::Sync - Initialize"); | 17 | NOTICE_LOG(OSHLE, "APT_U::Sync - Initialize"); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void GetLockHandle() { | 20 | void GetLockHandle(Service::Interface* self) { |
| 21 | u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); | 21 | u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); |
| 22 | cmd_buff[5] = 0x00000000; // TODO: This should be an actual mutex handle | 22 | cmd_buff[5] = 0x00000000; // TODO: This should be an actual mutex handle |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | const HLE::FunctionDef FunctionTable[] = { | 25 | const Interface::FunctionInfo FunctionTable[] = { |
| 26 | {0x00010040, GetLockHandle, "GetLockHandle"}, | 26 | {0x00010040, GetLockHandle, "GetLockHandle"}, |
| 27 | {0x00020080, Initialize, "Initialize"}, | 27 | {0x00020080, Initialize, "Initialize"}, |
| 28 | {0x00030040, NULL, "Enable"}, | 28 | {0x00030040, NULL, "Enable"}, |
diff --git a/src/core/hle/service/apt.h b/src/core/hle/service/apt.h index e74baac0c..4c7dd07e7 100644 --- a/src/core/hle/service/apt.h +++ b/src/core/hle/service/apt.h | |||
| @@ -32,10 +32,6 @@ public: | |||
| 32 | std::string GetPortName() const { | 32 | std::string GetPortName() const { |
| 33 | return "APT:U"; | 33 | return "APT:U"; |
| 34 | } | 34 | } |
| 35 | |||
| 36 | private: | ||
| 37 | |||
| 38 | DISALLOW_COPY_AND_ASSIGN(Interface); | ||
| 39 | }; | 35 | }; |
| 40 | 36 | ||
| 41 | } // namespace | 37 | } // namespace |
diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp index 7c80ab8b5..88c1f1a0f 100644 --- a/src/core/hle/service/gsp.cpp +++ b/src/core/hle/service/gsp.cpp | |||
| @@ -5,45 +5,96 @@ | |||
| 5 | 5 | ||
| 6 | #include "common/log.h" | 6 | #include "common/log.h" |
| 7 | 7 | ||
| 8 | #include "core/mem_map.h" | ||
| 8 | #include "core/hle/hle.h" | 9 | #include "core/hle/hle.h" |
| 9 | #include "core/hle/service/gsp.h" | 10 | #include "core/hle/service/gsp.h" |
| 10 | 11 | ||
| 12 | #include "core/hw/lcd.h" | ||
| 13 | |||
| 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 14 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 12 | // Namespace GSP_GPU | 15 | // Namespace GSP_GPU |
| 13 | 16 | ||
| 14 | namespace GSP_GPU { | 17 | namespace GSP_GPU { |
| 15 | 18 | ||
| 16 | const HLE::FunctionDef FunctionTable[] = { | 19 | enum { |
| 17 | {0x00010082, NULL, "WriteHWRegs"}, | 20 | REG_FRAMEBUFFER_1 = 0x00400468, |
| 18 | {0x00020084, NULL, "WriteHWRegsWithMask"}, | 21 | REG_FRAMEBUFFER_2 = 0x00400494, |
| 19 | {0x00030082, NULL, "WriteHWRegRepeat"}, | 22 | }; |
| 20 | {0x00040080, NULL, "ReadHWRegs"}, | 23 | |
| 21 | {0x00050200, NULL, "SetBufferSwap"}, | 24 | /// Read a GSP GPU hardware register |
| 22 | {0x00060082, NULL, "SetCommandList"}, | 25 | void ReadHWRegs(Service::Interface* self) { |
| 23 | {0x000700C2, NULL, "RequestDma"}, | 26 | static const u32 framebuffer_1[] = {LCD::PADDR_VRAM_TOP_LEFT_FRAME1, LCD::PADDR_VRAM_TOP_RIGHT_FRAME1}; |
| 24 | {0x00080082, NULL, "FlushDataCache"}, | 27 | static const u32 framebuffer_2[] = {LCD::PADDR_VRAM_TOP_LEFT_FRAME2, LCD::PADDR_VRAM_TOP_RIGHT_FRAME2}; |
| 25 | {0x00090082, NULL, "InvalidateDataCache"}, | 28 | |
| 26 | {0x000A0044, NULL, "RegisterInterruptEvents"}, | 29 | u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); |
| 27 | {0x000B0040, NULL, "SetLcdForceBlack"}, | 30 | u32 reg_addr = cmd_buff[1]; |
| 28 | {0x000C0000, NULL, "TriggerCmdReqQueue"}, | 31 | u32 size = cmd_buff[2]; |
| 29 | {0x000D0140, NULL, "SetDisplayTransfer"}, | 32 | u32* dst = (u32*)Memory::GetPointer(cmd_buff[0x41]); |
| 30 | {0x000E0180, NULL, "SetTextureCopy"}, | 33 | |
| 31 | {0x000F0200, NULL, "SetMemoryFill"}, | 34 | switch (reg_addr) { |
| 32 | {0x00100040, NULL, "SetAxiConfigQoSMode"}, | 35 | |
| 33 | {0x00110040, NULL, "SetPerfLogMode"}, | 36 | // NOTE: Calling SetFramebufferLocation here is a hack... Not sure the correct way yet to set |
| 34 | {0x00120000, NULL, "GetPerfLog"}, | 37 | // whether the framebuffers should be in VRAM or GSP heap, but from what I understand, if the |
| 35 | {0x00130042, NULL, "RegisterInterruptRelayQueue"}, | 38 | // user application is reading from either of these registers, then its going to be in VRAM. |
| 36 | {0x00140000, NULL, "UnregisterInterruptRelayQueue"}, | 39 | |
| 37 | {0x00150002, NULL, "TryAcquireRight"}, | 40 | // Top framebuffer 1 addresses |
| 38 | {0x00160042, NULL, "AcquireRight"}, | 41 | case REG_FRAMEBUFFER_1: |
| 39 | {0x00170000, NULL, "ReleaseRight"}, | 42 | LCD::SetFramebufferLocation(LCD::FRAMEBUFFER_LOCATION_VRAM); |
| 40 | {0x00180000, NULL, "ImportDisplayCaptureInfo"}, | 43 | memcpy(dst, framebuffer_1, size); |
| 41 | {0x00190000, NULL, "SaveVramSysArea"}, | 44 | break; |
| 42 | {0x001A0000, NULL, "RestoreVramSysArea"}, | 45 | |
| 43 | {0x001B0000, NULL, "ResetGpuCore"}, | 46 | // Top framebuffer 2 addresses |
| 44 | {0x001C0040, NULL, "SetLedForceOff"}, | 47 | case REG_FRAMEBUFFER_2: |
| 45 | {0x001D0040, NULL, "SetTestCommand"}, | 48 | LCD::SetFramebufferLocation(LCD::FRAMEBUFFER_LOCATION_VRAM); |
| 46 | {0x001E0080, NULL, "SetInternalPriorities"}, | 49 | memcpy(dst, framebuffer_2, size); |
| 50 | break; | ||
| 51 | |||
| 52 | default: | ||
| 53 | ERROR_LOG(OSHLE, "GSP_GPU::ReadHWRegs unknown register read at address %08X", reg_addr); | ||
| 54 | } | ||
| 55 | |||
| 56 | } | ||
| 57 | |||
| 58 | void RegisterInterruptRelayQueue(Service::Interface* self) { | ||
| 59 | u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); | ||
| 60 | u32 flags = cmd_buff[1]; | ||
| 61 | u32 event_handle = cmd_buff[3]; // TODO(bunnei): Implement event handling | ||
| 62 | cmd_buff[4] = self->NewHandle(); | ||
| 63 | |||
| 64 | return; | ||
| 65 | } | ||
| 66 | |||
| 67 | const Interface::FunctionInfo FunctionTable[] = { | ||
| 68 | {0x00010082, NULL, "WriteHWRegs"}, | ||
| 69 | {0x00020084, NULL, "WriteHWRegsWithMask"}, | ||
| 70 | {0x00030082, NULL, "WriteHWRegRepeat"}, | ||
| 71 | {0x00040080, ReadHWRegs, "ReadHWRegs"}, | ||
| 72 | {0x00050200, NULL, "SetBufferSwap"}, | ||
| 73 | {0x00060082, NULL, "SetCommandList"}, | ||
| 74 | {0x000700C2, NULL, "RequestDma"}, | ||
| 75 | {0x00080082, NULL, "FlushDataCache"}, | ||
| 76 | {0x00090082, NULL, "InvalidateDataCache"}, | ||
| 77 | {0x000A0044, NULL, "RegisterInterruptEvents"}, | ||
| 78 | {0x000B0040, NULL, "SetLcdForceBlack"}, | ||
| 79 | {0x000C0000, NULL, "TriggerCmdReqQueue"}, | ||
| 80 | {0x000D0140, NULL, "SetDisplayTransfer"}, | ||
| 81 | {0x000E0180, NULL, "SetTextureCopy"}, | ||
| 82 | {0x000F0200, NULL, "SetMemoryFill"}, | ||
| 83 | {0x00100040, NULL, "SetAxiConfigQoSMode"}, | ||
| 84 | {0x00110040, NULL, "SetPerfLogMode"}, | ||
| 85 | {0x00120000, NULL, "GetPerfLog"}, | ||
| 86 | {0x00130042, RegisterInterruptRelayQueue, "RegisterInterruptRelayQueue"}, | ||
| 87 | {0x00140000, NULL, "UnregisterInterruptRelayQueue"}, | ||
| 88 | {0x00150002, NULL, "TryAcquireRight"}, | ||
| 89 | {0x00160042, NULL, "AcquireRight"}, | ||
| 90 | {0x00170000, NULL, "ReleaseRight"}, | ||
| 91 | {0x00180000, NULL, "ImportDisplayCaptureInfo"}, | ||
| 92 | {0x00190000, NULL, "SaveVramSysArea"}, | ||
| 93 | {0x001A0000, NULL, "RestoreVramSysArea"}, | ||
| 94 | {0x001B0000, NULL, "ResetGpuCore"}, | ||
| 95 | {0x001C0040, NULL, "SetLedForceOff"}, | ||
| 96 | {0x001D0040, NULL, "SetTestCommand"}, | ||
| 97 | {0x001E0080, NULL, "SetInternalPriorities"}, | ||
| 47 | }; | 98 | }; |
| 48 | 99 | ||
| 49 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 100 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
diff --git a/src/core/hle/service/gsp.h b/src/core/hle/service/gsp.h index 3b1846082..5ba09ab70 100644 --- a/src/core/hle/service/gsp.h +++ b/src/core/hle/service/gsp.h | |||
| @@ -27,9 +27,6 @@ public: | |||
| 27 | return "gsp::Gpu"; | 27 | return "gsp::Gpu"; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | private: | ||
| 31 | |||
| 32 | DISALLOW_COPY_AND_ASSIGN(Interface); | ||
| 33 | }; | 30 | }; |
| 34 | 31 | ||
| 35 | } // namespace | 32 | } // namespace |
diff --git a/src/core/hle/service/hid.cpp b/src/core/hle/service/hid.cpp index 2d823dd16..5542e5bf2 100644 --- a/src/core/hle/service/hid.cpp +++ b/src/core/hle/service/hid.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace HID_User { | 13 | namespace HID_User { |
| 14 | 14 | ||
| 15 | const HLE::FunctionDef FunctionTable[] = { | 15 | const Interface::FunctionInfo FunctionTable[] = { |
| 16 | {0x000A0000, NULL, "GetIPCHandles"}, | 16 | {0x000A0000, NULL, "GetIPCHandles"}, |
| 17 | {0x00110000, NULL, "EnableAccelerometer"}, | 17 | {0x00110000, NULL, "EnableAccelerometer"}, |
| 18 | {0x00130000, NULL, "EnableGyroscopeLow"}, | 18 | {0x00130000, NULL, "EnableGyroscopeLow"}, |
diff --git a/src/core/hle/service/hid.h b/src/core/hle/service/hid.h index 746c1b1fc..b17fcfa86 100644 --- a/src/core/hle/service/hid.h +++ b/src/core/hle/service/hid.h | |||
| @@ -29,9 +29,6 @@ public: | |||
| 29 | return "hid:USER"; | 29 | return "hid:USER"; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | private: | ||
| 33 | |||
| 34 | DISALLOW_COPY_AND_ASSIGN(Interface); | ||
| 35 | }; | 32 | }; |
| 36 | 33 | ||
| 37 | } // namespace | 34 | } // namespace |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 9cbf8b6fa..b79dc9458 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -25,7 +25,7 @@ static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer | |||
| 25 | class Manager; | 25 | class Manager; |
| 26 | 26 | ||
| 27 | /// Interface to a CTROS service | 27 | /// Interface to a CTROS service |
| 28 | class Interface { | 28 | class Interface : NonCopyable { |
| 29 | friend class Manager; | 29 | friend class Manager; |
| 30 | public: | 30 | public: |
| 31 | 31 | ||
| @@ -35,6 +35,14 @@ public: | |||
| 35 | virtual ~Interface() { | 35 | virtual ~Interface() { |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | typedef void (*Function)(Interface*); | ||
| 39 | |||
| 40 | struct FunctionInfo { | ||
| 41 | u32 id; | ||
| 42 | Function func; | ||
| 43 | std::string name; | ||
| 44 | }; | ||
| 45 | |||
| 38 | /** | 46 | /** |
| 39 | * Gets the UID for the serice | 47 | * Gets the UID for the serice |
| 40 | * @return UID of service in native format | 48 | * @return UID of service in native format |
| @@ -51,6 +59,23 @@ public: | |||
| 51 | return "[UNKNOWN SERVICE PORT]"; | 59 | return "[UNKNOWN SERVICE PORT]"; |
| 52 | } | 60 | } |
| 53 | 61 | ||
| 62 | /// Allocates a new handle for the service | ||
| 63 | Syscall::Handle NewHandle() { | ||
| 64 | Syscall::Handle handle = (m_handles.size() << 16) | m_uid; | ||
| 65 | m_handles.push_back(handle); | ||
| 66 | return handle; | ||
| 67 | } | ||
| 68 | |||
| 69 | /// Frees a handle from the service | ||
| 70 | void DeleteHandle(Syscall::Handle handle) { | ||
| 71 | for(auto iter = m_handles.begin(); iter != m_handles.end(); ++iter) { | ||
| 72 | if(*iter == handle) { | ||
| 73 | m_handles.erase(iter); | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 54 | /** | 79 | /** |
| 55 | * Called when svcSendSyncRequest is called, loads command buffer and executes comand | 80 | * Called when svcSendSyncRequest is called, loads command buffer and executes comand |
| 56 | * @return Return result of svcSendSyncRequest passed back to user app | 81 | * @return Return result of svcSendSyncRequest passed back to user app |
| @@ -70,16 +95,17 @@ public: | |||
| 70 | return -1; | 95 | return -1; |
| 71 | } | 96 | } |
| 72 | 97 | ||
| 73 | itr->second.func(); | 98 | itr->second.func(this); |
| 74 | 99 | ||
| 75 | return 0; // TODO: Implement return from actual function | 100 | return 0; // TODO: Implement return from actual function |
| 76 | } | 101 | } |
| 77 | 102 | ||
| 78 | protected: | 103 | protected: |
| 104 | |||
| 79 | /** | 105 | /** |
| 80 | * Registers the functions in the service | 106 | * Registers the functions in the service |
| 81 | */ | 107 | */ |
| 82 | void Register(const HLE::FunctionDef* functions, int len) { | 108 | void Register(const FunctionInfo* functions, int len) { |
| 83 | for (int i = 0; i < len; i++) { | 109 | for (int i = 0; i < len; i++) { |
| 84 | m_functions[functions[i].id] = functions[i]; | 110 | m_functions[functions[i].id] = functions[i]; |
| 85 | } | 111 | } |
| @@ -87,9 +113,9 @@ protected: | |||
| 87 | 113 | ||
| 88 | private: | 114 | private: |
| 89 | u32 m_uid; | 115 | u32 m_uid; |
| 90 | std::map<u32, HLE::FunctionDef> m_functions; | 116 | |
| 91 | 117 | std::vector<Syscall::Handle> m_handles; | |
| 92 | DISALLOW_COPY_AND_ASSIGN(Interface); | 118 | std::map<u32, FunctionInfo> m_functions; |
| 93 | }; | 119 | }; |
| 94 | 120 | ||
| 95 | /// Simple class to manage accessing services from ports and UID handles | 121 | /// Simple class to manage accessing services from ports and UID handles |
| @@ -126,8 +152,6 @@ private: | |||
| 126 | 152 | ||
| 127 | std::vector<Interface*> m_services; | 153 | std::vector<Interface*> m_services; |
| 128 | std::map<std::string, u32> m_port_map; | 154 | std::map<std::string, u32> m_port_map; |
| 129 | |||
| 130 | DISALLOW_COPY_AND_ASSIGN(Manager); | ||
| 131 | }; | 155 | }; |
| 132 | 156 | ||
| 133 | /// Initialize ServiceManager | 157 | /// Initialize ServiceManager |
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 579ea4a34..9437868c5 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp | |||
| @@ -12,11 +12,11 @@ | |||
| 12 | 12 | ||
| 13 | namespace SRV { | 13 | namespace SRV { |
| 14 | 14 | ||
| 15 | void Initialize() { | 15 | void Initialize(Service::Interface* self) { |
| 16 | NOTICE_LOG(OSHLE, "SRV::Sync - Initialize"); | 16 | NOTICE_LOG(OSHLE, "SRV::Sync - Initialize"); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | void GetServiceHandle() { | 19 | void GetServiceHandle(Service::Interface* self) { |
| 20 | Syscall::Result res = 0; | 20 | Syscall::Result res = 0; |
| 21 | u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); | 21 | u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset); |
| 22 | 22 | ||
| @@ -37,7 +37,7 @@ void GetServiceHandle() { | |||
| 37 | //return res; | 37 | //return res; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | const HLE::FunctionDef FunctionTable[] = { | 40 | const Interface::FunctionInfo FunctionTable[] = { |
| 41 | {0x00010002, Initialize, "Initialize"}, | 41 | {0x00010002, Initialize, "Initialize"}, |
| 42 | {0x00020000, NULL, "GetProcSemaphore"}, | 42 | {0x00020000, NULL, "GetProcSemaphore"}, |
| 43 | {0x00030100, NULL, "RegisterService"}, | 43 | {0x00030100, NULL, "RegisterService"}, |
diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h index d9ac8fc88..760c976b4 100644 --- a/src/core/hle/service/srv.h +++ b/src/core/hle/service/srv.h | |||
| @@ -32,9 +32,6 @@ public: | |||
| 32 | */ | 32 | */ |
| 33 | Syscall::Result Sync(); | 33 | Syscall::Result Sync(); |
| 34 | 34 | ||
| 35 | private: | ||
| 36 | |||
| 37 | DISALLOW_COPY_AND_ASSIGN(Interface); | ||
| 38 | }; | 35 | }; |
| 39 | 36 | ||
| 40 | } // namespace | 37 | } // namespace |
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp index e5533a741..df6412743 100644 --- a/src/core/hle/syscall.cpp +++ b/src/core/hle/syscall.cpp | |||
| @@ -15,14 +15,29 @@ | |||
| 15 | 15 | ||
| 16 | namespace Syscall { | 16 | namespace Syscall { |
| 17 | 17 | ||
| 18 | enum ControlMemoryOperation { | ||
| 19 | MEMORY_OPERATION_HEAP = 0x00000003, | ||
| 20 | MEMORY_OPERATION_GSP_HEAP = 0x00010003, | ||
| 21 | }; | ||
| 22 | |||
| 23 | enum MapMemoryPermission { | ||
| 24 | MEMORY_PERMISSION_UNMAP = 0x00000000, | ||
| 25 | MEMORY_PERMISSION_NORMAL = 0x00000001, | ||
| 26 | }; | ||
| 27 | |||
| 18 | /// Map application or GSP heap memory | 28 | /// Map application or GSP heap memory |
| 19 | Result ControlMemory(void* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions) { | 29 | Result ControlMemory(u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { |
| 20 | u32 virtual_address = 0x00000000; | 30 | u32 virtual_address = 0x00000000; |
| 21 | 31 | ||
| 22 | switch (operation) { | 32 | switch (operation) { |
| 23 | 33 | ||
| 24 | // Map GSP heap memory? | 34 | // Map normal heap memory |
| 25 | case 0x00010003: | 35 | case MEMORY_OPERATION_HEAP: |
| 36 | virtual_address = Memory::MapBlock_Heap(size, operation, permissions); | ||
| 37 | break; | ||
| 38 | |||
| 39 | // Map GSP heap memory | ||
| 40 | case MEMORY_OPERATION_GSP_HEAP: | ||
| 26 | virtual_address = Memory::MapBlock_HeapGSP(size, operation, permissions); | 41 | virtual_address = Memory::MapBlock_HeapGSP(size, operation, permissions); |
| 27 | break; | 42 | break; |
| 28 | 43 | ||
| @@ -31,7 +46,22 @@ Result ControlMemory(void* outaddr, u32 addr0, u32 addr1, u32 size, u32 operatio | |||
| 31 | ERROR_LOG(OSHLE, "Unknown ControlMemory operation %08X", operation); | 46 | ERROR_LOG(OSHLE, "Unknown ControlMemory operation %08X", operation); |
| 32 | } | 47 | } |
| 33 | 48 | ||
| 34 | Core::g_app_core->SetReg(1, Memory::MapBlock_HeapGSP(size, operation, permissions)); | 49 | Core::g_app_core->SetReg(1, virtual_address); |
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | /// Maps a memory block to specified address | ||
| 54 | Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) { | ||
| 55 | int x = 0; | ||
| 56 | switch (mypermissions) { | ||
| 57 | case MEMORY_PERMISSION_NORMAL: | ||
| 58 | case MEMORY_PERMISSION_NORMAL + 1: | ||
| 59 | case MEMORY_PERMISSION_NORMAL + 2: | ||
| 60 | Memory::MapBlock_Shared(memblock, addr, mypermissions); | ||
| 61 | break; | ||
| 62 | default: | ||
| 63 | ERROR_LOG(OSHLE, "Unknown MapMemoryBlock permissions %08X", mypermissions); | ||
| 64 | } | ||
| 35 | return 0; | 65 | return 0; |
| 36 | } | 66 | } |
| 37 | 67 | ||
| @@ -63,7 +93,7 @@ Result WaitSynchronization1(Handle handle, s64 nanoseconds) { | |||
| 63 | 93 | ||
| 64 | const HLE::FunctionDef Syscall_Table[] = { | 94 | const HLE::FunctionDef Syscall_Table[] = { |
| 65 | {0x00, NULL, "Unknown"}, | 95 | {0x00, NULL, "Unknown"}, |
| 66 | {0x01, WrapI_VUUUUU<ControlMemory>, "ControlMemory"}, | 96 | {0x01, WrapI_UUUUU<ControlMemory>, "ControlMemory"}, |
| 67 | {0x02, NULL, "QueryMemory"}, | 97 | {0x02, NULL, "QueryMemory"}, |
| 68 | {0x03, NULL, "ExitProcess"}, | 98 | {0x03, NULL, "ExitProcess"}, |
| 69 | {0x04, NULL, "GetProcessAffinityMask"}, | 99 | {0x04, NULL, "GetProcessAffinityMask"}, |
| @@ -93,7 +123,7 @@ const HLE::FunctionDef Syscall_Table[] = { | |||
| 93 | {0x1C, NULL, "CancelTimer"}, | 123 | {0x1C, NULL, "CancelTimer"}, |
| 94 | {0x1D, NULL, "ClearTimer"}, | 124 | {0x1D, NULL, "ClearTimer"}, |
| 95 | {0x1E, NULL, "CreateMemoryBlock"}, | 125 | {0x1E, NULL, "CreateMemoryBlock"}, |
| 96 | {0x1F, NULL, "MapMemoryBlock"}, | 126 | {0x1F, WrapI_UUUU<MapMemoryBlock>, "MapMemoryBlock"}, |
| 97 | {0x20, NULL, "UnmapMemoryBlock"}, | 127 | {0x20, NULL, "UnmapMemoryBlock"}, |
| 98 | {0x21, NULL, "CreateAddressArbiter"}, | 128 | {0x21, NULL, "CreateAddressArbiter"}, |
| 99 | {0x22, NULL, "ArbitrateAddress"}, | 129 | {0x22, NULL, "ArbitrateAddress"}, |
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index 16bd70125..85669ae7f 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp | |||
| @@ -12,49 +12,42 @@ | |||
| 12 | namespace HW { | 12 | namespace HW { |
| 13 | 13 | ||
| 14 | enum { | 14 | enum { |
| 15 | ADDRESS_CONFIG = 0x10000000, | 15 | VADDR_HASH = 0x1EC01000, |
| 16 | ADDRESS_IRQ = 0x10001000, | 16 | VADDR_CSND = 0x1EC03000, |
| 17 | ADDRESS_NDMA = 0x10002000, | 17 | VADDR_DSP = 0x1EC40000, |
| 18 | ADDRESS_TIMER = 0x10003000, | 18 | VADDR_PDN = 0x1EC41000, |
| 19 | ADDRESS_CTRCARD = 0x10004000, | 19 | VADDR_CODEC = 0x1EC41000, |
| 20 | ADDRESS_CTRCARD_2 = 0x10005000, | 20 | VADDR_SPI = 0x1EC42000, |
| 21 | ADDRESS_SDMC_NAND = 0x10006000, | 21 | VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM? |
| 22 | ADDRESS_SDMC_NAND_2 = 0x10007000, // Apparently not used on retail | 22 | VADDR_I2C = 0x1EC44000, |
| 23 | ADDRESS_PXI = 0x10008000, | 23 | VADDR_CODEC_2 = 0x1EC45000, |
| 24 | ADDRESS_AES = 0x10009000, | 24 | VADDR_HID = 0x1EC46000, |
| 25 | ADDRESS_SHA = 0x1000A000, | 25 | VADDR_PAD = 0x1EC46000, |
| 26 | ADDRESS_RSA = 0x1000B000, | 26 | VADDR_PTM = 0x1EC46000, |
| 27 | ADDRESS_XDMA = 0x1000C000, | 27 | VADDR_GPIO = 0x1EC47000, |
| 28 | ADDRESS_SPICARD = 0x1000D800, | 28 | VADDR_I2C_2 = 0x1EC48000, |
| 29 | ADDRESS_CONFIG_2 = 0x10010000, | 29 | VADDR_SPI_3 = 0x1EC60000, |
| 30 | ADDRESS_HASH = 0x10101000, | 30 | VADDR_I2C_3 = 0x1EC61000, |
| 31 | ADDRESS_CSND = 0x10103000, | 31 | VADDR_MIC = 0x1EC62000, |
| 32 | ADDRESS_DSP = 0x10140000, | 32 | VADDR_PXI = 0x1EC63000, // 0xFFFD2000 |
| 33 | ADDRESS_PDN = 0x10141000, | 33 | //VADDR_NTRCARD |
| 34 | ADDRESS_CODEC = 0x10141000, | 34 | VADDR_CDMA = 0xFFFDA000, // CoreLink DMA-330? Info |
| 35 | ADDRESS_SPI = 0x10142000, | 35 | VADDR_DSP_2 = 0x1ED03000, |
| 36 | ADDRESS_SPI_2 = 0x10143000, | 36 | VADDR_HASH_2 = 0x1EE01000, |
| 37 | ADDRESS_I2C = 0x10144000, | 37 | VADDR_LCD = 0x1EF00000, |
| 38 | ADDRESS_CODEC_2 = 0x10145000, | ||
| 39 | ADDRESS_HID = 0x10146000, | ||
| 40 | ADDRESS_PAD = 0x10146000, | ||
| 41 | ADDRESS_PTM = 0x10146000, | ||
| 42 | ADDRESS_I2C_2 = 0x10148000, | ||
| 43 | ADDRESS_SPI_3 = 0x10160000, | ||
| 44 | ADDRESS_I2C_3 = 0x10161000, | ||
| 45 | ADDRESS_MIC = 0x10162000, | ||
| 46 | ADDRESS_PXI_2 = 0x10163000, | ||
| 47 | ADDRESS_NTRCARD = 0x10164000, | ||
| 48 | ADDRESS_DSP_2 = 0x10203000, | ||
| 49 | ADDRESS_HASH_2 = 0x10301000, | ||
| 50 | }; | 38 | }; |
| 51 | 39 | ||
| 52 | template <typename T> | 40 | template <typename T> |
| 53 | inline void Read(T &var, const u32 addr) { | 41 | inline void Read(T &var, const u32 addr) { |
| 54 | switch (addr & 0xFFFFF000) { | 42 | switch (addr & 0xFFFFF000) { |
| 55 | 43 | ||
| 56 | case ADDRESS_NDMA: | 44 | // TODO(bunnei): What is the virtual address of NDMA? |
| 57 | NDMA::Read(var, addr); | 45 | // case VADDR_NDMA: |
| 46 | // NDMA::Read(var, addr); | ||
| 47 | // break; | ||
| 48 | |||
| 49 | case VADDR_LCD: | ||
| 50 | LCD::Read(var, addr); | ||
| 58 | break; | 51 | break; |
| 59 | 52 | ||
| 60 | default: | 53 | default: |
| @@ -66,8 +59,13 @@ template <typename T> | |||
| 66 | inline void Write(u32 addr, const T data) { | 59 | inline void Write(u32 addr, const T data) { |
| 67 | switch (addr & 0xFFFFF000) { | 60 | switch (addr & 0xFFFFF000) { |
| 68 | 61 | ||
| 69 | case ADDRESS_NDMA: | 62 | // TODO(bunnei): What is the virtual address of NDMA? |
| 70 | NDMA::Write(addr, data); | 63 | // case VADDR_NDMA |
| 64 | // NDMA::Write(addr, data); | ||
| 65 | // break; | ||
| 66 | |||
| 67 | case VADDR_LCD: | ||
| 68 | LCD::Write(addr, data); | ||
| 71 | break; | 69 | break; |
| 72 | 70 | ||
| 73 | default: | 71 | default: |
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp index 3013673f8..6468053f2 100644 --- a/src/core/hw/lcd.cpp +++ b/src/core/hw/lcd.cpp | |||
| @@ -6,24 +6,126 @@ | |||
| 6 | #include "common/log.h" | 6 | #include "common/log.h" |
| 7 | 7 | ||
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/mem_map.h" | ||
| 9 | #include "core/hw/lcd.h" | 10 | #include "core/hw/lcd.h" |
| 10 | 11 | ||
| 11 | #include "video_core/video_core.h" | 12 | #include "video_core/video_core.h" |
| 12 | 13 | ||
| 13 | namespace LCD { | 14 | namespace LCD { |
| 14 | 15 | ||
| 16 | Registers g_regs; | ||
| 17 | |||
| 15 | static const u32 kFrameTicks = 268123480 / 60; ///< 268MHz / 60 frames per second | 18 | static const u32 kFrameTicks = 268123480 / 60; ///< 268MHz / 60 frames per second |
| 16 | 19 | ||
| 17 | u64 g_last_ticks = 0; ///< Last CPU ticks | 20 | u64 g_last_ticks = 0; ///< Last CPU ticks |
| 18 | 21 | ||
| 22 | /** | ||
| 23 | * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM | ||
| 24 | * @param | ||
| 25 | */ | ||
| 26 | void SetFramebufferLocation(const FramebufferLocation mode) { | ||
| 27 | switch (mode) { | ||
| 28 | case FRAMEBUFFER_LOCATION_FCRAM: | ||
| 29 | g_regs.framebuffer_top_left_1 = PADDR_TOP_LEFT_FRAME1; | ||
| 30 | g_regs.framebuffer_top_left_2 = PADDR_TOP_LEFT_FRAME2; | ||
| 31 | g_regs.framebuffer_top_right_1 = PADDR_TOP_RIGHT_FRAME1; | ||
| 32 | g_regs.framebuffer_top_right_2 = PADDR_TOP_RIGHT_FRAME2; | ||
| 33 | g_regs.framebuffer_sub_left_1 = PADDR_SUB_FRAME1; | ||
| 34 | //g_regs.framebuffer_sub_left_2 = unknown; | ||
| 35 | g_regs.framebuffer_sub_right_1 = PADDR_SUB_FRAME2; | ||
| 36 | //g_regs.framebufferr_sub_right_2 = unknown; | ||
| 37 | break; | ||
| 38 | |||
| 39 | case FRAMEBUFFER_LOCATION_VRAM: | ||
| 40 | g_regs.framebuffer_top_left_1 = PADDR_VRAM_TOP_LEFT_FRAME1; | ||
| 41 | g_regs.framebuffer_top_left_2 = PADDR_VRAM_TOP_LEFT_FRAME2; | ||
| 42 | g_regs.framebuffer_top_right_1 = PADDR_VRAM_TOP_RIGHT_FRAME1; | ||
| 43 | g_regs.framebuffer_top_right_2 = PADDR_VRAM_TOP_RIGHT_FRAME2; | ||
| 44 | g_regs.framebuffer_sub_left_1 = PADDR_VRAM_SUB_FRAME1; | ||
| 45 | //g_regs.framebuffer_sub_left_2 = unknown; | ||
| 46 | g_regs.framebuffer_sub_right_1 = PADDR_VRAM_SUB_FRAME2; | ||
| 47 | //g_regs.framebufferr_sub_right_2 = unknown; | ||
| 48 | break; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Gets the location of the framebuffers | ||
| 54 | * @return Location of framebuffers as FramebufferLocation enum | ||
| 55 | */ | ||
| 56 | const FramebufferLocation GetFramebufferLocation() { | ||
| 57 | if ((g_regs.framebuffer_top_right_1 & ~Memory::VRAM_MASK) == Memory::VRAM_PADDR) { | ||
| 58 | return FRAMEBUFFER_LOCATION_VRAM; | ||
| 59 | } else if ((g_regs.framebuffer_top_right_1 & ~Memory::FCRAM_MASK) == Memory::FCRAM_PADDR) { | ||
| 60 | return FRAMEBUFFER_LOCATION_FCRAM; | ||
| 61 | } else { | ||
| 62 | ERROR_LOG(LCD, "unknown framebuffer location!"); | ||
| 63 | } | ||
| 64 | return FRAMEBUFFER_LOCATION_UNKNOWN; | ||
| 65 | } | ||
| 66 | |||
| 67 | /** | ||
| 68 | * Gets a read-only pointer to a framebuffer in memory | ||
| 69 | * @param address Physical address of framebuffer | ||
| 70 | * @return Returns const pointer to raw framebuffer | ||
| 71 | */ | ||
| 72 | const u8* GetFramebufferPointer(const u32 address) { | ||
| 73 | switch (GetFramebufferLocation()) { | ||
| 74 | case FRAMEBUFFER_LOCATION_FCRAM: | ||
| 75 | return (const u8*)Memory::GetPointer(Memory::VirtualAddressFromPhysical_FCRAM(address)); | ||
| 76 | case FRAMEBUFFER_LOCATION_VRAM: | ||
| 77 | return (const u8*)Memory::GetPointer(Memory::VirtualAddressFromPhysical_VRAM(address)); | ||
| 78 | default: | ||
| 79 | ERROR_LOG(LCD, "unknown framebuffer location"); | ||
| 80 | } | ||
| 81 | return NULL; | ||
| 82 | } | ||
| 83 | |||
| 19 | template <typename T> | 84 | template <typename T> |
| 20 | inline void Read(T &var, const u32 addr) { | 85 | inline void Read(T &var, const u32 addr) { |
| 86 | switch (addr) { | ||
| 87 | case REG_FRAMEBUFFER_TOP_LEFT_1: | ||
| 88 | var = g_regs.framebuffer_top_left_1; | ||
| 89 | break; | ||
| 90 | case REG_FRAMEBUFFER_TOP_LEFT_2: | ||
| 91 | var = g_regs.framebuffer_top_left_2; | ||
| 92 | break; | ||
| 93 | case REG_FRAMEBUFFER_TOP_RIGHT_1: | ||
| 94 | var = g_regs.framebuffer_top_right_1; | ||
| 95 | break; | ||
| 96 | case REG_FRAMEBUFFER_TOP_RIGHT_2: | ||
| 97 | var = g_regs.framebuffer_top_right_2; | ||
| 98 | break; | ||
| 99 | case REG_FRAMEBUFFER_SUB_LEFT_1: | ||
| 100 | var = g_regs.framebuffer_sub_left_1; | ||
| 101 | break; | ||
| 102 | case REG_FRAMEBUFFER_SUB_RIGHT_1: | ||
| 103 | var = g_regs.framebuffer_sub_right_1; | ||
| 104 | break; | ||
| 105 | default: | ||
| 106 | ERROR_LOG(LCD, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); | ||
| 107 | break; | ||
| 108 | } | ||
| 109 | |||
| 21 | } | 110 | } |
| 22 | 111 | ||
| 23 | template <typename T> | 112 | template <typename T> |
| 24 | inline void Write(u32 addr, const T data) { | 113 | inline void Write(u32 addr, const T data) { |
| 114 | ERROR_LOG(LCD, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr); | ||
| 25 | } | 115 | } |
| 26 | 116 | ||
| 117 | // Explicitly instantiate template functions because we aren't defining this in the header: | ||
| 118 | |||
| 119 | template void Read<u64>(u64 &var, const u32 addr); | ||
| 120 | template void Read<u32>(u32 &var, const u32 addr); | ||
| 121 | template void Read<u16>(u16 &var, const u32 addr); | ||
| 122 | template void Read<u8>(u8 &var, const u32 addr); | ||
| 123 | |||
| 124 | template void Write<u64>(u32 addr, const u64 data); | ||
| 125 | template void Write<u32>(u32 addr, const u32 data); | ||
| 126 | template void Write<u16>(u32 addr, const u16 data); | ||
| 127 | template void Write<u8>(u32 addr, const u8 data); | ||
| 128 | |||
| 27 | /// Update hardware | 129 | /// Update hardware |
| 28 | void Update() { | 130 | void Update() { |
| 29 | u64 current_ticks = Core::g_app_core->GetTicks(); | 131 | u64 current_ticks = Core::g_app_core->GetTicks(); |
| @@ -37,6 +139,7 @@ void Update() { | |||
| 37 | /// Initialize hardware | 139 | /// Initialize hardware |
| 38 | void Init() { | 140 | void Init() { |
| 39 | g_last_ticks = Core::g_app_core->GetTicks(); | 141 | g_last_ticks = Core::g_app_core->GetTicks(); |
| 142 | SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM); | ||
| 40 | NOTICE_LOG(LCD, "initialized OK"); | 143 | NOTICE_LOG(LCD, "initialized OK"); |
| 41 | } | 144 | } |
| 42 | 145 | ||
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h index 386ed6004..2dd3b4adc 100644 --- a/src/core/hw/lcd.h +++ b/src/core/hw/lcd.h | |||
| @@ -8,6 +8,19 @@ | |||
| 8 | 8 | ||
| 9 | namespace LCD { | 9 | namespace LCD { |
| 10 | 10 | ||
| 11 | struct Registers { | ||
| 12 | u32 framebuffer_top_left_1; | ||
| 13 | u32 framebuffer_top_left_2; | ||
| 14 | u32 framebuffer_top_right_1; | ||
| 15 | u32 framebuffer_top_right_2; | ||
| 16 | u32 framebuffer_sub_left_1; | ||
| 17 | u32 framebuffer_sub_left_2; | ||
| 18 | u32 framebuffer_sub_right_1; | ||
| 19 | u32 framebuffer_sub_right_2; | ||
| 20 | }; | ||
| 21 | |||
| 22 | extern Registers g_regs; | ||
| 23 | |||
| 11 | enum { | 24 | enum { |
| 12 | TOP_ASPECT_X = 0x5, | 25 | TOP_ASPECT_X = 0x5, |
| 13 | TOP_ASPECT_Y = 0x3, | 26 | TOP_ASPECT_Y = 0x3, |
| @@ -16,15 +29,61 @@ enum { | |||
| 16 | TOP_WIDTH = 400, | 29 | TOP_WIDTH = 400, |
| 17 | BOTTOM_WIDTH = 320, | 30 | BOTTOM_WIDTH = 320, |
| 18 | 31 | ||
| 19 | FRAMEBUFFER_SEL = 0x20184E59, | 32 | // Physical addresses in FCRAM used by ARM9 applications - these are correct for real hardware |
| 20 | TOP_LEFT_FRAME1 = 0x20184E60, | 33 | PADDR_FRAMEBUFFER_SEL = 0x20184E59, |
| 21 | TOP_LEFT_FRAME2 = 0x201CB370, | 34 | PADDR_TOP_LEFT_FRAME1 = 0x20184E60, |
| 22 | TOP_RIGHT_FRAME1 = 0x20282160, | 35 | PADDR_TOP_LEFT_FRAME2 = 0x201CB370, |
| 23 | TOP_RIGHT_FRAME2 = 0x202C8670, | 36 | PADDR_TOP_RIGHT_FRAME1 = 0x20282160, |
| 24 | SUB_FRAME1 = 0x202118E0, | 37 | PADDR_TOP_RIGHT_FRAME2 = 0x202C8670, |
| 25 | SUB_FRAME2 = 0x20249CF0, | 38 | PADDR_SUB_FRAME1 = 0x202118E0, |
| 39 | PADDR_SUB_FRAME2 = 0x20249CF0, | ||
| 40 | |||
| 41 | // Physical addresses in VRAM - I'm not sure how these are actually allocated (so not real) | ||
| 42 | PADDR_VRAM_FRAMEBUFFER_SEL = 0x18184E59, | ||
| 43 | PADDR_VRAM_TOP_LEFT_FRAME1 = 0x18184E60, | ||
| 44 | PADDR_VRAM_TOP_LEFT_FRAME2 = 0x181CB370, | ||
| 45 | PADDR_VRAM_TOP_RIGHT_FRAME1 = 0x18282160, | ||
| 46 | PADDR_VRAM_TOP_RIGHT_FRAME2 = 0x182C8670, | ||
| 47 | PADDR_VRAM_SUB_FRAME1 = 0x182118E0, | ||
| 48 | PADDR_VRAM_SUB_FRAME2 = 0x18249CF0, | ||
| 49 | }; | ||
| 50 | |||
| 51 | enum { | ||
| 52 | REG_FRAMEBUFFER_TOP_LEFT_1 = 0x1EF00468, // Main LCD, first framebuffer for 3D left | ||
| 53 | REG_FRAMEBUFFER_TOP_LEFT_2 = 0x1EF0046C, // Main LCD, second framebuffer for 3D left | ||
| 54 | REG_FRAMEBUFFER_TOP_RIGHT_1 = 0x1EF00494, // Main LCD, first framebuffer for 3D right | ||
| 55 | REG_FRAMEBUFFER_TOP_RIGHT_2 = 0x1EF00498, // Main LCD, second framebuffer for 3D right | ||
| 56 | REG_FRAMEBUFFER_SUB_LEFT_1 = 0x1EF00568, // Sub LCD, first framebuffer | ||
| 57 | REG_FRAMEBUFFER_SUB_LEFT_2 = 0x1EF0056C, // Sub LCD, second framebuffer | ||
| 58 | REG_FRAMEBUFFER_SUB_RIGHT_1 = 0x1EF00594, // Sub LCD, unused first framebuffer | ||
| 59 | REG_FRAMEBUFFER_SUB_RIGHT_2 = 0x1EF00598, // Sub LCD, unused second framebuffer | ||
| 60 | }; | ||
| 61 | |||
| 62 | /// Framebuffer location | ||
| 63 | enum FramebufferLocation { | ||
| 64 | FRAMEBUFFER_LOCATION_UNKNOWN, ///< Framebuffer location is unknown | ||
| 65 | FRAMEBUFFER_LOCATION_FCRAM, ///< Framebuffer is in the GSP heap | ||
| 66 | FRAMEBUFFER_LOCATION_VRAM, ///< Framebuffer is in VRAM | ||
| 26 | }; | 67 | }; |
| 27 | 68 | ||
| 69 | /** | ||
| 70 | * Sets whether the framebuffers are in the GSP heap (FCRAM) or VRAM | ||
| 71 | * @param | ||
| 72 | */ | ||
| 73 | void SetFramebufferLocation(const FramebufferLocation mode); | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Gets a read-only pointer to a framebuffer in memory | ||
| 77 | * @param address Physical address of framebuffer | ||
| 78 | * @return Returns const pointer to raw framebuffer | ||
| 79 | */ | ||
| 80 | const u8* GetFramebufferPointer(const u32 address); | ||
| 81 | |||
| 82 | /** | ||
| 83 | * Gets the location of the framebuffers | ||
| 84 | */ | ||
| 85 | const FramebufferLocation GetFramebufferLocation(); | ||
| 86 | |||
| 28 | template <typename T> | 87 | template <typename T> |
| 29 | inline void Read(T &var, const u32 addr); | 88 | inline void Read(T &var, const u32 addr); |
| 30 | 89 | ||
diff --git a/src/core/mem_map.cpp b/src/core/mem_map.cpp index 180829239..96245e320 100644 --- a/src/core/mem_map.cpp +++ b/src/core/mem_map.cpp | |||
| @@ -16,23 +16,25 @@ u8* g_base = NULL; ///< The base pointer to the aut | |||
| 16 | 16 | ||
| 17 | MemArena g_arena; ///< The MemArena class | 17 | MemArena g_arena; ///< The MemArena class |
| 18 | 18 | ||
| 19 | u8* g_heap_gsp = NULL; ///< GSP heap (main memory) | ||
| 20 | u8* g_heap = NULL; ///< Application heap (main memory) | 19 | u8* g_heap = NULL; ///< Application heap (main memory) |
| 20 | u8* g_heap_gsp = NULL; ///< GSP heap (main memory) | ||
| 21 | u8* g_vram = NULL; ///< Video memory (VRAM) pointer | 21 | u8* g_vram = NULL; ///< Video memory (VRAM) pointer |
| 22 | u8* g_shared_mem = NULL; ///< Shared memory | ||
| 22 | 23 | ||
| 23 | u8* g_physical_bootrom = NULL; ///< Bootrom physical memory | 24 | u8* g_physical_bootrom = NULL; ///< Bootrom physical memory |
| 24 | u8* g_uncached_bootrom = NULL; | 25 | u8* g_uncached_bootrom = NULL; |
| 25 | 26 | ||
| 26 | u8* g_physical_fcram = NULL; ///< Main physical memory (FCRAM) | 27 | u8* g_physical_fcram = NULL; ///< Main physical memory (FCRAM) |
| 27 | u8* g_physical_heap_gsp = NULL; | 28 | u8* g_physical_heap_gsp = NULL; ///< GSP heap physical memory |
| 28 | u8* g_physical_vram = NULL; ///< Video physical memory (VRAM) | 29 | u8* g_physical_vram = NULL; ///< Video physical memory (VRAM) |
| 29 | u8* g_physical_scratchpad = NULL; ///< Scratchpad memory used for main thread stack | 30 | u8* g_physical_shared_mem = NULL; ///< Physical shared memory |
| 30 | 31 | ||
| 31 | // We don't declare the IO region in here since its handled by other means. | 32 | // We don't declare the IO region in here since its handled by other means. |
| 32 | static MemoryView g_views[] = { | 33 | static MemoryView g_views[] = { |
| 33 | {&g_vram, &g_physical_vram, VRAM_VADDR, VRAM_SIZE, 0}, | 34 | {&g_vram, &g_physical_vram, VRAM_VADDR, VRAM_SIZE, 0}, |
| 34 | {&g_heap_gsp, &g_physical_heap_gsp, HEAP_GSP_VADDR, HEAP_GSP_SIZE, 0}, | 35 | {&g_heap, &g_physical_fcram, HEAP_VADDR, HEAP_SIZE, MV_IS_PRIMARY_RAM}, |
| 35 | {&g_heap, &g_physical_fcram, HEAP_VADDR, HEAP_SIZE, MV_IS_PRIMARY_RAM}, | 36 | {&g_shared_mem, &g_physical_shared_mem, SHARED_MEMORY_VADDR, SHARED_MEMORY_SIZE, 0}, |
| 37 | {&g_heap_gsp, &g_physical_heap_gsp, HEAP_GSP_VADDR, HEAP_GSP_SIZE, 0}, | ||
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | /*static MemoryView views[] = | 40 | /*static MemoryView views[] = |
diff --git a/src/core/mem_map.h b/src/core/mem_map.h index ab1eb2606..c744e377e 100644 --- a/src/core/mem_map.h +++ b/src/core/mem_map.h | |||
| @@ -21,6 +21,11 @@ enum { | |||
| 21 | SCRATCHPAD_SIZE = 0x00004000, ///< Typical stack size - TODO: Read from exheader | 21 | SCRATCHPAD_SIZE = 0x00004000, ///< Typical stack size - TODO: Read from exheader |
| 22 | HEAP_GSP_SIZE = 0x02000000, ///< GSP heap size... TODO: Define correctly? | 22 | HEAP_GSP_SIZE = 0x02000000, ///< GSP heap size... TODO: Define correctly? |
| 23 | HEAP_SIZE = FCRAM_SIZE, ///< Application heap size | 23 | HEAP_SIZE = FCRAM_SIZE, ///< Application heap size |
| 24 | SHARED_MEMORY_SIZE = 0x04000000, ///< Shared memory size | ||
| 25 | HARDWARE_IO_SIZE = 0x01000000, | ||
| 26 | |||
| 27 | SHARED_MEMORY_VADDR = 0x10000000, ///< Shared memory | ||
| 28 | SHARED_MEMORY_VADDR_END = (SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE), | ||
| 24 | 29 | ||
| 25 | HEAP_PADDR = HEAP_GSP_SIZE, | 30 | HEAP_PADDR = HEAP_GSP_SIZE, |
| 26 | HEAP_PADDR_END = (HEAP_PADDR + HEAP_SIZE), | 31 | HEAP_PADDR_END = (HEAP_PADDR + HEAP_SIZE), |
| @@ -36,23 +41,34 @@ enum { | |||
| 36 | SCRATCHPAD_MASK = (SCRATCHPAD_SIZE - 1), ///< Scratchpad memory mask | 41 | SCRATCHPAD_MASK = (SCRATCHPAD_SIZE - 1), ///< Scratchpad memory mask |
| 37 | HEAP_GSP_MASK = (HEAP_GSP_SIZE - 1), | 42 | HEAP_GSP_MASK = (HEAP_GSP_SIZE - 1), |
| 38 | HEAP_MASK = (HEAP_SIZE - 1), | 43 | HEAP_MASK = (HEAP_SIZE - 1), |
| 44 | SHARED_MEMORY_MASK = (SHARED_MEMORY_SIZE - 1), | ||
| 39 | 45 | ||
| 40 | FCRAM_PADDR = 0x20000000, ///< FCRAM physical address | 46 | FCRAM_PADDR = 0x20000000, ///< FCRAM physical address |
| 41 | FCRAM_PADDR_END = (FCRAM_PADDR + FCRAM_SIZE), ///< FCRAM end of physical space | 47 | FCRAM_PADDR_END = (FCRAM_PADDR + FCRAM_SIZE), ///< FCRAM end of physical space |
| 42 | FCRAM_VADDR = 0x08000000, ///< FCRAM virtual address | 48 | FCRAM_VADDR = 0x08000000, ///< FCRAM virtual address |
| 43 | FCRAM_VADDR_END = (FCRAM_VADDR + FCRAM_SIZE), ///< FCRAM end of virtual space | 49 | FCRAM_VADDR_END = (FCRAM_VADDR + FCRAM_SIZE), ///< FCRAM end of virtual space |
| 44 | 50 | ||
| 51 | HARDWARE_IO_PADDR = 0x10000000, ///< IO physical address start | ||
| 52 | HARDWARE_IO_VADDR = 0x1EC00000, ///< IO virtual address start | ||
| 53 | HARDWARE_IO_PADDR_END = (HARDWARE_IO_PADDR + HARDWARE_IO_SIZE), | ||
| 54 | HARDWARE_IO_VADDR_END = (HARDWARE_IO_VADDR + HARDWARE_IO_SIZE), | ||
| 55 | |||
| 56 | VRAM_PADDR = 0x18000000, | ||
| 45 | VRAM_VADDR = 0x1F000000, | 57 | VRAM_VADDR = 0x1F000000, |
| 58 | VRAM_PADDR_END = (VRAM_PADDR + VRAM_SIZE), | ||
| 59 | VRAM_VADDR_END = (VRAM_VADDR + VRAM_SIZE), | ||
| 60 | |||
| 46 | SCRATCHPAD_VADDR_END = 0x10000000, | 61 | SCRATCHPAD_VADDR_END = 0x10000000, |
| 47 | SCRATCHPAD_VADDR = (SCRATCHPAD_VADDR_END - SCRATCHPAD_SIZE), ///< Stack space | 62 | SCRATCHPAD_VADDR = (SCRATCHPAD_VADDR_END - SCRATCHPAD_SIZE), ///< Stack space |
| 48 | }; | 63 | }; |
| 49 | 64 | ||
| 50 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 65 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 51 | 66 | ||
| 52 | /// Represents a block of heap memory mapped by ControlMemory | 67 | /// Represents a block of memory mapped by ControlMemory/MapMemoryBlock |
| 53 | struct HeapBlock { | 68 | struct MemoryBlock { |
| 54 | HeapBlock() : base_address(0), address(0), size(0), operation(0), permissions(0) { | 69 | MemoryBlock() : handle(0), base_address(0), address(0), size(0), operation(0), permissions(0) { |
| 55 | } | 70 | } |
| 71 | u32 handle; | ||
| 56 | u32 base_address; | 72 | u32 base_address; |
| 57 | u32 address; | 73 | u32 address; |
| 58 | u32 size; | 74 | u32 size; |
| @@ -81,6 +97,7 @@ extern u8 *g_base; | |||
| 81 | extern u8* g_heap_gsp; ///< GSP heap (main memory) | 97 | extern u8* g_heap_gsp; ///< GSP heap (main memory) |
| 82 | extern u8* g_heap; ///< Application heap (main memory) | 98 | extern u8* g_heap; ///< Application heap (main memory) |
| 83 | extern u8* g_vram; ///< Video memory (VRAM) | 99 | extern u8* g_vram; ///< Video memory (VRAM) |
| 100 | extern u8* g_shared_mem; ///< Shared memory | ||
| 84 | 101 | ||
| 85 | void Init(); | 102 | void Init(); |
| 86 | void Shutdown(); | 103 | void Shutdown(); |
| @@ -99,9 +116,25 @@ void Write32(const u32 addr, const u32 data); | |||
| 99 | u8* GetPointer(const u32 Address); | 116 | u8* GetPointer(const u32 Address); |
| 100 | 117 | ||
| 101 | /** | 118 | /** |
| 119 | * Maps a block of memory in shared memory | ||
| 120 | * @param handle Handle to map memory block for | ||
| 121 | * @param addr Address to map memory block to | ||
| 122 | * @param permissions Memory map permissions | ||
| 123 | */ | ||
| 124 | u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) ; | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Maps a block of memory on the heap | ||
| 128 | * @param size Size of block in bytes | ||
| 129 | * @param operation Memory map operation type | ||
| 130 | * @param flags Memory allocation flags | ||
| 131 | */ | ||
| 132 | u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions); | ||
| 133 | |||
| 134 | /** | ||
| 102 | * Maps a block of memory on the GSP heap | 135 | * Maps a block of memory on the GSP heap |
| 103 | * @param size Size of block in bytes | 136 | * @param size Size of block in bytes |
| 104 | * @param operation Control memory operation | 137 | * @param operation Memory map operation type |
| 105 | * @param permissions Control memory permissions | 138 | * @param permissions Control memory permissions |
| 106 | */ | 139 | */ |
| 107 | u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions); | 140 | u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions); |
| @@ -110,4 +143,16 @@ inline const char* GetCharPointer(const u32 address) { | |||
| 110 | return (const char *)GetPointer(address); | 143 | return (const char *)GetPointer(address); |
| 111 | } | 144 | } |
| 112 | 145 | ||
| 146 | inline const u32 VirtualAddressFromPhysical_FCRAM(const u32 address) { | ||
| 147 | return ((address & FCRAM_MASK) | FCRAM_VADDR); | ||
| 148 | } | ||
| 149 | |||
| 150 | inline const u32 VirtualAddressFromPhysical_IO(const u32 address) { | ||
| 151 | return (address + 0x0EB00000); | ||
| 152 | } | ||
| 153 | |||
| 154 | inline const u32 VirtualAddressFromPhysical_VRAM(const u32 address) { | ||
| 155 | return (address + 0x07000000); | ||
| 156 | } | ||
| 157 | |||
| 113 | } // namespace | 158 | } // namespace |
diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp index af4cfacbd..c8daf0df5 100644 --- a/src/core/mem_map_funcs.cpp +++ b/src/core/mem_map_funcs.cpp | |||
| @@ -12,15 +12,25 @@ | |||
| 12 | 12 | ||
| 13 | namespace Memory { | 13 | namespace Memory { |
| 14 | 14 | ||
| 15 | std::map<u32, HeapBlock> g_heap_gsp_map; | 15 | std::map<u32, MemoryBlock> g_heap_map; |
| 16 | std::map<u32, MemoryBlock> g_heap_gsp_map; | ||
| 17 | std::map<u32, MemoryBlock> g_shared_map; | ||
| 16 | 18 | ||
| 17 | /// Convert a physical address to virtual address | 19 | /// Convert a physical address to virtual address |
| 18 | u32 _AddressPhysicalToVirtual(const u32 addr) { | 20 | u32 _AddressPhysicalToVirtual(const u32 addr) { |
| 19 | // Our memory interface read/write functions assume virtual addresses. Put any physical address | 21 | // Our memory interface read/write functions assume virtual addresses. Put any physical address |
| 20 | // to virtual address translations here. This is obviously quite hacky... But we're not doing | 22 | // to virtual address translations here. This is obviously quite hacky... But we're not doing |
| 21 | // any MMU emulation yet or anything | 23 | // any MMU emulation yet or anything |
| 22 | if ((addr >= FCRAM_PADDR) && (addr < (FCRAM_PADDR_END))) { | 24 | if ((addr >= FCRAM_PADDR) && (addr < FCRAM_PADDR_END)) { |
| 23 | return (addr & FCRAM_MASK) | FCRAM_VADDR; | 25 | return VirtualAddressFromPhysical_FCRAM(addr); |
| 26 | |||
| 27 | // Hardware IO | ||
| 28 | // TODO(bunnei): FixMe | ||
| 29 | // This isn't going to work... The physical address of HARDWARE_IO conflicts with the virtual | ||
| 30 | // address of shared memory. | ||
| 31 | //} else if ((addr >= HARDWARE_IO_PADDR) && (addr < HARDWARE_IO_PADDR_END)) { | ||
| 32 | // return (addr + 0x0EB00000); | ||
| 33 | |||
| 24 | } | 34 | } |
| 25 | return addr; | 35 | return addr; |
| 26 | } | 36 | } |
| @@ -41,19 +51,24 @@ inline void _Read(T &var, const u32 addr) { | |||
| 41 | 51 | ||
| 42 | // Hardware I/O register reads | 52 | // Hardware I/O register reads |
| 43 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space | 53 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space |
| 44 | } else if ((vaddr & 0xFF000000) == 0x10000000 || (vaddr & 0xFF000000) == 0x1E000000) { | 54 | } else if ((vaddr >= HARDWARE_IO_VADDR) && (vaddr < HARDWARE_IO_VADDR_END)) { |
| 45 | HW::Read<T>(var, vaddr); | 55 | HW::Read<T>(var, vaddr); |
| 46 | 56 | ||
| 47 | // FCRAM - GSP heap | 57 | // FCRAM - GSP heap |
| 48 | } else if ((vaddr > HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { | 58 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { |
| 49 | var = *((const T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK]); | 59 | var = *((const T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK]); |
| 50 | 60 | ||
| 51 | // FCRAM - application heap | 61 | // FCRAM - application heap |
| 52 | } else if ((vaddr > HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { | 62 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { |
| 53 | var = *((const T*)&g_heap[vaddr & HEAP_MASK]); | 63 | var = *((const T*)&g_heap[vaddr & HEAP_MASK]); |
| 54 | 64 | ||
| 55 | /*else if ((vaddr & 0x3F800000) == 0x04000000) { | 65 | // Shared memory |
| 56 | var = *((const T*)&m_pVRAM[vaddr & VRAM_MASK]);*/ | 66 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { |
| 67 | var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]); | ||
| 68 | |||
| 69 | // VRAM | ||
| 70 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { | ||
| 71 | var = *((const T*)&g_vram[vaddr & VRAM_MASK]); | ||
| 57 | 72 | ||
| 58 | } else { | 73 | } else { |
| 59 | //_assert_msg_(MEMMAP, false, "unknown Read%d @ 0x%08X", sizeof(var) * 8, vaddr); | 74 | //_assert_msg_(MEMMAP, false, "unknown Read%d @ 0x%08X", sizeof(var) * 8, vaddr); |
| @@ -72,23 +87,25 @@ inline void _Write(u32 addr, const T data) { | |||
| 72 | 87 | ||
| 73 | // Hardware I/O register writes | 88 | // Hardware I/O register writes |
| 74 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space | 89 | // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space |
| 75 | } else if ((vaddr & 0xFF000000) == 0x10000000 || (vaddr & 0xFF000000) == 0x1E000000) { | 90 | } else if ((vaddr >= HARDWARE_IO_VADDR) && (vaddr < HARDWARE_IO_VADDR_END)) { |
| 76 | HW::Write<T>(vaddr, data); | 91 | HW::Write<T>(vaddr, data); |
| 77 | 92 | ||
| 78 | // FCRAM - GSP heap | 93 | // FCRAM - GSP heap |
| 79 | } else if ((vaddr > HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { | 94 | } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) { |
| 80 | *(T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK] = data; | 95 | *(T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK] = data; |
| 81 | 96 | ||
| 82 | // FCRAM - application heap | 97 | // FCRAM - application heap |
| 83 | } else if ((vaddr > HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { | 98 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { |
| 84 | *(T*)&g_heap[vaddr & HEAP_MASK] = data; | 99 | *(T*)&g_heap[vaddr & HEAP_MASK] = data; |
| 85 | 100 | ||
| 86 | } else if ((vaddr & 0xFF000000) == 0x14000000) { | 101 | // Shared memory |
| 87 | _assert_msg_(MEMMAP, false, "umimplemented write to GSP heap"); | 102 | } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { |
| 88 | } else if ((vaddr & 0xFFF00000) == 0x1EC00000) { | 103 | *(T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK] = data; |
| 89 | _assert_msg_(MEMMAP, false, "umimplemented write to IO registers"); | 104 | |
| 90 | } else if ((vaddr & 0xFF000000) == 0x1F000000) { | 105 | // VRAM |
| 91 | _assert_msg_(MEMMAP, false, "umimplemented write to VRAM"); | 106 | } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { |
| 107 | *(T*)&g_vram[vaddr & VRAM_MASK] = data; | ||
| 108 | |||
| 92 | } else if ((vaddr & 0xFFF00000) == 0x1FF00000) { | 109 | } else if ((vaddr & 0xFFF00000) == 0x1FF00000) { |
| 93 | _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); | 110 | _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); |
| 94 | } else if ((vaddr & 0xFFFF0000) == 0x1FF80000) { | 111 | } else if ((vaddr & 0xFFFF0000) == 0x1FF80000) { |
| @@ -114,19 +131,73 @@ u8 *GetPointer(const u32 addr) { | |||
| 114 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { | 131 | } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { |
| 115 | return g_heap + (vaddr & HEAP_MASK); | 132 | return g_heap + (vaddr & HEAP_MASK); |
| 116 | 133 | ||
| 134 | // Shared memory | ||
| 135 | } else if ((vaddr > SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { | ||
| 136 | return g_shared_mem + (vaddr & SHARED_MEMORY_MASK); | ||
| 137 | |||
| 138 | // VRAM | ||
| 139 | } else if ((vaddr > VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { | ||
| 140 | return g_vram + (vaddr & VRAM_MASK); | ||
| 141 | |||
| 117 | } else { | 142 | } else { |
| 118 | ERROR_LOG(MEMMAP, "Unknown GetPointer @ 0x%08x", vaddr); | 143 | ERROR_LOG(MEMMAP, "unknown GetPointer @ 0x%08x", vaddr); |
| 119 | return 0; | 144 | return 0; |
| 120 | } | 145 | } |
| 121 | } | 146 | } |
| 122 | 147 | ||
| 123 | /** | 148 | /** |
| 149 | * Maps a block of memory in shared memory | ||
| 150 | * @param handle Handle to map memory block for | ||
| 151 | * @param addr Address to map memory block to | ||
| 152 | * @param permissions Memory map permissions | ||
| 153 | */ | ||
| 154 | u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) { | ||
| 155 | MemoryBlock block; | ||
| 156 | |||
| 157 | block.handle = handle; | ||
| 158 | block.base_address = addr; | ||
| 159 | block.permissions = permissions; | ||
| 160 | |||
| 161 | if (g_shared_map.size() > 0) { | ||
| 162 | const MemoryBlock last_block = g_shared_map.rbegin()->second; | ||
| 163 | block.address = last_block.address + last_block.size; | ||
| 164 | } | ||
| 165 | g_shared_map[block.GetVirtualAddress()] = block; | ||
| 166 | |||
| 167 | return block.GetVirtualAddress(); | ||
| 168 | } | ||
| 169 | |||
| 170 | /** | ||
| 171 | * Maps a block of memory on the heap | ||
| 172 | * @param size Size of block in bytes | ||
| 173 | * @param operation Memory map operation type | ||
| 174 | * @param flags Memory allocation flags | ||
| 175 | */ | ||
| 176 | u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions) { | ||
| 177 | MemoryBlock block; | ||
| 178 | |||
| 179 | block.base_address = HEAP_VADDR; | ||
| 180 | block.size = size; | ||
| 181 | block.operation = operation; | ||
| 182 | block.permissions = permissions; | ||
| 183 | |||
| 184 | if (g_heap_map.size() > 0) { | ||
| 185 | const MemoryBlock last_block = g_heap_map.rbegin()->second; | ||
| 186 | block.address = last_block.address + last_block.size; | ||
| 187 | } | ||
| 188 | g_heap_map[block.GetVirtualAddress()] = block; | ||
| 189 | |||
| 190 | return block.GetVirtualAddress(); | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | ||
| 124 | * Maps a block of memory on the GSP heap | 194 | * Maps a block of memory on the GSP heap |
| 125 | * @param size Size of block in bytes | 195 | * @param size Size of block in bytes |
| 196 | * @param operation Memory map operation type | ||
| 126 | * @param flags Memory allocation flags | 197 | * @param flags Memory allocation flags |
| 127 | */ | 198 | */ |
| 128 | u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) { | 199 | u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) { |
| 129 | HeapBlock block; | 200 | MemoryBlock block; |
| 130 | 201 | ||
| 131 | block.base_address = HEAP_GSP_VADDR; | 202 | block.base_address = HEAP_GSP_VADDR; |
| 132 | block.size = size; | 203 | block.size = size; |
| @@ -134,7 +205,7 @@ u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) { | |||
| 134 | block.permissions = permissions; | 205 | block.permissions = permissions; |
| 135 | 206 | ||
| 136 | if (g_heap_gsp_map.size() > 0) { | 207 | if (g_heap_gsp_map.size() > 0) { |
| 137 | const HeapBlock last_block = g_heap_gsp_map.rbegin()->second; | 208 | const MemoryBlock last_block = g_heap_gsp_map.rbegin()->second; |
| 138 | block.address = last_block.address + last_block.size; | 209 | block.address = last_block.address + last_block.size; |
| 139 | } | 210 | } |
| 140 | g_heap_gsp_map[block.GetVirtualAddress()] = block; | 211 | g_heap_gsp_map[block.GetVirtualAddress()] = block; |
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index bc65bf0ce..2650620b4 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common.h" | 7 | #include "common/common.h" |
| 8 | 8 | ||
| 9 | class RendererBase { | 9 | class RendererBase : NonCopyable { |
| 10 | public: | 10 | public: |
| 11 | 11 | ||
| 12 | /// Used to reference a framebuffer | 12 | /// Used to reference a framebuffer |
| @@ -52,6 +52,4 @@ protected: | |||
| 52 | f32 m_current_fps; ///< Current framerate, should be set by the renderer | 52 | f32 m_current_fps; ///< Current framerate, should be set by the renderer |
| 53 | int m_current_frame; ///< Current frame, should be set by the renderer | 53 | int m_current_frame; ///< Current frame, should be set by the renderer |
| 54 | 54 | ||
| 55 | private: | ||
| 56 | DISALLOW_COPY_AND_ASSIGN(RendererBase); | ||
| 57 | }; | 55 | }; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index cf7b029ab..b63a73d18 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -53,12 +53,11 @@ void RendererOpenGL::SwapBuffers() { | |||
| 53 | 53 | ||
| 54 | /** | 54 | /** |
| 55 | * Helper function to flip framebuffer from left-to-right to top-to-bottom | 55 | * Helper function to flip framebuffer from left-to-right to top-to-bottom |
| 56 | * @param addr Address of framebuffer in RAM | 56 | * @param in Pointer to input raw framebuffer in V/RAM |
| 57 | * @param out Pointer to output buffer with flipped framebuffer | 57 | * @param out Pointer to output buffer with flipped framebuffer |
| 58 | * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei | 58 | * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei |
| 59 | */ | 59 | */ |
| 60 | void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out) { | 60 | void RendererOpenGL::FlipFramebuffer(const u8* in, u8* out) { |
| 61 | u8* in = Memory::GetPointer(addr); | ||
| 62 | for (int y = 0; y < VideoCore::kScreenTopHeight; y++) { | 61 | for (int y = 0; y < VideoCore::kScreenTopHeight; y++) { |
| 63 | for (int x = 0; x < VideoCore::kScreenTopWidth; x++) { | 62 | for (int x = 0; x < VideoCore::kScreenTopWidth; x++) { |
| 64 | int in_coord = (VideoCore::kScreenTopHeight * 3 * x) + (VideoCore::kScreenTopHeight * 3) | 63 | int in_coord = (VideoCore::kScreenTopHeight * 3 * x) + (VideoCore::kScreenTopHeight * 3) |
| @@ -77,10 +76,10 @@ void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out) { | |||
| 77 | * @param src_rect Source rectangle in XFB to copy | 76 | * @param src_rect Source rectangle in XFB to copy |
| 78 | * @param dst_rect Destination rectangle in output framebuffer to copy to | 77 | * @param dst_rect Destination rectangle in output framebuffer to copy to |
| 79 | */ | 78 | */ |
| 80 | void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { | 79 | void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) { |
| 81 | 80 | ||
| 82 | FlipFramebuffer(LCD::TOP_RIGHT_FRAME1, m_xfb_top_flipped); | 81 | FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_top_left_1), m_xfb_top_flipped); |
| 83 | FlipFramebuffer(LCD::SUB_FRAME1, m_xfb_bottom_flipped); | 82 | FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_sub_left_1), m_xfb_bottom_flipped); |
| 84 | 83 | ||
| 85 | // Blit the top framebuffer | 84 | // Blit the top framebuffer |
| 86 | // ------------------------ | 85 | // ------------------------ |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 00aa17649..4c0b6e59d 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -55,11 +55,11 @@ private: | |||
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | * Helper function to flip framebuffer from left-to-right to top-to-bottom | 57 | * Helper function to flip framebuffer from left-to-right to top-to-bottom |
| 58 | * @param addr Address of framebuffer in RAM | 58 | * @param in Pointer to input raw framebuffer in V/RAM |
| 59 | * @param out Pointer to output buffer with flipped framebuffer | 59 | * @param out Pointer to output buffer with flipped framebuffer |
| 60 | * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei | 60 | * @todo Early on hack... I'd like to find a more efficient way of doing this /bunnei |
| 61 | */ | 61 | */ |
| 62 | void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out); | 62 | void RendererOpenGL::FlipFramebuffer(const u8* in, u8* out); |
| 63 | 63 | ||
| 64 | 64 | ||
| 65 | EmuWindow* m_render_window; ///< Handle to render window | 65 | EmuWindow* m_render_window; ///< Handle to render window |
| @@ -87,5 +87,4 @@ private: | |||
| 87 | u8 m_xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4]; | 87 | u8 m_xfb_top_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4]; |
| 88 | u8 m_xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4]; | 88 | u8 m_xfb_bottom_flipped[VideoCore::kScreenTopWidth * VideoCore::kScreenTopWidth * 4]; |
| 89 | 89 | ||
| 90 | DISALLOW_COPY_AND_ASSIGN(RendererOpenGL); | ||
| 91 | }; \ No newline at end of file | 90 | }; \ No newline at end of file |