diff --git a/src/common/log.h b/src/common/log.h
index 432a307f06..02db8bd559 100644
--- a/src/common/log.h
+++ b/src/common/log.h
@@ -55,8 +55,8 @@ enum LOG_TYPE {
     WII_IPC_HID,
     WII_IPC_HLE,
     WII_IPC_NET,
-    WII_IPC_WC24,
-    WII_IPC_SSL,
+    NDMA,
+    HLE,
     RENDER,
     LCD,
     HW,
diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp
index 245760d0da..8e56deb8f0 100644
--- a/src/common/log_manager.cpp
+++ b/src/common/log_manager.cpp
@@ -67,9 +67,9 @@ LogManager::LogManager()
     m_Log[LogTypes::RENDER]             = new LogContainer("RENDER",            "RENDER");
     m_Log[LogTypes::LCD]                = new LogContainer("LCD",               "LCD");
     m_Log[LogTypes::WII_IPC_NET]        = new LogContainer("WII_IPC_NET",       "WII IPC NET");
-    m_Log[LogTypes::WII_IPC_WC24]       = new LogContainer("WII_IPC_WC24",      "WII IPC WC24");
-    m_Log[LogTypes::WII_IPC_SSL]        = new LogContainer("WII_IPC_SSL",       "WII IPC SSL");
-    m_Log[LogTypes::HW]                 = new LogContainer("HARDWARE",          "HARDWARE");
+    m_Log[LogTypes::NDMA]               = new LogContainer("NDMA",              "NDMA");
+    m_Log[LogTypes::HLE]                = new LogContainer("HLE",               "High Level Emulation");
+    m_Log[LogTypes::HW]                 = new LogContainer("HW",                "Hardware");
     m_Log[LogTypes::ACTIONREPLAY]       = new LogContainer("ActionReplay",      "ActionReplay");
     m_Log[LogTypes::MEMCARD_MANAGER]    = new LogContainer("MemCard Manager",   "MemCard Manager");
     m_Log[LogTypes::NETPLAY]            = new LogContainer("NETPLAY",           "Netplay");
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index a99644f118..e5a9ba3223 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -17,6 +17,22 @@
     #include <errno.h>
 #endif
 
+/// Make a string lowercase
+void LowerStr(char* str) {
+    for (int i = 0; str[i]; i++) {
+        str[i] = tolower(str[ i ]);
+    }
+}
+
+/// Make a string uppercase
+void UpperStr(char* str) {
+    for (int i=0; i < strlen(str); i++) {
+        if(str[i] >= 'a' && str[i] <= 'z') {
+            str[i] &= 0xDF;
+        }
+    }
+}
+
 // faster than sscanf
 bool AsciiToHex(const char* _szValue, u32& result)
 {
diff --git a/src/common/string_util.h b/src/common/string_util.h
index 6b7e847970..b3c99a807c 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -14,6 +14,12 @@
 
 #include "common/common.h"
 
+/// Make a string lowercase
+void LowerStr(char* str);
+
+/// Make a string uppercase
+void UpperStr(char* str);
+
 std::string StringFromFormat(const char* format, ...);
 // Cheap!
 bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args);
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index dafde83682..eee4726db0 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -42,6 +42,13 @@ public:
      */
     virtual u32 GetReg(int index) const = 0;
 
+    /**
+     * Set an ARM register
+     * @param index Register index (0-15)
+     * @param value Value to set register to
+     */
+    virtual void SetReg(int index, u32 value) = 0;
+
     /**
      * Get the current CPSR register
      * @return Returns the value of the CPSR register
@@ -59,11 +66,13 @@ public:
         return m_num_instructions;
     }
 
-private:
+protected:
     
     /// Execture next instruction
     virtual void ExecuteInstruction() = 0;
 
+private:
+
     u64 m_num_instructions;                     ///< Number of instructions executed
 
     DISALLOW_COPY_AND_ASSIGN(ARM_Interface);
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index 81f38f0169..4045779d78 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -31,30 +31,61 @@ ARM_Interpreter::ARM_Interpreter()  {
     m_state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
 }
 
-void ARM_Interpreter::SetPC(u32 pc) {
-    m_state->pc = m_state->Reg[15] = pc;
-}
-
-u32 ARM_Interpreter::GetPC() const {
-    return m_state->pc;
-}
-
-u32 ARM_Interpreter::GetReg(int index) const {
-    return m_state->Reg[index];
-}
-
-u32 ARM_Interpreter::GetCPSR() const {
-    return m_state->Cpsr;
-}
-
-u64 ARM_Interpreter::GetTicks() const {
-    return ARMul_Time(m_state);
-}
-
 ARM_Interpreter::~ARM_Interpreter() {
     delete m_state;
 }
 
+/**
+ * Set the Program Counter to an address
+ * @param addr Address to set PC to
+ */
+void ARM_Interpreter::SetPC(u32 pc) {
+    m_state->pc = m_state->Reg[15] = pc;
+}
+
+/*
+ * Get the current Program Counter
+ * @return Returns current PC
+ */
+u32 ARM_Interpreter::GetPC() const {
+    return m_state->pc;
+}
+
+/**
+ * Get an ARM register
+ * @param index Register index (0-15)
+ * @return Returns the value in the register
+ */
+u32 ARM_Interpreter::GetReg(int index) const {
+    return m_state->Reg[index];
+}
+
+/**
+ * Set an ARM register
+ * @param index Register index (0-15)
+ * @param value Value to set register to
+ */
+void ARM_Interpreter::SetReg(int index, u32 value) {
+    m_state->Reg[index] = value;
+}
+
+/**
+ * Get the current CPSR register
+ * @return Returns the value of the CPSR register
+ */
+u32 ARM_Interpreter::GetCPSR() const {
+    return m_state->Cpsr;
+}
+
+/**
+ * Returns the number of clock ticks since the last reset
+ * @return Returns number of clock ticks
+ */
+u64 ARM_Interpreter::GetTicks() const {
+    return ARMul_Time(m_state);
+}
+
+/// Execture next instruction
 void ARM_Interpreter::ExecuteInstruction() {
     m_state->step++;
     m_state->cycle++;
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 932046d9a5..f3c86f8dd0 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -12,22 +12,55 @@
 
 class ARM_Interpreter : virtual public ARM_Interface {
 public:
+
     ARM_Interpreter();
     ~ARM_Interpreter();
 
-    void ExecuteInstruction();
-
+    /**
+     * Set the Program Counter to an address
+     * @param addr Address to set PC to
+     */
     void SetPC(u32 pc);
 
+    /*
+     * Get the current Program Counter
+     * @return Returns current PC
+     */
     u32 GetPC() const;
 
+    /**
+     * Get an ARM register
+     * @param index Register index (0-15)
+     * @return Returns the value in the register
+     */
     u32 GetReg(int index) const;
 
+    /**
+     * Set an ARM register
+     * @param index Register index (0-15)
+     * @param value Value to set register to
+     */
+    void SetReg(int index, u32 value);
+
+    /**
+     * Get the current CPSR register
+     * @return Returns the value of the CPSR register
+     */
     u32 GetCPSR() const;
 
+    /**
+     * Returns the number of clock ticks since the last reset
+     * @return Returns number of clock ticks
+     */
     u64 GetTicks() const;
 
+protected:
+
+    /// Execture next instruction
+    void ExecuteInstruction();
+
 private:
+
     ARMul_State* m_state;
 
     DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter);
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 46c51fbe82..6074ff4807 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -16,6 +16,8 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
+#include "core/hle/hle.h"
+
 #include "arm_regformat.h"
 #include "armdefs.h"
 #include "armemu.h"
@@ -4558,6 +4560,7 @@ ARMul_Emulate26 (ARMul_State * state)
                 //    ARMul_OSHandleSWI (state, BITS (0, 23));
                 //    break;
                 //}
+                HLE::CallSyscall(instr);
                 ARMul_Abort (state, ARMul_SWIV);
                 break;
             }
diff --git a/src/core/arm/interpreter/armemu.h b/src/core/arm/interpreter/armemu.h
index 7391dea7fd..7c118948ac 100644
--- a/src/core/arm/interpreter/armemu.h
+++ b/src/core/arm/interpreter/armemu.h
@@ -229,6 +229,17 @@ extern ARMword isize;
     }									\
   while (0)
 
+#define SETABORT_SKIPBRANCH(i, m, d)						\
+  do									\
+    { 									\
+      int SETABORT_mode = (m);						\
+									\
+      ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state));	\
+      ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT))	\
+			     | (i) | SETABORT_mode));			\
+    }									\
+  while (0)
+
 //#ifndef MODE32
 #define VECTORS 0x20
 #define LEGALADDR 0x03ffffff
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
index cdbd02f3c6..a8aeecdeac 100644
--- a/src/core/arm/interpreter/arminit.cpp
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -530,9 +530,13 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
 			  isize);
 		break;
 	case ARMul_SWIV:	/* Software Interrupt */
-		SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
+		// Modified SETABORT that doesn't branch to a SVC vector as we are implementing this in HLE
+		// Instead of doing normal routine, backup R15 by one instruction (this is what PC will get 
+		// set to, making it the next instruction after the SVC call), and skip setting the LR.
+		SETABORT_SKIPBRANCH (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
 			  isize);
-		break;
+		state->Reg[15] -= 4;
+		return;
 	case ARMul_PrefetchAbortV:	/* Prefetch Abort */
 		state->AbortAddr = 1;
 		SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index a0c866c151..101b9807ae 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -19,6 +19,8 @@
 #include "armemu.h"
 //#include "ansidecl.h"
 #include "skyeye_defs.h"
+#include "core/hle/hle.h"
+
 unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
                                         unsigned cpnum);
 //extern int skyeye_instr_debug;
@@ -734,39 +736,39 @@ ARMword
 ARMul_MRC (ARMul_State * state, ARMword instr)
 {
 	unsigned cpab;
-	ARMword result = 0;
+	ARMword result = HLE::CallGetThreadCommandBuffer();
 
-	//printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
-	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
-		//chy 2004-07-19 should fix in the future????!!!!
-		//printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr  CPnum is %x, instr %x\n",CPNum, instr);
-		ARMul_UndefInstr (state, instr);
-		return -1;
-	}
+	////printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
+	//if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+	//	//chy 2004-07-19 should fix in the future????!!!!
+	//	//printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr  CPnum is %x, instr %x\n",CPNum, instr);
+	//	ARMul_UndefInstr (state, instr);
+	//	return -1;
+	//}
 
-	cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
-	while (cpab == ARMul_BUSY) {
-		ARMul_Icycles (state, 1, 0);
-		if (IntPending (state)) {
-			cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
-						    instr, 0);
-			return (0);
-		}
-		else
-			cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
-						    &result);
-	}
-	if (cpab == ARMul_CANT) {
-		printf ("SKYEYE ARMul_MRC,CANT UndefInstr  CPnum is %x, instr %x\n", CPNum, instr);
-		ARMul_Abort (state, ARMul_UndefinedInstrV);
-		/* Parent will destroy the flags otherwise.  */
-		result = ECC;
-	}
-	else {
-		BUSUSEDINCPCN;
-		ARMul_Ccycles (state, 1, 0);
-		ARMul_Icycles (state, 1, 0);
-	}
+	//cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
+	//while (cpab == ARMul_BUSY) {
+	//	ARMul_Icycles (state, 1, 0);
+	//	if (IntPending (state)) {
+	//		cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
+	//					    instr, 0);
+	//		return (0);
+	//	}
+	//	else
+	//		cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
+	//					    &result);
+	//}
+	//if (cpab == ARMul_CANT) {
+	//	printf ("SKYEYE ARMul_MRC,CANT UndefInstr  CPnum is %x, instr %x\n", CPNum, instr);
+	//	ARMul_Abort (state, ARMul_UndefinedInstrV);
+	//	/* Parent will destroy the flags otherwise.  */
+	//	result = ECC;
+	//}
+	//else {
+	//	BUSUSEDINCPCN;
+	//	ARMul_Ccycles (state, 1, 0);
+	//	ARMul_Icycles (state, 1, 0);
+	//}
 
 	return result;
 }
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 28f6b6c586..859a62c78f 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -40,7 +40,7 @@ void Stop() {
 
 /// Initialize the core
 int Init() {
-    NOTICE_LOG(MASTER_LOG, "Core initialized OK");
+    NOTICE_LOG(MASTER_LOG, "initialized OK");
 
     g_disasm = new ARM_Disasm();
     g_app_core = new ARM_Interpreter();
@@ -54,7 +54,7 @@ void Shutdown() {
     delete g_app_core;
     delete g_sys_core;
 
-    NOTICE_LOG(MASTER_LOG, "Core shutdown OK");
+    NOTICE_LOG(MASTER_LOG, "shutdown OK");
 }
 
 } // namespace
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 1800b55129..b6fc604c68 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -152,8 +152,16 @@
     <ClCompile Include="elf\elf_reader.cpp" />
     <ClCompile Include="file_sys\directory_file_system.cpp" />
     <ClCompile Include="file_sys\meta_file_system.cpp" />
+    <ClCompile Include="hle\hle.cpp" />
+    <ClCompile Include="hle\service\apt.cpp" />
+    <ClCompile Include="hle\service\gsp.cpp" />
+    <ClCompile Include="hle\service\hid.cpp" />
+    <ClCompile Include="hle\service\service.cpp" />
+    <ClCompile Include="hle\service\srv.cpp" />
+    <ClCompile Include="hle\syscall.cpp" />
     <ClCompile Include="hw\hw.cpp" />
-    <ClCompile Include="hw\hw_lcd.cpp" />
+    <ClCompile Include="hw\lcd.cpp" />
+    <ClCompile Include="hw\ndma.cpp" />
     <ClCompile Include="loader.cpp" />
     <ClCompile Include="mem_map.cpp" />
     <ClCompile Include="mem_map_funcs.cpp" />
@@ -182,8 +190,17 @@
     <ClInclude Include="file_sys\directory_file_system.h" />
     <ClInclude Include="file_sys\file_sys.h" />
     <ClInclude Include="file_sys\meta_file_system.h" />
+    <ClInclude Include="hle\function_wrappers.h" />
+    <ClInclude Include="hle\hle.h" />
+    <ClInclude Include="hle\service\apt.h" />
+    <ClInclude Include="hle\service\gsp.h" />
+    <ClInclude Include="hle\service\hid.h" />
+    <ClInclude Include="hle\service\service.h" />
+    <ClInclude Include="hle\service\srv.h" />
+    <ClInclude Include="hle\syscall.h" />
     <ClInclude Include="hw\hw.h" />
-    <ClInclude Include="hw\hw_lcd.h" />
+    <ClInclude Include="hw\lcd.h" />
+    <ClInclude Include="hw\ndma.h" />
     <ClInclude Include="loader.h" />
     <ClInclude Include="mem_map.h" />
     <ClInclude Include="system.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 2efac81272..ff7877feb6 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -22,6 +22,12 @@
     <Filter Include="elf">
       <UniqueIdentifier>{7ae34319-6d72-4d12-bc62-9b438ba9241f}</UniqueIdentifier>
     </Filter>
+    <Filter Include="hle">
+      <UniqueIdentifier>{8b62769e-3e2a-4a57-a7bc-b3b2933c2bc7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="hle\service">
+      <UniqueIdentifier>{812c5189-ca49-4704-b842-3ffad09092d3}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="arm\disassembler\arm_disasm.cpp">
@@ -63,9 +69,6 @@
     <ClCompile Include="hw\hw.cpp">
       <Filter>hw</Filter>
     </ClCompile>
-    <ClCompile Include="hw\hw_lcd.cpp">
-      <Filter>hw</Filter>
-    </ClCompile>
     <ClCompile Include="elf\elf_reader.cpp">
       <Filter>elf</Filter>
     </ClCompile>
@@ -75,6 +78,33 @@
     <ClCompile Include="mem_map_funcs.cpp" />
     <ClCompile Include="system.cpp" />
     <ClCompile Include="core_timing.cpp" />
+    <ClCompile Include="hle\hle.cpp">
+      <Filter>hle</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\syscall.cpp">
+      <Filter>hle</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\service\service.cpp">
+      <Filter>hle\service</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\service\apt.cpp">
+      <Filter>hle\service</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\service\srv.cpp">
+      <Filter>hle\service</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\service\gsp.cpp">
+      <Filter>hle\service</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\service\hid.cpp">
+      <Filter>hle\service</Filter>
+    </ClCompile>
+    <ClCompile Include="hw\ndma.cpp">
+      <Filter>hw</Filter>
+    </ClCompile>
+    <ClCompile Include="hw\lcd.cpp">
+      <Filter>hw</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -131,9 +161,6 @@
     <ClInclude Include="hw\hw.h">
       <Filter>hw</Filter>
     </ClInclude>
-    <ClInclude Include="hw\hw_lcd.h">
-      <Filter>hw</Filter>
-    </ClInclude>
     <ClInclude Include="elf\elf_reader.h">
       <Filter>elf</Filter>
     </ClInclude>
@@ -148,6 +175,36 @@
     <ClInclude Include="loader.h" />
     <ClInclude Include="mem_map.h" />
     <ClInclude Include="system.h" />
+    <ClInclude Include="hle\hle.h">
+      <Filter>hle</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\function_wrappers.h">
+      <Filter>hle</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\service\service.h">
+      <Filter>hle\service</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\syscall.h">
+      <Filter>hle</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\service\apt.h">
+      <Filter>hle\service</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\service\srv.h">
+      <Filter>hle\service</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\service\gsp.h">
+      <Filter>hle\service</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\service\hid.h">
+      <Filter>hle\service</Filter>
+    </ClInclude>
+    <ClInclude Include="hw\ndma.h">
+      <Filter>hw</Filter>
+    </ClInclude>
+    <ClInclude Include="hw\lcd.h">
+      <Filter>hw</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
new file mode 100644
index 0000000000..4897d3f286
--- /dev/null
+++ b/src/core/hle/function_wrappers.h
@@ -0,0 +1,736 @@
+// Copyright (c) 2012- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#pragma once
+
+#include "common/common_types.h"
+#include "core/mem_map.h"
+#include "core/hle/hle.h"
+
+// For easy parameter parsing and return value processing.
+
+//32bit wrappers
+template<void func()> void WrapV_V() {
+    func();
+}
+
+template<u32 func()> void WrapU_V() {
+    RETURN(func());
+}
+
+template<int func(void *, const char *)> void WrapI_VC() {
+    u32 retval = func(Memory::GetPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)));
+    RETURN(retval);
+}
+
+template<u32 func(int, void *, int)> void WrapU_IVI() {
+    u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(const char *, int, int, u32)> void WrapI_CIIU() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(int, const char *, u32, void *, void *, u32, int)> void WrapI_ICUVVUI() {
+    u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointer(PARAM(3)),Memory::GetPointer(PARAM(4)), PARAM(5), PARAM(6) );
+    RETURN(retval);
+}
+
+// Hm, do so many params get passed in registers?
+template<int func(const char *, int, const char *, int, int, int, int, int)> void WrapI_CICIIIII() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), Memory::GetCharPointer(PARAM(2)),
+        PARAM(3), PARAM(4), PARAM(5), PARAM(6), PARAM(7));
+    RETURN(retval);
+}
+
+// Hm, do so many params get passed in registers?
+template<int func(const char *, int, int, int, int, int, int)> void WrapI_CIIIIII() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+        PARAM(3), PARAM(4), PARAM(5), PARAM(6));
+    RETURN(retval);
+}
+
+// Hm, do so many params get passed in registers?
+template<int func(int, int, int, int, int, int, u32)> void WrapI_IIIIIIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6));
+    RETURN(retval);
+}
+
+// Hm, do so many params get passed in registers?
+template<int func(int, int, int, int, int, int, int, int, u32)> void WrapI_IIIIIIIIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6), PARAM(7), PARAM(8));
+    RETURN(retval);
+}
+
+template<u32 func(int, void *)> void WrapU_IV() {
+    u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)));
+    RETURN(retval);
+}
+
+template<float func()> void WrapF_V() {
+    RETURNF(func());
+}
+
+// TODO: Not sure about the floating point parameter passing
+template<float func(int, float, u32)> void WrapF_IFU() {
+    RETURNF(func(PARAM(0), PARAMF(0), PARAM(1)));
+}
+
+template<u32 func(u32)> void WrapU_U() {
+    u32 retval = func(PARAM(0));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int)> void WrapU_UI() {
+    u32 retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(u32)> void WrapI_U() {
+    int retval = func(PARAM(0));
+    RETURN(retval);
+}
+
+template<int func(u32, int)> void WrapI_UI() {
+    int retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(u32, int, int, u32)> void WrapI_UIIU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(int, u32, int)> void WrapU_IUI() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(u32, u32)> void WrapI_UU() {
+    int retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(u32, float, float)> void WrapI_UFF() {
+    // Not sure about the float arguments.
+    int retval = func(PARAM(0), PARAMF(0), PARAMF(1));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, u32)> void WrapI_UUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, u32, int)> void WrapI_UUUI() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, u32, int, int, int,int )> void WrapI_UUUIIII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, u32, u32)> void WrapI_UUUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, u32, u32, u32)> void WrapI_UUUUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func()> void WrapI_V() {
+    int retval = func();
+    RETURN(retval);
+}
+
+template<u32 func(int)> void WrapU_I() {
+    u32 retval = func(PARAM(0));
+    RETURN(retval);
+}
+
+template<u32 func(int, int, u32)> void WrapU_IIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(int)> void WrapI_I() {
+    int retval = func(PARAM(0));
+    RETURN(retval);
+}
+
+template<void func(u32)> void WrapV_U() {
+    func(PARAM(0));
+}
+
+template<void func(int)> void WrapV_I() {
+    func(PARAM(0));
+}
+
+template<void func(u32, u32)> void WrapV_UU() {
+    func(PARAM(0), PARAM(1));
+}
+
+template<void func(int, int)> void WrapV_II() {
+    func(PARAM(0), PARAM(1));
+}
+
+template<void func(u32, const char *)> void WrapV_UC() {
+    func(PARAM(0), Memory::GetCharPointer(PARAM(1)));
+}
+
+template<int func(u32, const char *)> void WrapI_UC() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)));
+    RETURN(retval);
+}
+
+template<int func(u32, const char *, int)> void WrapI_UCI() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int , int , int, int, int)> void WrapU_UIIIII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int , int , int, u32)> void WrapU_UIIIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int , int , int, int, int, int)> void WrapU_UIIIIII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32)> void WrapU_UU() {
+    u32 retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, int)> void WrapU_UUI() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, int, int)> void WrapU_UUII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(const char *, u32, u32, u32)> void WrapU_CUUU() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<void func(u32, int, u32, int, int)> void WrapV_UIUII() {
+    func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+}
+
+template<u32 func(u32, int, u32, int, int)> void WrapU_UIUII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(u32, int, u32, int, int)> void WrapI_UIUII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int, u32, int)> void WrapU_UIUI() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(u32, int, u32, int)> void WrapI_UIUI() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int, u32)> void WrapU_UIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int, u32, u32)> void WrapU_UIUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int, int)> void WrapU_UII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int, int, u32)> void WrapU_UIIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(u32, int, int, u32, u32)> void WrapI_UIIUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, int, int)> void WrapI_UUII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, int, int, int)> void WrapI_UUIII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<void func(u32, int, int, int)> void WrapV_UIII() {
+    func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+}
+
+template<void func(u32, int, int, int, int, int)> void WrapV_UIIIII() {
+    func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5));
+}
+
+template<void func(u32, int, int)> void WrapV_UII() {
+    func(PARAM(0), PARAM(1), PARAM(2));
+}
+
+template<u32 func(int, u32)> void WrapU_IU() {
+    int retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(int, u32)> void WrapI_IU() {
+    int retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, int)> void WrapI_UUI() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(u32, u32, int, u32)> void WrapI_UUIU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(int, int)> void WrapI_II() {
+    int retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(int, int, int)> void WrapI_III() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(int, u32, int)> void WrapI_IUI() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(int, int, int, int)> void WrapI_IIII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(u32, int, int, int)> void WrapI_UIII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(int, int, int, u32, int)> void WrapI_IIIUI() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(int, u32, u32, int, int)> void WrapI_IUUII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(int, const char *, int, u32, u32)> void WrapI_ICIUU() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(int, int, u32)> void WrapI_IIU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<void func(int, u32)> void WrapV_IU() {
+    func(PARAM(0), PARAM(1));
+}
+
+template<void func(u32, int)> void WrapV_UI() {
+    func(PARAM(0), PARAM(1));
+}
+
+template<u32 func(const char *)> void WrapU_C() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)));
+    RETURN(retval);
+}
+
+template<u32 func(const char *, const char *, const char *, u32)> void WrapU_CCCU() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)),
+            Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)),
+            PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(const char *)> void WrapI_C() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)));
+    RETURN(retval);
+}
+
+template<int func(const char *, u32)> void WrapI_CU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1));
+    RETURN(retval);
+}
+
+template<int func(const char *, u32, int)> void WrapI_CUI() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(int, const char *, int, u32)> void WrapI_ICIU() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(const char *, int, u32)> void WrapI_CIU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(const char *, u32, u32)> void WrapI_CUU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(const char *, u32, u32, u32)> void WrapI_CUUU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(const char *, const char*, int, int)> void WrapI_CCII() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(const char *, u32, u32, int, u32, u32)> void WrapI_CUUIUU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<int func(const char *, int, int, u32, int, int)> void WrapI_CIIUII() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+        PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<int func(const char *, int, u32, u32, u32)> void WrapI_CIUUU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(const char *, u32, u32, u32, u32, u32)> void WrapI_CUUUUU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<u32 func(const char *, u32)> void WrapU_CU() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1));
+    RETURN((u32) retval);
+}
+
+template<u32 func(u32, const char *)> void WrapU_UC() {
+    u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)));
+    RETURN(retval);
+}
+
+template<u32 func(const char *, u32, u32)> void WrapU_CUU() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
+    RETURN((u32) retval);
+}
+
+template<u32 func(int, int, int)> void WrapU_III() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(int, int)> void WrapU_II() {
+    u32 retval = func(PARAM(0), PARAM(1));
+    RETURN(retval);
+}
+
+template<u32 func(int, int, int, int)> void WrapU_IIII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(int, u32, u32)> void WrapU_IUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(int, u32, u32, u32)> void WrapU_IUUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(int, u32, u32, u32, u32)> void WrapU_IUUUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32)> void WrapU_UUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<void func(int, u32, u32)> void WrapV_IUU() {
+    func(PARAM(0), PARAM(1), PARAM(2));
+}
+
+template<void func(int, int, u32)> void WrapV_IIU() {
+    func(PARAM(0), PARAM(1), PARAM(2));
+}
+
+template<void func(u32, int, u32)> void WrapV_UIU() {
+    func(PARAM(0), PARAM(1), PARAM(2));
+}
+
+template<int func(u32, int, u32)> void WrapI_UIU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<void func(int, u32, u32, u32, u32)> void WrapV_IUUUU() {
+    func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+}
+
+template<void func(u32, u32, u32)> void WrapV_UUU() {
+    func(PARAM(0), PARAM(1), PARAM(2));
+}
+
+template<void func(u32, u32, u32, u32)> void WrapV_UUUU() {
+    func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+}
+
+template<void func(const char *, u32, int, u32)> void WrapV_CUIU() {
+    func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
+}
+
+template<int func(const char *, u32, int, u32)> void WrapI_CUIU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<void func(u32, const char *, u32, int, u32)> void WrapV_UCUIU() {
+    func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3),
+            PARAM(4));
+}
+
+template<int func(u32, const char *, u32, int, u32)> void WrapI_UCUIU() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2),
+            PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<void func(const char *, u32, int, int, u32)> void WrapV_CUIIU() {
+    func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3),
+            PARAM(4));
+}
+
+template<int func(const char *, u32, int, int, u32)> void WrapI_CUIIU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32, u32)> void WrapU_UUUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(u32, const char *, u32, u32)> void WrapU_UCUU() {
+    u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32, int)> void WrapU_UUUI() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32, int, u32)> void WrapU_UUUIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32, int, u32, int)> void WrapU_UUUIUI() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, int, u32)> void WrapU_UUIU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<u32 func(u32, int, int, int)> void WrapU_UIII() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(int, u32, u32, u32, u32)> void WrapI_IUUUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<int func(int, u32, u32, u32, u32, u32)> void WrapI_IUUUUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<int func(int, u32, int, int)> void WrapI_IUII() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+template<u32 func(u32, u32, u32, u32, u32)> void WrapU_UUUUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<void func(u32, u32, u32, u32, u32)> void WrapV_UUUUU() {
+    func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
+}
+
+template<u32 func(const char *, const char *)> void WrapU_CC() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)),
+            Memory::GetCharPointer(PARAM(1)));
+    RETURN(retval);
+}
+
+template<void func(const char *, int)> void WrapV_CI() {
+    func(Memory::GetCharPointer(PARAM(0)), PARAM(1));
+}
+
+template<u32 func(const char *, int)> void WrapU_CI() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1));
+    RETURN(retval);
+}
+
+template<u32 func(const char *, int, int)> void WrapU_CII() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(const char *, int, u32, int, u32)> void WrapU_CIUIU() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template<u32 func(const char *, int, u32, int, u32, int)> void WrapU_CIUIUI() {
+    u32 retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2),
+            PARAM(3), PARAM(4), PARAM(5));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32, u32, u32, u32)> void WrapU_UUUUUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4),
+            PARAM(5));
+    RETURN(retval);
+}
+
+template<int func(int, u32, u32, u32)> void WrapI_IUUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(int, u32, u32)> void WrapI_IUU() {
+    int retval = func(PARAM(0), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template<u32 func(u32, u32, u32, u32, u32, u32, u32)> void WrapU_UUUUUUU() {
+  u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6));
+  RETURN(retval);
+}
+
+template<int func(u32, int, u32, u32)> void WrapI_UIUU() {
+    u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+    RETURN(retval);
+}
+
+template<int func(int, const char *)> void WrapI_IC() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)));
+    RETURN(retval);
+}
+
+template <int func(int, const char *, const char *, u32, int)> void WrapI_ICCUI() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3), PARAM(4));
+    RETURN(retval);
+}
+
+template <int func(int, const char *, const char *, int)> void WrapI_ICCI() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), Memory::GetCharPointer(PARAM(2)), PARAM(3));
+    RETURN(retval);
+}
+
+template <int func(const char *, int, int)> void WrapI_CII() {
+    int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
+    RETURN(retval);
+}
+
+template <int func(int, const char *, int)> void WrapI_ICI() {
+    int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2));
+    RETURN(retval);
+}
+
+template<int func(int, void *, void *, void *, void *, u32, int)> void WrapI_IVVVVUI(){
+  u32 retval = func(PARAM(0), Memory::GetPointer(PARAM(1)), Memory::GetPointer(PARAM(2)), Memory::GetPointer(PARAM(3)), Memory::GetPointer(PARAM(4)), PARAM(5), PARAM(6) );
+  RETURN(retval);
+}
+
+template<int func(int, const char *, u32, void *, int, int, int)> void WrapI_ICUVIII(){
+  u32 retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), Memory::GetPointer(PARAM(3)), PARAM(4), PARAM(5), PARAM(6));
+  RETURN(retval);
+}
+
+template<int func(void *, u32, u32, u32, u32, u32)> void WrapI_VUUUUU(){
+  u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5));
+  RETURN(retval);
+}
+
+template<int func(u32, s64)> void WrapI_US64() {
+    int retval = func(PARAM(0), PARAM64(2));
+    RETURN(retval);
+}
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
new file mode 100644
index 0000000000..5672a659f1
--- /dev/null
+++ b/src/core/hle/hle.cpp
@@ -0,0 +1,120 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#include <vector>
+
+#include "core/mem_map.h"
+#include "core/hle/hle.h"
+#include "core/hle/syscall.h"
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace HLE {
+
+static std::vector<ModuleDef> g_module_db;
+
+u8* g_command_buffer = NULL;    ///< Command buffer used for sharing between appcore and syscore
+
+// Read from memory used by CTROS HLE functions
+template <typename T>
+inline void Read(T &var, const u32 addr) {
+    if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) {
+        var = *((const T*)&g_command_buffer[addr & CMD_BUFFER_MASK]);
+    } else {
+        ERROR_LOG(HLE, "unknown read from address %08X", addr);
+    }
+}
+
+// Write to memory used by CTROS HLE functions
+template <typename T>
+inline void Write(u32 addr, const T data) {
+    if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) {
+        *(T*)&g_command_buffer[addr & CMD_BUFFER_MASK] = data;
+    } else {
+        ERROR_LOG(HLE, "unknown write to address %08X", addr);
+    }
+}
+
+u8 *GetPointer(const u32 addr) {
+    if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) {
+        return g_command_buffer + (addr & CMD_BUFFER_MASK);
+    } else {
+        ERROR_LOG(HLE, "unknown pointer from address %08X", addr);
+        return 0;
+    }
+}
+
+// Explicitly instantiate template functions because we aren't defining this in the header:
+
+template void Read<u64>(u64 &var, const u32 addr);
+template void Read<u32>(u32 &var, const u32 addr);
+template void Read<u16>(u16 &var, const u32 addr);
+template void Read<u8>(u8 &var, const u32 addr);
+
+template void Write<u64>(u32 addr, const u64 data);
+template void Write<u32>(u32 addr, const u32 data);
+template void Write<u16>(u32 addr, const u16 data);
+template void Write<u8>(u32 addr, const u8 data);
+
+const FunctionDef* GetSyscallInfo(u32 opcode) {
+    u32 func_num = opcode & 0xFFFFFF; // 8 bits
+    if (func_num > 0xFF) {
+        ERROR_LOG(HLE,"Unknown syscall: 0x%02X", func_num); 
+        return NULL;
+    }
+    return &g_module_db[0].func_table[func_num];
+}
+
+void CallSyscall(u32 opcode) {
+    const FunctionDef *info = GetSyscallInfo(opcode);
+
+    if (!info) {
+        return;
+    }
+    if (info->func) {
+        info->func();
+    } else {
+        ERROR_LOG(HLE, "Unimplemented SysCall function %s(..)", info->name.c_str());
+    }
+}
+
+/// Returns the coprocessor (in this case, syscore) command buffer pointer
+Addr CallGetThreadCommandBuffer() {
+    // 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);
+    return CMD_BUFFER_ADDR;
+}
+
+void RegisterModule(std::string name, int num_functions, const FunctionDef* func_table) {
+    ModuleDef module = {name, num_functions, func_table};
+    g_module_db.push_back(module);
+}
+
+void RegisterAllModules() {
+    Syscall::Register();
+}
+
+void Init() {
+    Service::Init();
+
+    g_command_buffer = new u8[CMD_BUFFER_SIZE];
+    
+    RegisterAllModules();
+
+    NOTICE_LOG(HLE, "initialized OK");
+}
+
+void Shutdown() {
+    Service::Shutdown();
+
+    delete g_command_buffer;
+
+    g_module_db.clear();
+
+    NOTICE_LOG(HLE, "shutdown OK");
+}
+
+} // namespace
diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h
new file mode 100644
index 0000000000..628a1da892
--- /dev/null
+++ b/src/core/hle/hle.h
@@ -0,0 +1,66 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include "common/common_types.h"
+#include "core/core.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define PARAM(n)        Core::g_app_core->GetReg(n)
+#define PARAM64(n)      (Core::g_app_core->GetReg(n) | ((u64)Core::g_app_core->GetReg(n + 1) << 32))
+#define RETURN(n)       Core::g_app_core->SetReg(0, n)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace HLE {
+
+enum {
+    CMD_BUFFER_ADDR     = 0xA0010000,    ///< Totally arbitrary unused address space
+    CMD_BUFFER_SIZE     = 0x10000,
+    CMD_BUFFER_MASK     = (CMD_BUFFER_SIZE - 1),
+    CMD_BUFFER_ADDR_END = (CMD_BUFFER_ADDR + CMD_BUFFER_SIZE),
+};
+
+typedef u32 Addr;
+typedef void (*Func)();
+
+struct FunctionDef {
+    u32                 id;
+    Func                func;
+    std::string         name;
+};
+
+struct ModuleDef {
+    std::string         name;
+    int                 num_funcs;
+    const FunctionDef*  func_table;
+};
+
+// Read from memory used by CTROS HLE functions
+template <typename T>
+inline void Read(T &var, const u32 addr);
+
+// Write to memory used by CTROS HLE functions
+template <typename T>
+inline void Write(u32 addr, const T data);
+
+u8* GetPointer(const u32 Address);
+
+inline const char* GetCharPointer(const u32 address) {
+    return (const char *)GetPointer(address);
+}
+
+void RegisterModule(std::string name, int num_functions, const FunctionDef *func_table);
+
+void CallSyscall(u32 opcode);
+
+Addr CallGetThreadCommandBuffer();
+
+void Init();
+
+void Shutdown();
+
+} // namespace
diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp
new file mode 100644
index 0000000000..4f8d7248dd
--- /dev/null
+++ b/src/core/hle/service/apt.cpp
@@ -0,0 +1,116 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+
+#include "common/log.h"
+
+#include "core/hle/hle.h"
+#include "core/hle/service/apt.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace APT_U
+
+namespace APT_U {
+
+void Initialize() {
+    NOTICE_LOG(OSHLE, "APT_U::Sync - Initialize");
+}
+
+void GetLockHandle() {
+    u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset);
+    cmd_buff[5] = 0x00000000; // TODO: This should be an actual mutex handle
+}
+
+const HLE::FunctionDef FunctionTable[] = {
+    {0x00010040, GetLockHandle, "GetLockHandle"},
+    {0x00020080, Initialize,    "Initialize"},
+    {0x00030040, NULL,          "Enable"},
+    {0x00040040, NULL,          "Finalize"},
+    {0x00050040, NULL,          "GetAppletManInfo"},
+    {0x00060040, NULL,          "GetAppletInfo"},
+    {0x00070000, NULL,          "GetLastSignaledAppletId"},
+    {0x00080000, NULL,          "CountRegisteredApplet"},
+    {0x00090040, NULL,          "IsRegistered"},
+    {0x000A0040, NULL,          "GetAttribute"},
+    {0x000B0040, NULL,          "InquireNotification"},
+    {0x000C0104, NULL,          "SendParameter"},
+    {0x000D0080, NULL,          "ReceiveParameter"},
+    {0x000E0080, NULL,          "GlanceParameter"},
+    {0x000F0100, NULL,          "CancelParameter"},
+    {0x001000C2, NULL,          "DebugFunc"},
+    {0x001100C0, NULL,          "MapProgramIdForDebug"},
+    {0x00120040, NULL,          "SetHomeMenuAppletIdForDebug"},
+    {0x00130000, NULL,          "GetPreparationState"},
+    {0x00140040, NULL,          "SetPreparationState"},
+    {0x00150140, NULL,          "PrepareToStartApplication"},
+    {0x00160040, NULL,          "PreloadLibraryApplet"},
+    {0x00170040, NULL,          "FinishPreloadingLibraryApplet"},
+    {0x00180040, NULL,          "PrepareToStartLibraryApplet"},
+    {0x00190040, NULL,          "PrepareToStartSystemApplet"},
+    {0x001A0000, NULL,          "PrepareToStartNewestHomeMenu"},
+    {0x001B00C4, NULL,          "StartApplication"},
+    {0x001C0000, NULL,          "WakeupApplication"},
+    {0x001D0000, NULL,          "CancelApplication"},
+    {0x001E0084, NULL,          "StartLibraryApplet"},
+    {0x001F0084, NULL,          "StartSystemApplet"},
+    {0x00200044, NULL,          "StartNewestHomeMenu"},
+    {0x00210000, NULL,          "OrderToCloseApplication"},
+    {0x00220040, NULL,          "PrepareToCloseApplication"},
+    {0x00230040, NULL,          "PrepareToJumpToApplication"},
+    {0x00240044, NULL,          "JumpToApplication"},
+    {0x002500C0, NULL,          "PrepareToCloseLibraryApplet"},
+    {0x00260000, NULL,          "PrepareToCloseSystemApplet"},
+    {0x00270044, NULL,          "CloseApplication"},
+    {0x00280044, NULL,          "CloseLibraryApplet"},
+    {0x00290044, NULL,          "CloseSystemApplet"},
+    {0x002A0000, NULL,          "OrderToCloseSystemApplet"},
+    {0x002B0000, NULL,          "PrepareToJumpToHomeMenu"},
+    {0x002C0044, NULL,          "JumpToHomeMenu"},
+    {0x002D0000, NULL,          "PrepareToLeaveHomeMenu"},
+    {0x002E0044, NULL,          "LeaveHomeMenu"},
+    {0x002F0040, NULL,          "PrepareToLeaveResidentApplet"},
+    {0x00300044, NULL,          "LeaveResidentApplet"},
+    {0x00310100, NULL,          "PrepareToDoApplicationJump"},
+    {0x00320084, NULL,          "DoApplicationJump"},
+    {0x00330000, NULL,          "GetProgramIdOnApplicationJump"},
+    {0x00340084, NULL,          "SendDeliverArg"},
+    {0x00350080, NULL,          "ReceiveDeliverArg"},
+    {0x00360040, NULL,          "LoadSysMenuArg"},
+    {0x00370042, NULL,          "StoreSysMenuArg"},
+    {0x00380040, NULL,          "PreloadResidentApplet"},
+    {0x00390040, NULL,          "PrepareToStartResidentApplet"},
+    {0x003A0044, NULL,          "StartResidentApplet"},
+    {0x003B0040, NULL,          "CancelLibraryApplet"},
+    {0x003C0042, NULL,          "SendDspSleep"},
+    {0x003D0042, NULL,          "SendDspWakeUp"},
+    {0x003E0080, NULL,          "ReplySleepQuery"},
+    {0x003F0040, NULL,          "ReplySleepNotificationComplete"},
+    {0x00400042, NULL,          "SendCaptureBufferInfo"},
+    {0x00410040, NULL,          "ReceiveCaptureBufferInfo"},
+    {0x00420080, NULL,          "SleepSystem"},
+    {0x00430040, NULL,          "NotifyToWait"},
+    {0x00440000, NULL,          "GetSharedFont"},
+    {0x00450040, NULL,          "GetWirelessRebootInfo"},
+    {0x00460104, NULL,          "Wrap"},
+    {0x00470104, NULL,          "Unwrap"},
+    {0x00480100, NULL,          "GetProgramInfo"},
+    {0x00490180, NULL,          "Reboot"},
+    {0x004A0040, NULL,          "GetCaptureInfo"},
+    {0x004B00C2, NULL,          "AppletUtility"},
+    {0x004C0000, NULL,          "SetFatalErrDispMode"},
+    {0x004D0080, NULL,          "GetAppletProgramInfo"},
+    {0x004E0000, NULL,          "HardwareResetAsync"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+Interface::~Interface() {
+}
+
+} // namespace
diff --git a/src/core/hle/service/apt.h b/src/core/hle/service/apt.h
new file mode 100644
index 0000000000..e74baac0c0
--- /dev/null
+++ b/src/core/hle/service/apt.h
@@ -0,0 +1,41 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace APT_U
+
+namespace APT_U {
+
+// Application and title launching service. These services handle signaling for home/power button as
+// well. Only one session for either APT service can be open at a time, normally processes close the
+// service handle immediately once finished using the service. The commands for APT:U and APT:S are 
+// exactly the same, however certain commands are only accessible with APT:S(NS module will call 
+// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services.
+
+/// Interface to "APT:U" service
+class Interface : public Service::Interface {
+public:
+
+    Interface();
+
+    ~Interface();
+
+    /**
+     * Gets the string port name used by CTROS for the service
+     * @return Port name of service
+     */
+    std::string GetPortName() const {
+        return "APT:U";
+    }
+
+private:
+
+    DISALLOW_COPY_AND_ASSIGN(Interface);
+};
+
+} // namespace
diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp
new file mode 100644
index 0000000000..7c80ab8b59
--- /dev/null
+++ b/src/core/hle/service/gsp.cpp
@@ -0,0 +1,59 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+
+#include "common/log.h"
+
+#include "core/hle/hle.h"
+#include "core/hle/service/gsp.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace GSP_GPU
+
+namespace GSP_GPU {
+
+const HLE::FunctionDef FunctionTable[] = {
+    {0x00010082, NULL, "WriteHWRegs"},
+    {0x00020084, NULL, "WriteHWRegsWithMask"},
+    {0x00030082, NULL, "WriteHWRegRepeat"},
+    {0x00040080, NULL, "ReadHWRegs"},
+    {0x00050200, NULL, "SetBufferSwap"},
+    {0x00060082, NULL, "SetCommandList"},
+    {0x000700C2, NULL, "RequestDma"},
+    {0x00080082, NULL, "FlushDataCache"},
+    {0x00090082, NULL, "InvalidateDataCache"},
+    {0x000A0044, NULL, "RegisterInterruptEvents"},
+    {0x000B0040, NULL, "SetLcdForceBlack"},
+    {0x000C0000, NULL, "TriggerCmdReqQueue"},
+    {0x000D0140, NULL, "SetDisplayTransfer"},
+    {0x000E0180, NULL, "SetTextureCopy"},
+    {0x000F0200, NULL, "SetMemoryFill"},
+    {0x00100040, NULL, "SetAxiConfigQoSMode"},
+    {0x00110040, NULL, "SetPerfLogMode"},
+    {0x00120000, NULL, "GetPerfLog"},
+    {0x00130042, NULL, "RegisterInterruptRelayQueue"},
+    {0x00140000, NULL, "UnregisterInterruptRelayQueue"},
+    {0x00150002, NULL, "TryAcquireRight"},
+    {0x00160042, NULL, "AcquireRight"},
+    {0x00170000, NULL, "ReleaseRight"},
+    {0x00180000, NULL, "ImportDisplayCaptureInfo"},
+    {0x00190000, NULL, "SaveVramSysArea"},
+    {0x001A0000, NULL, "RestoreVramSysArea"},
+    {0x001B0000, NULL, "ResetGpuCore"},
+    {0x001C0040, NULL, "SetLedForceOff"},
+    {0x001D0040, NULL, "SetTestCommand"},
+    {0x001E0080, NULL, "SetInternalPriorities"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+Interface::~Interface() {
+}
+
+} // namespace
diff --git a/src/core/hle/service/gsp.h b/src/core/hle/service/gsp.h
new file mode 100644
index 0000000000..3b18460821
--- /dev/null
+++ b/src/core/hle/service/gsp.h
@@ -0,0 +1,35 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace GSP_GPU
+
+namespace GSP_GPU {
+
+/// Interface to "srv:" service
+class Interface : public Service::Interface {
+public:
+
+    Interface();
+
+    ~Interface();
+
+    /**
+     * Gets the string port name used by CTROS for the service
+     * @return Port name of service
+     */
+    std::string GetPortName() const {
+        return "gsp::Gpu";
+    }
+
+private:
+
+    DISALLOW_COPY_AND_ASSIGN(Interface);
+};
+
+} // namespace
diff --git a/src/core/hle/service/hid.cpp b/src/core/hle/service/hid.cpp
new file mode 100644
index 0000000000..2d823dd16c
--- /dev/null
+++ b/src/core/hle/service/hid.cpp
@@ -0,0 +1,33 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+
+#include "core/hle/hle.h"
+#include "core/hle/service/hid.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace HID_User
+
+namespace HID_User {
+
+const HLE::FunctionDef FunctionTable[] = {
+    {0x000A0000, NULL, "GetIPCHandles"},
+    {0x00110000, NULL, "EnableAccelerometer"},
+    {0x00130000, NULL, "EnableGyroscopeLow"},
+    {0x00150000, NULL, "GetGyroscopeLowRawToDpsCoefficient"},
+    {0x00160000, NULL, "GetGyroscopeLowCalibrateParam"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+Interface::~Interface() {
+}
+
+} // namespace
diff --git a/src/core/hle/service/hid.h b/src/core/hle/service/hid.h
new file mode 100644
index 0000000000..746c1b1fc5
--- /dev/null
+++ b/src/core/hle/service/hid.h
@@ -0,0 +1,37 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace HID_User
+
+// This service is used for interfacing to physical user controls... perhaps "Human Interface 
+// Devices"? Uses include game pad controls, accelerometers, gyroscopes, etc.
+
+namespace HID_User {
+
+class Interface : public Service::Interface {
+public:
+
+    Interface();
+
+    ~Interface();
+
+    /**
+     * Gets the string port name used by CTROS for the service
+     * @return Port name of service
+     */
+    std::string GetPortName() const {
+        return "hid:USER";
+    }
+
+private:
+
+    DISALLOW_COPY_AND_ASSIGN(Interface);
+};
+
+} // namespace
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
new file mode 100644
index 0000000000..e6605a398a
--- /dev/null
+++ b/src/core/hle/service/service.cpp
@@ -0,0 +1,94 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "common/common.h"
+#include "common/log.h"
+#include "common/string_util.h"
+
+#include "core/hle/hle.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/apt.h"
+#include "core/hle/service/gsp.h"
+#include "core/hle/service/hid.h"
+#include "core/hle/service/srv.h"
+
+namespace Service {
+
+Manager* g_manager = NULL;  ///< Service manager
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Service Manager class
+
+Manager::Manager() {
+}
+
+Manager::~Manager() {
+    for(Interface* service : m_services) {
+        DeleteService(service->GetPortName());
+    }
+}
+
+/// Add a service to the manager (does not create it though)
+void Manager::AddService(Interface* service) {
+    int index = m_services.size();
+    u32 new_uid = GetUIDFromIndex(index);
+
+    m_services.push_back(service);
+
+    m_port_map[service->GetPortName()] = new_uid;
+    service->m_uid = new_uid;
+}
+
+/// Removes a service from the manager, also frees memory
+void Manager::DeleteService(std::string port_name) {
+    auto service = FetchFromPortName(port_name);
+
+    m_services.erase(m_services.begin() + GetIndexFromUID(service->m_uid));
+    m_port_map.erase(port_name);
+
+    delete service;
+}
+
+/// Get a Service Interface from its UID
+Interface* Manager::FetchFromUID(u32 uid) {
+    int index = GetIndexFromUID(uid);
+    if (index < (int)m_services.size()) {
+        return m_services[index];
+    }
+    return NULL;
+}
+
+/// Get a Service Interface from its port
+Interface* Manager::FetchFromPortName(std::string port_name) {
+    auto itr = m_port_map.find(port_name);
+    if (itr == m_port_map.end()) {
+        return NULL;
+    }
+    return FetchFromUID(itr->second);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Module interface
+
+/// Initialize ServiceManager
+void Init() {
+    g_manager = new Manager;
+    
+    g_manager->AddService(new SRV::Interface);
+    g_manager->AddService(new APT_U::Interface);
+    g_manager->AddService(new GSP_GPU::Interface);
+    g_manager->AddService(new HID_User::Interface);
+
+    NOTICE_LOG(HLE, "Services initialized OK");
+}
+
+/// Shutdown ServiceManager
+void Shutdown() {
+    delete g_manager;
+    NOTICE_LOG(HLE, "Services shutdown OK");
+}
+
+
+}
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
new file mode 100644
index 0000000000..9cbf8b6fa9
--- /dev/null
+++ b/src/core/hle/service/service.h
@@ -0,0 +1,143 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <vector>
+#include <map>
+#include <string>
+
+#include "common/common.h"
+#include "common/common_types.h"
+#include "core/hle/syscall.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Service
+
+namespace Service {
+
+typedef s32 NativeUID;                          ///< Native handle for a service
+
+static const int kMaxPortSize           = 0x08; ///< Maximum size of a port name (8 characters)
+static const int kCommandHeaderOffset   = 0x80; ///< Offset into command buffer of header
+
+class Manager;
+
+/// Interface to a CTROS service
+class Interface {
+    friend class Manager;
+public:
+
+    Interface() {
+    }
+
+    virtual ~Interface() {
+    }
+
+    /**
+     * Gets the UID for the serice
+     * @return UID of service in native format
+     */
+    NativeUID GetUID() const {
+        return (NativeUID)m_uid;
+    }
+
+    /**
+     * Gets the string name used by CTROS for a service
+     * @return Port name of service
+     */
+    virtual std::string GetPortName() const {
+        return "[UNKNOWN SERVICE PORT]";
+    }
+
+    /**
+     * Called when svcSendSyncRequest is called, loads command buffer and executes comand
+     * @return Return result of svcSendSyncRequest passed back to user app
+     */
+    Syscall::Result Sync() {
+        u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + kCommandHeaderOffset);
+        auto itr = m_functions.find(cmd_buff[0]);
+
+        if (itr == m_functions.end()) {
+            ERROR_LOG(OSHLE, "Unknown/unimplemented function: port = %s, command = 0x%08X!", 
+                GetPortName().c_str(), cmd_buff[0]);
+            return -1;
+        }
+        if (itr->second.func == NULL) {
+            ERROR_LOG(OSHLE, "Unimplemented function: port = %s, name = %s!", 
+                GetPortName().c_str(), itr->second.name.c_str());
+            return -1;
+        } 
+
+        itr->second.func();
+
+        return 0; // TODO: Implement return from actual function
+    }
+
+protected:
+    /**
+     * Registers the functions in the service
+     */
+    void Register(const HLE::FunctionDef* functions, int len) {
+        for (int i = 0; i < len; i++) {
+            m_functions[functions[i].id] = functions[i];
+        }
+    }
+
+private:
+    u32 m_uid;
+    std::map<u32, HLE::FunctionDef> m_functions;
+
+    DISALLOW_COPY_AND_ASSIGN(Interface);
+};
+
+/// Simple class to manage accessing services from ports and UID handles
+class Manager {
+
+public:
+    Manager();
+
+    ~Manager();
+
+    /// Add a service to the manager (does not create it though)
+    void AddService(Interface* service);
+
+    /// Removes a service from the manager (does not delete it though)
+    void DeleteService(std::string port_name);
+
+    /// Get a Service Interface from its UID
+    Interface* FetchFromUID(u32 uid);
+
+    /// Get a Service Interface from its port
+    Interface* FetchFromPortName(std::string port_name);
+
+private:
+
+    /// Convert an index into m_services vector into a UID
+    static u32 GetUIDFromIndex(const int index) {
+        return index | 0x10000000;
+    }
+
+    /// Convert a UID into an index into m_services
+    static int GetIndexFromUID(const u32 uid) {
+        return uid & 0x0FFFFFFF;
+    }
+
+    std::vector<Interface*>     m_services;
+    std::map<std::string, u32>  m_port_map;
+
+    DISALLOW_COPY_AND_ASSIGN(Manager);
+};
+
+/// Initialize ServiceManager
+void Init();
+
+/// Shutdown ServiceManager
+void Shutdown();
+
+
+extern Manager* g_manager; ///< Service manager
+
+
+} // namespace
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
new file mode 100644
index 0000000000..579ea4a344
--- /dev/null
+++ b/src/core/hle/service/srv.cpp
@@ -0,0 +1,58 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "core/hle/hle.h"
+#include "core/hle/service/srv.h"
+#include "core/hle/service/service.h"
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace SRV
+
+namespace SRV {
+
+void Initialize() {
+    NOTICE_LOG(OSHLE, "SRV::Sync - Initialize");
+}
+
+void GetServiceHandle() {
+    Syscall::Result res = 0;
+    u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + Service::kCommandHeaderOffset);
+
+    std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
+    Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
+
+    NOTICE_LOG(OSHLE, "SRV::Sync - GetHandle - port: %s, handle: 0x%08X", port_name.c_str(), 
+        service->GetUID());
+
+    if (NULL != service) {
+        cmd_buff[3] = service->GetUID();
+    } else {
+        ERROR_LOG(OSHLE, "Service %s does not exist", port_name.c_str());
+        res = -1;
+    }
+    cmd_buff[1] = res;
+
+    //return res;
+}
+
+const HLE::FunctionDef FunctionTable[] = {
+    {0x00010002, Initialize,        "Initialize"},
+    {0x00020000, NULL,              "GetProcSemaphore"},
+    {0x00030100, NULL,              "RegisterService"},
+    {0x000400C0, NULL,              "UnregisterService"},
+    {0x00050100, GetServiceHandle,  "GetServiceHandle"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+    Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+Interface::~Interface() {
+}
+
+} // namespace
diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h
new file mode 100644
index 0000000000..d9ac8fc888
--- /dev/null
+++ b/src/core/hle/service/srv.h
@@ -0,0 +1,40 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace SRV
+
+namespace SRV {
+
+/// Interface to "srv:" service
+class Interface : public Service::Interface {
+
+public:
+
+    Interface();
+
+    ~Interface();
+
+    /**
+     * Gets the string name used by CTROS for the service
+     * @return Port name of service
+     */
+    std::string GetPortName() const {
+        return "srv:";
+    }
+
+    /**
+     * Called when svcSendSyncRequest is called, loads command buffer and executes comand
+     * @return Return result of svcSendSyncRequest passed back to user app
+     */
+    Syscall::Result Sync();
+
+private:
+     
+    DISALLOW_COPY_AND_ASSIGN(Interface);
+};
+
+} // namespace
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
new file mode 100644
index 0000000000..e5533a7412
--- /dev/null
+++ b/src/core/hle/syscall.cpp
@@ -0,0 +1,197 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#include <map>
+
+#include "core/mem_map.h"
+
+#include "core/hle/function_wrappers.h"
+#include "core/hle/syscall.h"
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Syscall
+
+namespace Syscall {
+
+/// Map application or GSP heap memory
+Result ControlMemory(void* outaddr, u32 addr0, u32 addr1, u32 size, u32 operation, u32 permissions) {
+    u32 virtual_address = 0x00000000;
+
+    switch (operation) {
+
+    // Map GSP heap memory?
+    case 0x00010003:
+        virtual_address = Memory::MapBlock_HeapGSP(size, operation, permissions);
+        break;
+
+    // Unknown ControlMemory operation
+    default:
+        ERROR_LOG(OSHLE, "Unknown ControlMemory operation %08X", operation);
+    }
+
+    Core::g_app_core->SetReg(1,  Memory::MapBlock_HeapGSP(size, operation, permissions));
+    return 0;
+}
+
+/// Connect to an OS service given the port name, returns the handle to the port to out
+Result ConnectToPort(void* out, const char* port_name) {
+    Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
+    Core::g_app_core->SetReg(1, service->GetUID());
+    return 0;
+}
+
+/// Synchronize to an OS service
+Result SendSyncRequest(Handle session) {
+    Service::Interface* service = Service::g_manager->FetchFromUID(session);
+    service->Sync();
+    return 0;
+}
+
+/// Close a handle
+Result CloseHandle(Handle handle) {
+    // ImplementMe
+    return 0;
+}
+
+/// Wait for a handle to synchronize, timeout after the specified nanoseconds
+Result WaitSynchronization1(Handle handle, s64 nanoseconds) {
+    // ImplementMe
+    return 0;
+}
+
+const HLE::FunctionDef Syscall_Table[] = {
+    {0x00,  NULL,                               "Unknown"},
+    {0x01,  WrapI_VUUUUU<ControlMemory>,        "ControlMemory"},
+    {0x02,  NULL,                               "QueryMemory"},
+    {0x03,  NULL,                               "ExitProcess"},
+    {0x04,  NULL,                               "GetProcessAffinityMask"},
+    {0x05,  NULL,                               "SetProcessAffinityMask"},
+    {0x06,  NULL,                               "GetProcessIdealProcessor"},
+    {0x07,  NULL,                               "SetProcessIdealProcessor"},
+    {0x08,  NULL,                               "CreateThread"},
+    {0x09,  NULL,                               "ExitThread"},
+    {0x0A,  NULL,                               "SleepThread"},
+    {0x0B,  NULL,                               "GetThreadPriority"},
+    {0x0C,  NULL,                               "SetThreadPriority"},
+    {0x0D,  NULL,                               "GetThreadAffinityMask"},
+    {0x0E,  NULL,                               "SetThreadAffinityMask"},
+    {0x0F,  NULL,                               "GetThreadIdealProcessor"},
+    {0x10,  NULL,                               "SetThreadIdealProcessor"},
+    {0x11,  NULL,                               "GetCurrentProcessorNumber"},
+    {0x12,  NULL,                               "Run"},
+    {0x13,  NULL,                               "CreateMutex"},
+    {0x14,  NULL,                               "ReleaseMutex"},
+    {0x15,  NULL,                               "CreateSemaphore"},
+    {0x16,  NULL,                               "ReleaseSemaphore"},
+    {0x17,  NULL,                               "CreateEvent"},
+    {0x18,  NULL,                               "SignalEvent"},
+    {0x19,  NULL,                               "ClearEvent"},
+    {0x1A,  NULL,                               "CreateTimer"},
+    {0x1B,  NULL,                               "SetTimer"},
+    {0x1C,  NULL,                               "CancelTimer"},
+    {0x1D,  NULL,                               "ClearTimer"},
+    {0x1E,  NULL,                               "CreateMemoryBlock"},
+    {0x1F,  NULL,                               "MapMemoryBlock"},
+    {0x20,  NULL,                               "UnmapMemoryBlock"},
+    {0x21,  NULL,                               "CreateAddressArbiter"},
+    {0x22,  NULL,                               "ArbitrateAddress"},
+    {0x23,  WrapI_U<CloseHandle>,               "CloseHandle"},
+    {0x24,  WrapI_US64<WaitSynchronization1>,   "WaitSynchronization1"},
+    {0x25,  NULL,                               "WaitSynchronizationN"},
+    {0x26,  NULL,                               "SignalAndWait"},
+    {0x27,  NULL,                               "DuplicateHandle"},
+    {0x28,  NULL,                               "GetSystemTick"},
+    {0x29,  NULL,                               "GetHandleInfo"},
+    {0x2A,  NULL,                               "GetSystemInfo"},
+    {0x2B,  NULL,                               "GetProcessInfo"},
+    {0x2C,  NULL,                               "GetThreadInfo"},
+    {0x2D,  WrapI_VC<ConnectToPort>,            "ConnectToPort"},
+    {0x2E,  NULL,                               "SendSyncRequest1"},
+    {0x2F,  NULL,                               "SendSyncRequest2"},
+    {0x30,  NULL,                               "SendSyncRequest3"},
+    {0x31,  NULL,                               "SendSyncRequest4"},
+    {0x32,  WrapI_U<SendSyncRequest>,           "SendSyncRequest"},
+    {0x33,  NULL,                               "OpenProcess"},
+    {0x34,  NULL,                               "OpenThread"},
+    {0x35,  NULL,                               "GetProcessId"},
+    {0x36,  NULL,                               "GetProcessIdOfThread"},
+    {0x37,  NULL,                               "GetThreadId"},
+    {0x38,  NULL,                               "GetResourceLimit"},
+    {0x39,  NULL,                               "GetResourceLimitLimitValues"},
+    {0x3A,  NULL,                               "GetResourceLimitCurrentValues"},
+    {0x3B,  NULL,                               "GetThreadContext"},
+    {0x3C,  NULL,                               "Break"},
+    {0x3D,  NULL,                               "OutputDebugString"},
+    {0x3E,  NULL,                               "ControlPerformanceCounter"},
+    {0x3F,  NULL,                               "Unknown"},
+    {0x40,  NULL,                               "Unknown"},
+    {0x41,  NULL,                               "Unknown"},
+    {0x42,  NULL,                               "Unknown"},
+    {0x43,  NULL,                               "Unknown"},
+    {0x44,  NULL,                               "Unknown"},
+    {0x45,  NULL,                               "Unknown"},
+    {0x46,  NULL,                               "Unknown"},
+    {0x47,  NULL,                               "CreatePort"},
+    {0x48,  NULL,                               "CreateSessionToPort"},
+    {0x49,  NULL,                               "CreateSession"},
+    {0x4A,  NULL,                               "AcceptSession"},
+    {0x4B,  NULL,                               "ReplyAndReceive1"},
+    {0x4C,  NULL,                               "ReplyAndReceive2"},
+    {0x4D,  NULL,                               "ReplyAndReceive3"},
+    {0x4E,  NULL,                               "ReplyAndReceive4"},
+    {0x4F,  NULL,                               "ReplyAndReceive"},
+    {0x50,  NULL,                               "BindInterrupt"},
+    {0x51,  NULL,                               "UnbindInterrupt"},
+    {0x52,  NULL,                               "InvalidateProcessDataCache"},
+    {0x53,  NULL,                               "StoreProcessDataCache"},
+    {0x54,  NULL,                               "FlushProcessDataCache"},
+    {0x55,  NULL,                               "StartInterProcessDma"},
+    {0x56,  NULL,                               "StopDma"},
+    {0x57,  NULL,                               "GetDmaState"},
+    {0x58,  NULL,                               "RestartDma"},
+    {0x59,  NULL,                               "Unknown"},
+    {0x5A,  NULL,                               "Unknown"},
+    {0x5B,  NULL,                               "Unknown"},
+    {0x5C,  NULL,                               "Unknown"},
+    {0x5D,  NULL,                               "Unknown"},
+    {0x5E,  NULL,                               "Unknown"},
+    {0x5F,  NULL,                               "Unknown"},
+    {0x60,  NULL,                               "DebugActiveProcess"},
+    {0x61,  NULL,                               "BreakDebugProcess"},
+    {0x62,  NULL,                               "TerminateDebugProcess"},
+    {0x63,  NULL,                               "GetProcessDebugEvent"},
+    {0x64,  NULL,                               "ContinueDebugEvent"},
+    {0x65,  NULL,                               "GetProcessList"},
+    {0x66,  NULL,                               "GetThreadList"},
+    {0x67,  NULL,                               "GetDebugThreadContext"},
+    {0x68,  NULL,                               "SetDebugThreadContext"},
+    {0x69,  NULL,                               "QueryDebugProcessMemory"},
+    {0x6A,  NULL,                               "ReadProcessMemory"},
+    {0x6B,  NULL,                               "WriteProcessMemory"},
+    {0x6C,  NULL,                               "SetHardwareBreakPoint"},
+    {0x6D,  NULL,                               "GetDebugThreadParam"},
+    {0x6E,  NULL,                               "Unknown"},
+    {0x6F,  NULL,                               "Unknown"},
+    {0x70,  NULL,                               "ControlProcessMemory"},
+    {0x71,  NULL,                               "MapProcessMemory"},
+    {0x72,  NULL,                               "UnmapProcessMemory"},
+    {0x73,  NULL,                               "Unknown"},
+    {0x74,  NULL,                               "Unknown"},
+    {0x75,  NULL,                               "Unknown"},
+    {0x76,  NULL,                               "TerminateProcess"},
+    {0x77,  NULL,                               "Unknown"},
+    {0x78,  NULL,                               "CreateResourceLimit"},
+    {0x79,  NULL,                               "Unknown"},
+    {0x7A,  NULL,                               "Unknown"},
+    {0x7B,  NULL,                               "Unknown"},
+    {0x7C,  NULL,                               "KernelSetState"},
+    {0x7D,  NULL,                               "QueryProcessMemory"},
+};
+
+void Register() {
+    HLE::RegisterModule("SyscallTable", ARRAY_SIZE(Syscall_Table), Syscall_Table);
+}
+
+} // namespace
diff --git a/src/core/hle/syscall.h b/src/core/hle/syscall.h
new file mode 100644
index 0000000000..7a94e01367
--- /dev/null
+++ b/src/core/hle/syscall.h
@@ -0,0 +1,19 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include "common/common_types.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Syscall
+
+namespace Syscall {
+
+typedef u32 Handle;
+typedef s32 Result;
+
+void Register();
+
+} // namespace
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
index 44625e3af3..16bd701254 100644
--- a/src/core/hw/hw.cpp
+++ b/src/core/hw/hw.cpp
@@ -6,18 +6,73 @@
 #include "common/log.h"
 
 #include "core/hw/hw.h"
-#include "core/hw/hw_lcd.h"
+#include "core/hw/lcd.h"
+#include "core/hw/ndma.h"
 
 namespace HW {
 
+enum {
+    ADDRESS_CONFIG      = 0x10000000,
+    ADDRESS_IRQ         = 0x10001000,
+    ADDRESS_NDMA        = 0x10002000,
+    ADDRESS_TIMER       = 0x10003000,
+    ADDRESS_CTRCARD     = 0x10004000,
+    ADDRESS_CTRCARD_2   = 0x10005000,
+    ADDRESS_SDMC_NAND   = 0x10006000,
+    ADDRESS_SDMC_NAND_2 = 0x10007000,   // Apparently not used on retail
+    ADDRESS_PXI         = 0x10008000,
+    ADDRESS_AES         = 0x10009000,
+    ADDRESS_SHA         = 0x1000A000,
+    ADDRESS_RSA         = 0x1000B000,
+    ADDRESS_XDMA        = 0x1000C000,
+    ADDRESS_SPICARD     = 0x1000D800,
+    ADDRESS_CONFIG_2    = 0x10010000,
+    ADDRESS_HASH        = 0x10101000,
+    ADDRESS_CSND        = 0x10103000,
+    ADDRESS_DSP         = 0x10140000,
+    ADDRESS_PDN         = 0x10141000,
+    ADDRESS_CODEC       = 0x10141000,
+    ADDRESS_SPI         = 0x10142000,
+    ADDRESS_SPI_2       = 0x10143000,
+    ADDRESS_I2C         = 0x10144000,
+    ADDRESS_CODEC_2     = 0x10145000,
+    ADDRESS_HID         = 0x10146000,
+    ADDRESS_PAD         = 0x10146000,
+    ADDRESS_PTM         = 0x10146000,
+    ADDRESS_I2C_2       = 0x10148000,
+    ADDRESS_SPI_3       = 0x10160000,
+    ADDRESS_I2C_3       = 0x10161000,
+    ADDRESS_MIC         = 0x10162000,
+    ADDRESS_PXI_2       = 0x10163000,
+    ADDRESS_NTRCARD     = 0x10164000,
+    ADDRESS_DSP_2       = 0x10203000,
+    ADDRESS_HASH_2      = 0x10301000,
+};
+
 template <typename T>
 inline void Read(T &var, const u32 addr) {
-    NOTICE_LOG(HW, "Hardware read from address %08X", addr);
+    switch (addr & 0xFFFFF000) {
+    
+    case ADDRESS_NDMA:
+        NDMA::Read(var, addr);
+        break;
+
+    default:
+        ERROR_LOG(HW, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
+    }
 }
 
 template <typename T>
 inline void Write(u32 addr, const T data) {
-    NOTICE_LOG(HW, "Hardware write to address %08X", addr);
+    switch (addr & 0xFFFFF000) {
+    
+    case ADDRESS_NDMA:
+        NDMA::Write(addr, data);
+        break;
+
+    default:
+        ERROR_LOG(HW, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
+    }
 }
 
 // Explicitly instantiate template functions because we aren't defining this in the header:
@@ -27,25 +82,27 @@ template void Read<u32>(u32 &var, const u32 addr);
 template void Read<u16>(u16 &var, const u32 addr);
 template void Read<u8>(u8 &var, const u32 addr);
 
-template void Write<const u64>(u32 addr, const u64 data);
-template void Write<const u32>(u32 addr, const u32 data);
-template void Write<const u16>(u32 addr, const u16 data);
-template void Write<const u8>(u32 addr, const u8 data);
+template void Write<u64>(u32 addr, const u64 data);
+template void Write<u32>(u32 addr, const u32 data);
+template void Write<u16>(u32 addr, const u16 data);
+template void Write<u8>(u32 addr, const u8 data);
 
 /// Update hardware
 void Update() {
     LCD::Update();
+    NDMA::Update();
 }
 
 /// Initialize hardware
 void Init() {
     LCD::Init();
-    NOTICE_LOG(HW, "Hardware initialized OK");
+    NDMA::Init();
+    NOTICE_LOG(HW, "initialized OK");
 }
 
 /// Shutdown hardware
 void Shutdown() {
-    NOTICE_LOG(HW, "Hardware shutdown OK");
+    NOTICE_LOG(HW, "shutdown OK");
 }
 
 }
\ No newline at end of file
diff --git a/src/core/hw/hw_lcd.cpp b/src/core/hw/lcd.cpp
similarity index 88%
rename from src/core/hw/hw_lcd.cpp
rename to src/core/hw/lcd.cpp
index fd783a84a5..3013673f84 100644
--- a/src/core/hw/hw_lcd.cpp
+++ b/src/core/hw/lcd.cpp
@@ -6,7 +6,7 @@
 #include "common/log.h"
 
 #include "core/core.h"
-#include "core/hw/hw_lcd.h"
+#include "core/hw/lcd.h"
 
 #include "video_core/video_core.h"
 
@@ -37,12 +37,12 @@ void Update() {
 /// Initialize hardware
 void Init() {
     g_last_ticks = Core::g_app_core->GetTicks();
-    NOTICE_LOG(LCD, "LCD initialized OK");
+    NOTICE_LOG(LCD, "initialized OK");
 }
 
 /// Shutdown hardware
 void Shutdown() {
-    NOTICE_LOG(LCD, "LCD shutdown OK");
+    NOTICE_LOG(LCD, "shutdown OK");
 }
 
 } // namespace
diff --git a/src/core/hw/hw_lcd.h b/src/core/hw/lcd.h
similarity index 100%
rename from src/core/hw/hw_lcd.h
rename to src/core/hw/lcd.h
diff --git a/src/core/hw/ndma.cpp b/src/core/hw/ndma.cpp
new file mode 100644
index 0000000000..52e459ebdd
--- /dev/null
+++ b/src/core/hw/ndma.cpp
@@ -0,0 +1,48 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "common/common_types.h"
+#include "common/log.h"
+
+#include "core/hw/ndma.h"
+
+namespace NDMA {
+
+template <typename T>
+inline void Read(T &var, const u32 addr) {
+    ERROR_LOG(NDMA, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
+}
+
+template <typename T>
+inline void Write(u32 addr, const T data) {
+    ERROR_LOG(NDMA, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
+}
+
+// Explicitly instantiate template functions because we aren't defining this in the header:
+
+template void Read<u64>(u64 &var, const u32 addr);
+template void Read<u32>(u32 &var, const u32 addr);
+template void Read<u16>(u16 &var, const u32 addr);
+template void Read<u8>(u8 &var, const u32 addr);
+
+template void Write<u64>(u32 addr, const u64 data);
+template void Write<u32>(u32 addr, const u32 data);
+template void Write<u16>(u32 addr, const u16 data);
+template void Write<u8>(u32 addr, const u8 data);
+
+/// Update hardware
+void Update() {
+}
+
+/// Initialize hardware
+void Init() {
+    NOTICE_LOG(LCD, "initialized OK");
+}
+
+/// Shutdown hardware
+void Shutdown() {
+    NOTICE_LOG(LCD, "shutdown OK");
+}
+
+} // namespace
diff --git a/src/core/hw/ndma.h b/src/core/hw/ndma.h
new file mode 100644
index 0000000000..d8fa3d40b3
--- /dev/null
+++ b/src/core/hw/ndma.h
@@ -0,0 +1,26 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/common_types.h"
+
+namespace NDMA {
+
+template <typename T>
+inline void Read(T &var, const u32 addr);
+
+template <typename T>
+inline void Write(u32 addr, const T data);
+
+/// Update hardware
+void Update();
+
+/// Initialize hardware
+void Init();
+
+/// Shutdown hardware
+void Shutdown();
+
+} // namespace
diff --git a/src/core/mem_map.cpp b/src/core/mem_map.cpp
index 96f8d0440b..180829239c 100644
--- a/src/core/mem_map.cpp
+++ b/src/core/mem_map.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 Citra Emulator Project
+ // Copyright 2014 Citra Emulator Project
 // Licensed under GPLv2
 // Refer to the license.txt file included.
 
@@ -12,27 +12,27 @@
 
 namespace Memory {
 
-    
 u8*    g_base                   = NULL;         ///< The base pointer to the auto-mirrored arena.
 
 MemArena g_arena;                               ///< The MemArena class
 
-u8* g_bootrom                   = NULL;         ///< Bootrom physical memory
-u8* g_fcram                     = NULL;         ///< Main memory (FCRAM) pointer
+u8* g_heap_gsp                  = NULL;         ///< GSP heap (main memory)
+u8* g_heap                      = NULL;         ///< Application heap (main memory)
 u8* g_vram                      = NULL;         ///< Video memory (VRAM) pointer
-u8* g_scratchpad                = NULL;         ///< Scratchpad memory - Used for main thread stack
 
 u8* g_physical_bootrom          = NULL;         ///< Bootrom physical memory
 u8* g_uncached_bootrom          = NULL;
 
 u8* g_physical_fcram            = NULL;         ///< Main physical memory (FCRAM)
+u8* g_physical_heap_gsp         = NULL;
 u8* g_physical_vram             = NULL;         ///< Video physical memory (VRAM)
 u8* g_physical_scratchpad       = NULL;         ///< Scratchpad memory used for main thread stack
 
 // We don't declare the IO region in here since its handled by other means.
 static MemoryView g_views[] = {
-    { &g_vram,  &g_physical_vram,   MEM_VRAM_VADDR,     MEM_VRAM_SIZE,  0 },
-    { &g_fcram, &g_physical_fcram,  MEM_FCRAM_VADDR,    MEM_FCRAM_SIZE, MV_IS_PRIMARY_RAM },
+    {&g_vram,       &g_physical_vram,       VRAM_VADDR,     VRAM_SIZE,      0},
+    {&g_heap_gsp,   &g_physical_heap_gsp,   HEAP_GSP_VADDR, HEAP_GSP_SIZE,  0},
+    {&g_heap,       &g_physical_fcram,      HEAP_VADDR,     HEAP_SIZE,      MV_IS_PRIMARY_RAM},
 };
 
 /*static MemoryView views[] =
@@ -56,14 +56,12 @@ void Init() {
 
     for (size_t i = 0; i < ARRAY_SIZE(g_views); i++) {
         if (g_views[i].flags & MV_IS_PRIMARY_RAM)
-            g_views[i].size = MEM_FCRAM_SIZE;
+            g_views[i].size = FCRAM_SIZE;
     }
 
     g_base = MemoryMap_Setup(g_views, kNumMemViews, flags, &g_arena);
 
-    g_scratchpad = new u8[MEM_SCRATCHPAD_SIZE];
-
-    NOTICE_LOG(MEMMAP, "Memory system initialized. RAM at %p (mirror at 0 @ %p)", g_fcram, 
+    NOTICE_LOG(MEMMAP, "initialized OK, RAM at %p (mirror at 0 @ %p)", g_heap, 
         g_physical_fcram);
 }
 
@@ -72,12 +70,9 @@ void Shutdown() {
     MemoryMap_Shutdown(g_views, kNumMemViews, flags, &g_arena);
     
     g_arena.ReleaseSpace();
-    delete[] g_scratchpad;
-    
-    g_base          = NULL;
-    g_scratchpad    = NULL;
+    g_base = NULL;
 
-    NOTICE_LOG(MEMMAP, "Memory system shut down.");
+    NOTICE_LOG(MEMMAP, "shutdown OK");
 }
 
 } // namespace
diff --git a/src/core/mem_map.h b/src/core/mem_map.h
index 1a3bd7234e..ab1eb2606a 100644
--- a/src/core/mem_map.h
+++ b/src/core/mem_map.h
@@ -4,39 +4,67 @@
 
 #pragma once
 
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
 #include "common/common.h"
 #include "common/common_types.h"
 
+namespace Memory {
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 enum {
-    MEM_BOOTROM_SIZE        = 0x00010000,	///< Bootrom (super secret code/data @ 0x8000) size
-    MEM_MPCORE_PRIV_SIZE    = 0x00002000,	///< MPCore private memory region size
-    MEM_VRAM_SIZE           = 0x00600000,	///< VRAM size
-    MEM_DSP_SIZE            = 0x00080000,	///< DSP memory size
-    MEM_AXI_WRAM_SIZE       = 0x00080000,	///< AXI WRAM size
-    MEM_FCRAM_SIZE          = 0x08000000,	///< FCRAM size... Really 0x07E00000, but power of 2
-                                            //      works much better
-    MEM_SCRATCHPAD_SIZE     = 0x00004000,  ///< Typical stack size - TODO: Read from exheader
-                            
-    MEM_VRAM_MASK           = 0x007FFFFF,
-    MEM_FCRAM_MASK          = (MEM_FCRAM_SIZE - 1),	            ///< FCRAM mask
-    MEM_SCRATCHPAD_MASK     = (MEM_SCRATCHPAD_SIZE - 1),           ///< Scratchpad memory mask
-                            
-    MEM_FCRAM_PADDR     = 0x20000000,                           ///< FCRAM physical address
-    MEM_FCRAM_PADDR_END = (MEM_FCRAM_PADDR + MEM_FCRAM_SIZE),   ///< FCRAM end of physical space
-    MEM_FCRAM_VADDR     = 0x08000000,                           ///< FCRAM virtual address
-    MEM_FCRAM_VADDR_END = (MEM_FCRAM_VADDR + MEM_FCRAM_SIZE),   ///< FCRAM end of virtual space
+    BOOTROM_SIZE            = 0x00010000,   ///< Bootrom (super secret code/data @ 0x8000) size
+    MPCORE_PRIV_SIZE        = 0x00002000,   ///< MPCore private memory region size
+    VRAM_SIZE               = 0x00600000,   ///< VRAM size
+    DSP_SIZE                = 0x00080000,   ///< DSP memory size
+    AXI_WRAM_SIZE           = 0x00080000,   ///< AXI WRAM size
+    FCRAM_SIZE              = 0x08000000,   ///< FCRAM size
+    SCRATCHPAD_SIZE         = 0x00004000,   ///< Typical stack size - TODO: Read from exheader
+    HEAP_GSP_SIZE           = 0x02000000,   ///< GSP heap size... TODO: Define correctly?
+    HEAP_SIZE               = FCRAM_SIZE,   ///< Application heap size
 
-    MEM_VRAM_VADDR          = 0x1F000000,
-    MEM_SCRATCHPAD_VADDR    = (0x10000000 - MEM_SCRATCHPAD_SIZE),  ///< Scratchpad virtual address
+    HEAP_PADDR              = HEAP_GSP_SIZE,
+    HEAP_PADDR_END          = (HEAP_PADDR + HEAP_SIZE),
+    HEAP_VADDR              = 0x08000000,
+    HEAP_VADDR_END          = (HEAP_VADDR + HEAP_SIZE),
+    HEAP_GSP_VADDR          = 0x14000000,
+    HEAP_GSP_VADDR_END      = (HEAP_GSP_VADDR + HEAP_GSP_SIZE),
+    HEAP_GSP_PADDR          = 0x00000000,
+    HEAP_GSP_PADDR_END      = (HEAP_GSP_PADDR + HEAP_GSP_SIZE),
+
+    VRAM_MASK               = 0x007FFFFF,
+    FCRAM_MASK              = (FCRAM_SIZE - 1),                 ///< FCRAM mask
+    SCRATCHPAD_MASK         = (SCRATCHPAD_SIZE - 1),            ///< Scratchpad memory mask
+    HEAP_GSP_MASK           = (HEAP_GSP_SIZE - 1),
+    HEAP_MASK               = (HEAP_SIZE - 1),
+
+    FCRAM_PADDR             = 0x20000000,                       ///< FCRAM physical address
+    FCRAM_PADDR_END         = (FCRAM_PADDR + FCRAM_SIZE),       ///< FCRAM end of physical space
+    FCRAM_VADDR             = 0x08000000,                       ///< FCRAM virtual address
+    FCRAM_VADDR_END         = (FCRAM_VADDR + FCRAM_SIZE),       ///< FCRAM end of virtual space
+
+    VRAM_VADDR              = 0x1F000000,
+    SCRATCHPAD_VADDR_END    = 0x10000000,
+    SCRATCHPAD_VADDR        = (SCRATCHPAD_VADDR_END - SCRATCHPAD_SIZE), ///< Stack space
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-namespace Memory {
+/// Represents a block of heap memory mapped by ControlMemory
+struct HeapBlock {
+    HeapBlock() : base_address(0), address(0), size(0), operation(0), permissions(0) {
+    }
+    u32 base_address;
+    u32 address;
+    u32 size;
+    u32 operation;
+    u32 permissions;
+
+    const u32 GetVirtualAddress() const{
+        return base_address + address;
+    }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
 
 // Base is a pointer to the base of the memory map. Yes, some MMU tricks
 // are used to set up a full GC or Wii memory map in process memory.  on
@@ -50,9 +78,9 @@ extern u8 *g_base;
 // These are guaranteed to point to "low memory" addresses (sub-32-bit).
 // 64-bit: Pointers to low-mem (sub-0x10000000) mirror
 // 32-bit: Same as the corresponding physical/virtual pointers.
-extern u8* g_fcram;			///< Main memory
-extern u8* g_vram;			///< Video memory (VRAM)
-extern u8* g_scratchpad;    ///< Stack memory
+extern u8* g_heap_gsp;      ///< GSP heap (main memory)
+extern u8* g_heap;          ///< Application heap (main memory)
+extern u8* g_vram;          ///< Video memory (VRAM)
 
 void Init();
 void Shutdown();
@@ -70,4 +98,16 @@ void Write32(const u32 addr, const u32 data);
 
 u8* GetPointer(const u32 Address);
 
+/**
+ * Maps a block of memory on the GSP heap
+ * @param size Size of block in bytes
+ * @param operation Control memory operation
+ * @param permissions Control memory permissions
+ */
+u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions);
+
+inline const char* GetCharPointer(const u32 address) {
+    return (const char *)GetPointer(address);
+}
+
 } // namespace
diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp
index 4c0e08b3fb..af4cfacbdf 100644
--- a/src/core/mem_map_funcs.cpp
+++ b/src/core/mem_map_funcs.cpp
@@ -2,151 +2,146 @@
 // Licensed under GPLv2
 // Refer to the license.txt file included.
 
+#include <map>
+
 #include "common/common.h"
 
 #include "core/mem_map.h"
 #include "core/hw/hw.h"
+#include "hle/hle.h"
 
 namespace Memory {
 
+std::map<u32, HeapBlock> g_heap_gsp_map;
+
+/// Convert a physical address to virtual address
+u32 _AddressPhysicalToVirtual(const u32 addr) {
+    // Our memory interface read/write functions assume virtual addresses. Put any physical address 
+    // to virtual address translations here. This is obviously quite hacky... But we're not doing 
+    // any MMU emulation yet or anything
+    if ((addr >= FCRAM_PADDR) && (addr < (FCRAM_PADDR_END))) {
+        return (addr & FCRAM_MASK) | FCRAM_VADDR;
+    }
+    return addr;
+}
+
 template <typename T>
 inline void _Read(T &var, const u32 addr) {
     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
     // TODO: Make sure this represents the mirrors in a correct way.
     // Could just do a base-relative read, too.... TODO
 
+    const u32 vaddr = _AddressPhysicalToVirtual(addr);
+    
+    // Memory allocated for HLE use that can be addressed from the emulated application
+    // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE
+    // core running the user application (appcore)
+    if (vaddr >= HLE::CMD_BUFFER_ADDR && vaddr < HLE::CMD_BUFFER_ADDR_END) {
+        HLE::Read<T>(var, vaddr);
+
     // Hardware I/O register reads
     // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
-    if ((addr & 0xFF000000) == 0x10000000 || (addr & 0xFF000000) == 0x1E000000) {
-        HW::Read<T>(var, addr);
+    } else if ((vaddr & 0xFF000000) == 0x10000000 || (vaddr & 0xFF000000) == 0x1E000000) {
+        HW::Read<T>(var, vaddr);
 
-    // FCRAM virtual address reads
-    } else if ((addr & 0x3E000000) == 0x08000000) {
-        var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
+    // FCRAM - GSP heap
+    } else if ((vaddr > HEAP_GSP_VADDR)  && (vaddr < HEAP_GSP_VADDR_END)) {
+        var = *((const T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK]);
 
-    // Scratchpad memory
-    } else if (addr > MEM_SCRATCHPAD_VADDR && addr <= (MEM_SCRATCHPAD_VADDR + MEM_SCRATCHPAD_SIZE)) {
-        var = *((const T*)&g_scratchpad[addr & MEM_SCRATCHPAD_MASK]);
- 
-    /*else if ((addr & 0x3F800000) == 0x04000000) {
-        var = *((const T*)&m_pVRAM[addr & VRAM_MASK]);
-    }*/
+    // FCRAM - application heap
+    } else if ((vaddr > HEAP_VADDR)  && (vaddr < HEAP_VADDR_END)) {
+        var = *((const T*)&g_heap[vaddr & HEAP_MASK]);
 
-    // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses. 
-    // Until we progress far enough along, we'll accept all physical address reads here. I think 
-    // that this is typically a corner-case from usermode software unless they are trying to do 
-    // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
-    } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
-        var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
+    /*else if ((vaddr & 0x3F800000) == 0x04000000) {
+        var = *((const T*)&m_pVRAM[vaddr & VRAM_MASK]);*/
 
     } else {
-        _assert_msg_(MEMMAP, false, "unknown memory read");
+        //_assert_msg_(MEMMAP, false, "unknown Read%d @ 0x%08X", sizeof(var) * 8, vaddr);
     }
 }
 
 template <typename T>
 inline void _Write(u32 addr, const T data) {
+    u32 vaddr = _AddressPhysicalToVirtual(addr);
     
+    // Memory allocated for HLE use that can be addressed from the emulated application
+    // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE
+    // core running the user application (appcore)
+    if (vaddr >= HLE::CMD_BUFFER_ADDR && vaddr < HLE::CMD_BUFFER_ADDR_END) {
+        HLE::Write<T>(vaddr, data);
+
     // Hardware I/O register writes
     // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
-    if ((addr & 0xFF000000) == 0x10000000 || (addr & 0xFF000000) == 0x1E000000) {
-        HW::Write<const T>(addr, data);
-    
-    // ExeFS:/.code is loaded here:
-    } else if ((addr & 0xFFF00000) == 0x00100000) {
-        // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
-        // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions
-        // The ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when
-        // the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only 
-        // applies when this flag is clear. Executables are usually loaded to 0x14000000 when the 
-        // exheader "special memory" flag is set, however this address can be arbitrary.
-        *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
+    } else if ((vaddr & 0xFF000000) == 0x10000000 || (vaddr & 0xFF000000) == 0x1E000000) {
+        HW::Write<T>(vaddr, data);
 
-    // Scratchpad memory
-    } else if (addr > MEM_SCRATCHPAD_VADDR && addr <= (MEM_SCRATCHPAD_VADDR + MEM_SCRATCHPAD_SIZE)) {
-        *(T*)&g_scratchpad[addr & MEM_SCRATCHPAD_MASK] = data;
+    // FCRAM - GSP heap
+    } else if ((vaddr > HEAP_GSP_VADDR)  && (vaddr < HEAP_GSP_VADDR_END)) {
+        *(T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK] = data;
 
-    // Heap mapped by ControlMemory:
-    } else if ((addr & 0x3E000000) == 0x08000000) {
-        // TODO(ShizZy): Writes to this virtual address should be put in physical memory at FCRAM + GSP
-        // heap size... the following is writing to FCRAM + 0, which is actually supposed to be the 
-        // application's GSP heap
-        *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
+    // FCRAM - application heap
+    } else if ((vaddr > HEAP_VADDR)  && (vaddr < HEAP_VADDR_END)) {
+        *(T*)&g_heap[vaddr & HEAP_MASK] = data;
 
-    } else if ((addr & 0xFF000000) == 0x14000000) {
+    } else if ((vaddr & 0xFF000000) == 0x14000000) {
         _assert_msg_(MEMMAP, false, "umimplemented write to GSP heap");
-    } else if ((addr & 0xFFF00000) == 0x1EC00000) {
+    } else if ((vaddr & 0xFFF00000) == 0x1EC00000) {
         _assert_msg_(MEMMAP, false, "umimplemented write to IO registers");
-    } else if ((addr & 0xFF000000) == 0x1F000000) {
+    } else if ((vaddr & 0xFF000000) == 0x1F000000) {
         _assert_msg_(MEMMAP, false, "umimplemented write to VRAM");
-    } else if ((addr & 0xFFF00000) == 0x1FF00000) {
+    } else if ((vaddr & 0xFFF00000) == 0x1FF00000) {
         _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory");
-    } else if ((addr & 0xFFFF0000) == 0x1FF80000) {
+    } else if ((vaddr & 0xFFFF0000) == 0x1FF80000) {
         _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory");
-    } else if ((addr & 0xFFFFF000) == 0x1FF81000) {
+    } else if ((vaddr & 0xFFFFF000) == 0x1FF81000) {
         _assert_msg_(MEMMAP, false, "umimplemented write to shared page");
     
-    // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses. 
-    // Until we progress far enough along, we'll accept all physical address writes here. I think 
-    // that this is typically a corner-case from usermode software unless they are trying to do 
-    // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
-    } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
-        *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
-
     // Error out...
     } else {
-        _assert_msg_(MEMMAP, false, "unknown memory write");
-    }
-}
-
-bool IsValidAddress(const u32 addr) {
-    if ((addr & 0x3E000000) == 0x08000000) {
-        return true;
-    } else if ((addr & 0x3F800000) == 0x04000000) {
-        return true;
-    } else if ((addr & 0xBFFF0000) == 0x00010000) {
-        return true;
-    } else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + MEM_FCRAM_MASK) {
-        return true;
-    } else {
-        return false;
+        _assert_msg_(MEMMAP, false, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8,
+            data, vaddr);
     }
 }
 
 u8 *GetPointer(const u32 addr) {
-    // TODO(bunnei): Just a stub for now... ImplementMe!
-    if ((addr & 0x3E000000) == 0x08000000) {
-        return g_fcram + (addr & MEM_FCRAM_MASK);
+    const u32 vaddr = _AddressPhysicalToVirtual(addr);
 
-    // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses. 
-    // Until we progress far enough along, we'll accept all physical address reads here. I think 
-    // that this is typically a corner-case from usermode software unless they are trying to do 
-    // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
-    } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
-        return g_fcram + (addr & MEM_FCRAM_MASK);
+    // FCRAM - GSP heap
+    if ((vaddr >= HEAP_GSP_VADDR)  && (vaddr < HEAP_GSP_VADDR_END)) {
+        return g_heap_gsp + (vaddr & HEAP_GSP_MASK);
+
+    // FCRAM - application heap
+    } else if ((vaddr >= HEAP_VADDR)  && (vaddr < HEAP_VADDR_END)) {
+        return g_heap + (vaddr & HEAP_MASK);
 
-    //else if ((addr & 0x3F800000) == 0x04000000) {
-    //    return g_vram + (addr & MEM_VRAM_MASK);
-    //}
-    //else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + g_MemorySize) {
-    //    return m_pRAM + (addr & g_MemoryMask);
-    //}
     } else {
-        //ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
-        ERROR_LOG(MEMMAP, "Unknown GetPointer %08x", addr);
-        static bool reported = false;
-        //if (!reported) {
-        //    Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
-        //    reported = true;
-        //}
-        //if (!g_Config.bIgnoreBadMemAccess) {
-        //    Core_EnableStepping(true);
-        //    host->SetDebugMode(true);
-        //}
+        ERROR_LOG(MEMMAP, "Unknown GetPointer @ 0x%08x", vaddr);
         return 0;
     }
 }
 
+/**
+ * Maps a block of memory on the GSP heap
+ * @param size Size of block in bytes
+ * @param flags Memory allocation flags
+ */
+u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) {
+    HeapBlock block;
+    
+    block.base_address  = HEAP_GSP_VADDR;
+    block.size          = size;
+    block.operation     = operation;
+    block.permissions   = permissions;
+    
+    if (g_heap_gsp_map.size() > 0) {
+        const HeapBlock last_block = g_heap_gsp_map.rbegin()->second;
+        block.address = last_block.address + last_block.size;
+    }
+    g_heap_gsp_map[block.GetVirtualAddress()] = block;
+
+    return block.GetVirtualAddress();
+}
+
 u8 Read8(const u32 addr) {
     u8 _var = 0;
     _Read<u8>(_var, addr);
diff --git a/src/core/system.cpp b/src/core/system.cpp
index edb07fef57..c77092327b 100644
--- a/src/core/system.cpp
+++ b/src/core/system.cpp
@@ -7,6 +7,7 @@
 #include "core/mem_map.h"
 #include "core/system.h"
 #include "core/hw/hw.h"
+#include "core/hle/hle.h"
 
 #include "video_core/video_core.h"
 
@@ -19,15 +20,16 @@ void UpdateState(State state) {
 }
 
 void Init(EmuWindow* emu_window) {
-	Core::Init();
-	Memory::Init();
+    Core::Init();
+    Memory::Init();
     HW::Init();
-	CoreTiming::Init();
+    HLE::Init();
+    CoreTiming::Init();
     VideoCore::Init(emu_window);
 }
 
 void RunLoopFor(int cycles) {
-	RunLoopUntil(CoreTiming::GetTicks() + cycles);
+    RunLoopUntil(CoreTiming::GetTicks() + cycles);
 }
 
 void RunLoopUntil(u64 global_cycles) {
@@ -35,9 +37,12 @@ void RunLoopUntil(u64 global_cycles) {
 
 void Shutdown() {
     Core::Shutdown();
+    Memory::Shutdown();
     HW::Shutdown();
+    HLE::Shutdown();
+    CoreTiming::Shutdown();
     VideoCore::Shutdown();
-	g_ctr_file_system.Shutdown();
+    g_ctr_file_system.Shutdown();
 }
 
 } // namespace
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 97f84c248f..35804aee1d 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -2,6 +2,8 @@
 // Licensed under GPLv2
 // Refer to the license.txt file included.
 
+#include "core/hw/lcd.h"
+
 #include "video_core/video_core.h"
 #include "video_core/renderer_opengl/renderer_opengl.h"
 
@@ -75,8 +77,8 @@ void RendererOpenGL::FlipFramebuffer(u32 addr, u8* out) {
  */
 void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {  
 
-    FlipFramebuffer(0x20282160, m_xfb_top_flipped);
-    FlipFramebuffer(0x202118E0, m_xfb_bottom_flipped);
+    FlipFramebuffer(LCD::TOP_RIGHT_FRAME1,  m_xfb_top_flipped);
+    FlipFramebuffer(LCD::SUB_FRAME1,        m_xfb_bottom_flipped);
 
     // Blit the top framebuffer
     // ------------------------
@@ -84,7 +86,7 @@ void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {
     // Update textures with contents of XFB in RAM - top
     glBindTexture(GL_TEXTURE_2D, m_xfb_texture_top);
     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
-        GL_RGB, GL_UNSIGNED_BYTE, m_xfb_top_flipped);
+        GL_BGR, GL_UNSIGNED_BYTE, m_xfb_top_flipped);
     glBindTexture(GL_TEXTURE_2D, 0);
 
     // Render target is destination framebuffer
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index e227b6795f..f2e17f9f93 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -38,12 +38,13 @@ void Init(EmuWindow* emu_window) {
 
     g_current_frame = 0;
 
-    NOTICE_LOG(VIDEO, "initialized ok");
+    NOTICE_LOG(VIDEO, "initialized OK");
 }
 
 /// Shutdown the video core
 void Shutdown() {
     delete g_renderer;
+    NOTICE_LOG(VIDEO, "shutdown OK");
 }
 
 } // namespace