summaryrefslogtreecommitdiff
path: root/src/core/hw/gpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hw/gpu.cpp')
-rw-r--r--src/core/hw/gpu.cpp47
1 files changed, 23 insertions, 24 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index d94c2329b..fd40f8ac0 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -19,7 +19,7 @@
19 19
20namespace GPU { 20namespace GPU {
21 21
22RegisterSet<u32, Regs> g_regs; 22Regs g_regs;
23 23
24u32 g_cur_line = 0; ///< Current vertical screen line 24u32 g_cur_line = 0; ///< Current vertical screen line
25u64 g_last_line_ticks = 0; ///< CPU tick count from last vertical screen line 25u64 g_last_line_ticks = 0; ///< CPU tick count from last vertical screen line
@@ -32,8 +32,8 @@ void SetFramebufferLocation(const FramebufferLocation mode) {
32 switch (mode) { 32 switch (mode) {
33 case FRAMEBUFFER_LOCATION_FCRAM: 33 case FRAMEBUFFER_LOCATION_FCRAM:
34 { 34 {
35 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 35 auto& framebuffer_top = g_regs.framebuffer_config[0];
36 auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); 36 auto& framebuffer_sub = g_regs.framebuffer_config[1];
37 37
38 framebuffer_top.address_left1 = PADDR_TOP_LEFT_FRAME1; 38 framebuffer_top.address_left1 = PADDR_TOP_LEFT_FRAME1;
39 framebuffer_top.address_left2 = PADDR_TOP_LEFT_FRAME2; 39 framebuffer_top.address_left2 = PADDR_TOP_LEFT_FRAME2;
@@ -48,8 +48,8 @@ void SetFramebufferLocation(const FramebufferLocation mode) {
48 48
49 case FRAMEBUFFER_LOCATION_VRAM: 49 case FRAMEBUFFER_LOCATION_VRAM:
50 { 50 {
51 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 51 auto& framebuffer_top = g_regs.framebuffer_config[0];
52 auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); 52 auto& framebuffer_sub = g_regs.framebuffer_config[1];
53 53
54 framebuffer_top.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1; 54 framebuffer_top.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1;
55 framebuffer_top.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2; 55 framebuffer_top.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2;
@@ -107,13 +107,12 @@ inline void Read(T &var, const u32 raw_addr) {
107 int index = addr / 4; 107 int index = addr / 4;
108 108
109 // Reads other than u32 are untested, so I'd rather have them abort than silently fail 109 // Reads other than u32 are untested, so I'd rather have them abort than silently fail
110 if (index >= Regs::NumIds || !std::is_same<T,u32>::value) 110 if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) {
111 {
112 ERROR_LOG(GPU, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); 111 ERROR_LOG(GPU, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
113 return; 112 return;
114 } 113 }
115 114
116 var = g_regs[static_cast<Regs::Id>(addr / 4)]; 115 var = g_regs[addr / 4];
117} 116}
118 117
119template <typename T> 118template <typename T>
@@ -122,22 +121,22 @@ inline void Write(u32 addr, const T data) {
122 int index = addr / 4; 121 int index = addr / 4;
123 122
124 // Writes other than u32 are untested, so I'd rather have them abort than silently fail 123 // Writes other than u32 are untested, so I'd rather have them abort than silently fail
125 if (index >= Regs::NumIds || !std::is_same<T,u32>::value) 124 if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) {
126 {
127 ERROR_LOG(GPU, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr); 125 ERROR_LOG(GPU, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
128 return; 126 return;
129 } 127 }
130 128
131 g_regs[static_cast<Regs::Id>(index)] = data; 129 g_regs[index] = data;
132 130
133 switch (static_cast<Regs::Id>(index)) { 131 switch (index) {
134 132
135 // Memory fills are triggered once the fill value is written. 133 // Memory fills are triggered once the fill value is written.
136 // NOTE: This is not verified. 134 // NOTE: This is not verified.
137 case Regs::MemoryFill + 3: 135 case GPU_REG_INDEX_WORKAROUND(memory_fill_config[0].value, 0x00004 + 0x3):
138 case Regs::MemoryFill + 7: 136 case GPU_REG_INDEX_WORKAROUND(memory_fill_config[1].value, 0x00008 + 0x3):
139 { 137 {
140 const auto& config = g_regs.Get<Regs::MemoryFill>(static_cast<Regs::Id>(index - 3)); 138 const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].value));
139 const auto& config = g_regs.memory_fill_config[is_second_filler];
141 140
142 // TODO: Not sure if this check should be done at GSP level instead 141 // TODO: Not sure if this check should be done at GSP level instead
143 if (config.address_start) { 142 if (config.address_start) {
@@ -152,9 +151,9 @@ inline void Write(u32 addr, const T data) {
152 break; 151 break;
153 } 152 }
154 153
155 case Regs::DisplayTransfer + 6: 154 case GPU_REG_INDEX(display_transfer_config.trigger):
156 { 155 {
157 const auto& config = g_regs.Get<Regs::DisplayTransfer>(); 156 const auto& config = g_regs.display_transfer_config;
158 if (config.trigger & 1) { 157 if (config.trigger & 1) {
159 u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress()); 158 u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress());
160 u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress()); 159 u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress());
@@ -221,13 +220,13 @@ inline void Write(u32 addr, const T data) {
221 break; 220 break;
222 } 221 }
223 222
224 case Regs::CommandProcessor + 4: 223 case GPU_REG_INDEX(command_processor_config.trigger):
225 { 224 {
226 const auto& config = g_regs.Get<Regs::CommandProcessor>(); 225 const auto& config = g_regs.command_processor_config;
227 if (config.trigger & 1) 226 if (config.trigger & 1)
228 { 227 {
229 // u32* buffer = (u32*)Memory::GetPointer(config.address << 3); 228 // u32* buffer = (u32*)Memory::GetPointer(config.GetPhysicalAddress());
230 ERROR_LOG(GPU, "Beginning 0x%08x bytes of commands from address 0x%08x", config.size, config.address << 3); 229 ERROR_LOG(GPU, "Beginning 0x%08x bytes of commands from address 0x%08x", config.size, config.GetPhysicalAddress());
231 // TODO: Process command list! 230 // TODO: Process command list!
232 } 231 }
233 break; 232 break;
@@ -252,7 +251,7 @@ template void Write<u8>(u32 addr, const u8 data);
252 251
253/// Update hardware 252/// Update hardware
254void Update() { 253void Update() {
255 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 254 auto& framebuffer_top = g_regs.framebuffer_config[0];
256 u64 current_ticks = Core::g_app_core->GetTicks(); 255 u64 current_ticks = Core::g_app_core->GetTicks();
257 256
258 // Synchronize line... 257 // Synchronize line...
@@ -280,8 +279,8 @@ void Init() {
280// SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM); 279// SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM);
281 SetFramebufferLocation(FRAMEBUFFER_LOCATION_VRAM); 280 SetFramebufferLocation(FRAMEBUFFER_LOCATION_VRAM);
282 281
283 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 282 auto& framebuffer_top = g_regs.framebuffer_config[0];
284 auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); 283 auto& framebuffer_sub = g_regs.framebuffer_config[1];
285 // TODO: Width should be 240 instead? 284 // TODO: Width should be 240 instead?
286 framebuffer_top.width = 480; 285 framebuffer_top.width = 480;
287 framebuffer_top.height = 400; 286 framebuffer_top.height = 400;