From b1c8bad9a646b2f4ae1b03c45844d060d8889aab Mon Sep 17 00:00:00 2001
From: Tony Wasserka <NeoBrainX@gmail.com>
Date: Sat, 17 May 2014 22:07:06 +0200
Subject: [PATCH] Pica: Add command list registers.

---
 src/core/hw/lcd.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++---
 src/core/hw/lcd.h   | 12 ++++++++++--
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
index b57563a73a..61ee99c1fd 100644
--- a/src/core/hw/lcd.cpp
+++ b/src/core/hw/lcd.cpp
@@ -7,11 +7,11 @@
 
 #include "core/core.h"
 #include "core/mem_map.h"
+#include "core/hle/kernel/thread.h"
 #include "core/hw/lcd.h"
 
 #include "video_core/video_core.h"
 
-#include "core/hle/kernel/thread.h"
 
 namespace LCD {
 
@@ -89,31 +89,70 @@ inline void Read(T &var, const u32 addr) {
     case REG_FRAMEBUFFER_TOP_LEFT_1:
         var = g_regs.framebuffer_top_left_1;
         break;
+
     case REG_FRAMEBUFFER_TOP_LEFT_2:
         var = g_regs.framebuffer_top_left_2;
         break;
+
     case REG_FRAMEBUFFER_TOP_RIGHT_1:
         var = g_regs.framebuffer_top_right_1;
         break;
+
     case REG_FRAMEBUFFER_TOP_RIGHT_2:
         var = g_regs.framebuffer_top_right_2;
         break;
+
     case REG_FRAMEBUFFER_SUB_LEFT_1:
         var = g_regs.framebuffer_sub_left_1;
         break;
+
     case REG_FRAMEBUFFER_SUB_RIGHT_1:
         var = g_regs.framebuffer_sub_right_1;
         break;
+
+    case CommandListSize:
+        var = g_regs.command_list_size;
+        break;
+
+    case CommandListAddress:
+        var = g_regs.command_list_address;
+        break;
+
+    case ProcessCommandList:
+        var = g_regs.command_processing_enabled;
+        break;
+
     default:
         ERROR_LOG(LCD, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
         break;
     }
-    
 }
 
 template <typename T>
 inline void Write(u32 addr, const T data) {
-    ERROR_LOG(LCD, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
+    switch (addr) {
+    case CommandListSize:
+        g_regs.command_list_size = data;
+        break;
+
+    case CommandListAddress:
+        g_regs.command_list_address = data;
+        break;
+
+    case ProcessCommandList:
+        g_regs.command_processing_enabled = data;
+        if (g_regs.command_processing_enabled & 1)
+        {
+            // u32* buffer = (u32*)Memory::GetPointer(g_regs.command_list_address << 3);
+            ERROR_LOG(LCD, "Beginning %x bytes of commands from address %x", g_regs.command_list_size, g_regs.command_list_address << 3);
+            // TODO: Process command list!
+        }
+        break;
+
+    default:
+        ERROR_LOG(LCD, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
+        break;
+    }
 }
 
 // Explicitly instantiate template functions because we aren't defining this in the header:
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h
index 2dd3b4adc3..2ae852d7c7 100644
--- a/src/core/hw/lcd.h
+++ b/src/core/hw/lcd.h
@@ -17,6 +17,10 @@ struct Registers {
     u32 framebuffer_sub_left_2;
     u32 framebuffer_sub_right_1;
     u32 framebuffer_sub_right_2;
+
+    u32 command_list_size;
+    u32 command_list_address;
+    u32 command_processing_enabled;
 };
 
 extern Registers g_regs;
@@ -24,7 +28,7 @@ extern Registers g_regs;
 enum {
     TOP_ASPECT_X        = 0x5,
     TOP_ASPECT_Y        = 0x3,
-    
+
     TOP_HEIGHT          = 240,
     TOP_WIDTH           = 400,
     BOTTOM_WIDTH        = 320,
@@ -57,12 +61,16 @@ enum {
     REG_FRAMEBUFFER_SUB_LEFT_2  = 0x1EF0056C,   // Sub LCD, second framebuffer
     REG_FRAMEBUFFER_SUB_RIGHT_1 = 0x1EF00594,   // Sub LCD, unused first framebuffer
     REG_FRAMEBUFFER_SUB_RIGHT_2 = 0x1EF00598,   // Sub LCD, unused second framebuffer
+
+    CommandListSize         = 0x1EF018E0,
+    CommandListAddress      = 0x1EF018E8,
+    ProcessCommandList      = 0x1EF018F0,
 };
 
 /// Framebuffer location
 enum FramebufferLocation {
     FRAMEBUFFER_LOCATION_UNKNOWN,   ///< Framebuffer location is unknown
-    FRAMEBUFFER_LOCATION_FCRAM,  ///< Framebuffer is in the GSP heap
+    FRAMEBUFFER_LOCATION_FCRAM,     ///< Framebuffer is in the GSP heap
     FRAMEBUFFER_LOCATION_VRAM,      ///< Framebuffer is in VRAM
 };