From a272803dcb5fdd6b0b5181cbdeff9ad68c9db934 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 26 Apr 2014 01:47:52 -0400
Subject: [PATCH] added preliminary DataSynchronizationBarrier support with
 simple DMA copy

---
 src/core/hle/mrc.cpp | 46 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/mrc.cpp b/src/core/hle/mrc.cpp
index 04d6cb5a56..5223be7c92 100644
--- a/src/core/hle/mrc.cpp
+++ b/src/core/hle/mrc.cpp
@@ -1,10 +1,43 @@
-#include "mrc.h"
-#include "hle.h"
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#include "core/hle/mrc.h"
+#include "core/hle/hle.h"
+#include "core/mem_map.h"
+#include "core/core.h"
 
 namespace HLE {
 
+enum {
+    CMD_GX_REQUEST_DMA  = 0x00000000,
+};
+
+/// Data synchronization barrier
+u32 DataSynchronizationBarrier(u32* command_buffer) {
+    u32 command = command_buffer[0];
+
+    switch (command) {
+
+    case CMD_GX_REQUEST_DMA:
+        {
+            u32* src = (u32*)Memory::GetPointer(command_buffer[1]);
+            u32* dst = (u32*)Memory::GetPointer(command_buffer[2]);
+            u32 size = command_buffer[3];
+            memcpy(dst, src, size);
+        }
+        break;
+
+    default:
+        ERROR_LOG(OSHLE, "MRC::DataSynchronizationBarrier unknown command 0x%08X", command);
+        return -1;
+    }
+
+    return 0;
+}
+
 /// Returns the coprocessor (in this case, syscore) command buffer pointer
-Addr CallGetThreadCommandBuffer() {
+Addr GetThreadCommandBuffer() {
     // Called on insruction: mrc p15, 0, r0, c13, c0, 3
     // Returns an address in OSHLE memory for the CPU to read/write to
     RETURN(CMD_BUFFER_ADDR);
@@ -16,14 +49,13 @@ u32 CallMRC(ARM11_MRC_OPERATION operation) {
     switch (operation) {
 
     case DATA_SYNCHRONIZATION_BARRIER:
-        ERROR_LOG(OSHLE, "Unimplemented MRC operation DATA_SYNCHRONIZATION_BARRIER");
-        break;
+        return DataSynchronizationBarrier((u32*)Memory::GetPointer(PARAM(0)));
 
     case CALL_GET_THREAD_COMMAND_BUFFER:
-        return CallGetThreadCommandBuffer();
+        return GetThreadCommandBuffer();
 
     default:
-        ERROR_LOG(OSHLE, "Unimplemented MRC operation 0x%02X", operation);
+        ERROR_LOG(OSHLE, "unimplemented MRC operation 0x%02X", operation);
         break;
     }
     return -1;