diff --git a/Ryujinx/OsHle/Ipc/IpcHandler.cs b/Ryujinx/OsHle/Ipc/IpcHandler.cs
index c8b26dba67..ff90d873b3 100644
--- a/Ryujinx/OsHle/Ipc/IpcHandler.cs
+++ b/Ryujinx/OsHle/Ipc/IpcHandler.cs
@@ -10,8 +10,6 @@ namespace Ryujinx.OsHle.Ipc
 {
     static class IpcHandler
     {
-        private delegate long ServiceProcessRequest(ServiceCtx Context);
-
         private static Dictionary<(string, int), ServiceProcessRequest> ServiceCmds =
                    new Dictionary<(string, int), ServiceProcessRequest>()
         {
@@ -71,122 +69,10 @@ namespace Ryujinx.OsHle.Ipc
             { ( "vi:m",        2), Service.ViGetDisplayService                      },
         };
 
-        private static Dictionary<(Type, int), ServiceProcessRequest> ObjectCmds =
-                   new Dictionary<(Type, int), ServiceProcessRequest>()
-        {
-            //IManagerForApplication
-            { (typeof(AccIManagerForApplication), 0), AccIManagerForApplication.CheckAvailability },
-            { (typeof(AccIManagerForApplication), 1), AccIManagerForApplication.GetAccountId      },
-
-            //IProfile
-            { (typeof(AccIProfile), 1), AccIProfile.GetBase },
-
-            //IApplicationFunctions
-            { (typeof(AmIApplicationFunctions),  1), AmIApplicationFunctions.PopLaunchParameter },
-            { (typeof(AmIApplicationFunctions), 20), AmIApplicationFunctions.EnsureSaveData     },
-            { (typeof(AmIApplicationFunctions), 21), AmIApplicationFunctions.GetDesiredLanguage },
-            { (typeof(AmIApplicationFunctions), 40), AmIApplicationFunctions.NotifyRunning      },
-
-            //IApplicationProxy
-            { (typeof(AmIApplicationProxy),    0), AmIApplicationProxy.GetCommonStateGetter    },
-            { (typeof(AmIApplicationProxy),    1), AmIApplicationProxy.GetSelfController       },
-            { (typeof(AmIApplicationProxy),    2), AmIApplicationProxy.GetWindowController     },
-            { (typeof(AmIApplicationProxy),    3), AmIApplicationProxy.GetAudioController      },
-            { (typeof(AmIApplicationProxy),    4), AmIApplicationProxy.GetDisplayController    },
-            { (typeof(AmIApplicationProxy),   11), AmIApplicationProxy.GetLibraryAppletCreator },
-            { (typeof(AmIApplicationProxy),   20), AmIApplicationProxy.GetApplicationFunctions },
-            { (typeof(AmIApplicationProxy), 1000), AmIApplicationProxy.GetDebugFunctions       },
-
-            //ICommonStateGetter
-            { (typeof(AmICommonStateGetter), 0), AmICommonStateGetter.GetEventHandle       },
-            { (typeof(AmICommonStateGetter), 1), AmICommonStateGetter.ReceiveMessage       },
-            { (typeof(AmICommonStateGetter), 5), AmICommonStateGetter.GetOperationMode     },
-            { (typeof(AmICommonStateGetter), 6), AmICommonStateGetter.GetPerformanceMode   },
-            { (typeof(AmICommonStateGetter), 9), AmICommonStateGetter.GetCurrentFocusState },
-
-            //ISelfController
-            { (typeof(AmISelfController), 11), AmISelfController.SetOperationModeChangedNotification   },
-            { (typeof(AmISelfController), 12), AmISelfController.SetPerformanceModeChangedNotification },
-            { (typeof(AmISelfController), 13), AmISelfController.SetFocusHandlingMode                  },
-            { (typeof(AmISelfController), 16), AmISelfController.SetOutOfFocusSuspendingEnabled        },
-
-            //IStorage
-            { (typeof(AmIStorage), 0), AmIStorage.Open },
-
-            //IStorageAccessor
-            { (typeof(AmIStorageAccessor),  0), AmIStorageAccessor.GetSize },
-            { (typeof(AmIStorageAccessor), 11), AmIStorageAccessor.Read    },
-
-            //IWindowController
-            { (typeof(AmIWindowController),  1), AmIWindowController.GetAppletResourceUserId },
-            { (typeof(AmIWindowController), 10), AmIWindowController.AcquireForegroundRights },
-
-            //ISession
-            { (typeof(ApmISession), 0), ApmISession.SetPerformanceConfiguration },
-
-            //IAudioRenderer
-            { (typeof(AudIAudioRenderer), 4), AudIAudioRenderer.RequestUpdateAudioRenderer },
-            { (typeof(AudIAudioRenderer), 5), AudIAudioRenderer.StartAudioRenderer         },
-            { (typeof(AudIAudioRenderer), 6), AudIAudioRenderer.StopAudioRenderer          },
-            { (typeof(AudIAudioRenderer), 7), AudIAudioRenderer.QuerySystemEvent           },
-
-            //IAudioOut
-            { (typeof(AudIAudioOut), 0), AudIAudioOut.GetAudioOutState             },
-            { (typeof(AudIAudioOut), 1), AudIAudioOut.StartAudioOut                },
-            { (typeof(AudIAudioOut), 2), AudIAudioOut.StopAudioOut                 },
-            { (typeof(AudIAudioOut), 3), AudIAudioOut.AppendAudioOutBuffer         },
-            { (typeof(AudIAudioOut), 4), AudIAudioOut.RegisterBufferEvent          },
-            { (typeof(AudIAudioOut), 5), AudIAudioOut.GetReleasedAudioOutBuffer    },
-            { (typeof(AudIAudioOut), 6), AudIAudioOut.ContainsAudioOutBuffer       },
-            { (typeof(AudIAudioOut), 7), AudIAudioOut.AppendAudioOutBuffer_ex      },
-            { (typeof(AudIAudioOut), 8), AudIAudioOut.GetReleasedAudioOutBuffer_ex },
-
-            //IFile
-            { (typeof(FspSrvIFile), 0), FspSrvIFile.Read  },
-            { (typeof(FspSrvIFile), 1), FspSrvIFile.Write },
-
-            //IFileSystem
-            { (typeof(FspSrvIFileSystem),  7), FspSrvIFileSystem.GetEntryType },
-            { (typeof(FspSrvIFileSystem),  8), FspSrvIFileSystem.OpenFile     },
-            { (typeof(FspSrvIFileSystem), 10), FspSrvIFileSystem.Commit       },
-
-            //IStorage
-            { (typeof(FspSrvIStorage), 0), FspSrvIStorage.Read },
-
-            //IAppletResource
-            { (typeof(HidIAppletResource), 0), HidIAppletResource.GetSharedMemoryHandle },
-
-            //ISystemClock
-            { (typeof(TimeISystemClock), 0), TimeISystemClock.GetCurrentTime },
-
-            //IApplicationDisplayService
-            { (typeof(ViIApplicationDisplayService),  100), ViIApplicationDisplayService.GetRelayService                      },
-            { (typeof(ViIApplicationDisplayService),  101), ViIApplicationDisplayService.GetSystemDisplayService              },
-            { (typeof(ViIApplicationDisplayService),  102), ViIApplicationDisplayService.GetManagerDisplayService             },
-            { (typeof(ViIApplicationDisplayService),  103), ViIApplicationDisplayService.GetIndirectDisplayTransactionService },
-            { (typeof(ViIApplicationDisplayService), 1010), ViIApplicationDisplayService.OpenDisplay                          },
-            { (typeof(ViIApplicationDisplayService), 2020), ViIApplicationDisplayService.OpenLayer                            },
-            { (typeof(ViIApplicationDisplayService), 2030), ViIApplicationDisplayService.CreateStrayLayer                     },
-            { (typeof(ViIApplicationDisplayService), 2101), ViIApplicationDisplayService.SetLayerScalingMode                  },
-            { (typeof(ViIApplicationDisplayService), 5202), ViIApplicationDisplayService.GetDisplayVSyncEvent                 },
-
-            //IHOSBinderDriver
-            { (typeof(ViIHOSBinderDriver), 0), ViIHOSBinderDriver.TransactParcel  },
-            { (typeof(ViIHOSBinderDriver), 1), ViIHOSBinderDriver.AdjustRefcount  },
-            { (typeof(ViIHOSBinderDriver), 2), ViIHOSBinderDriver.GetNativeHandle },
-
-            //IManagerDisplayService
-            { (typeof(ViIManagerDisplayService), 2010), ViIManagerDisplayService.CreateManagedLayer },
-            { (typeof(ViIManagerDisplayService), 6000), ViIManagerDisplayService.AddToLayerStack    },
-
-            //ISystemDisplayService
-            { (typeof(ViISystemDisplayService), 2205), ViISystemDisplayService.SetLayerZ },
-        };
-
         private const long SfciMagic = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'I' << 24;
         private const long SfcoMagic = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'O' << 24;
 
-        public static void ProcessRequest(
+        public static void IpcCall(
             Switch     Ns,
             AMemory    Memory,
             HSession   Session,
@@ -221,15 +107,15 @@ namespace Ryujinx.OsHle.Ipc
 
                             if (Obj is HDomain)
                             {
-                                DbgServiceName = $"{ServiceName} {CmdId}";
-
                                 ServiceCmds.TryGetValue((ServiceName, CmdId), out ProcReq);
+
+                                DbgServiceName = $"{ServiceName} {ProcReq?.Method.Name ?? CmdId.ToString()}";
                             }
                             else if (Obj != null)
                             {
-                                DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {CmdId}";
+                                ((IIpcInterface)Obj).Commands.TryGetValue(CmdId, out ProcReq);
 
-                                ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
+                                DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {ProcReq?.Method.Name ?? CmdId.ToString()}";
                             }
                         }
                         else if (Request.DomCmd == IpcDomCmd.DeleteObj)
@@ -250,15 +136,15 @@ namespace Ryujinx.OsHle.Ipc
                         {
                             object Obj = ((HSessionObj)Session).Obj;
 
-                            DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {CmdId}";
+                            ((IIpcInterface)Obj).Commands.TryGetValue(CmdId, out ProcReq);
 
-                            ObjectCmds.TryGetValue((Obj.GetType(), CmdId), out ProcReq);
+                            DbgServiceName = $"{ServiceName} {Obj.GetType().Name} {ProcReq?.Method.Name ?? CmdId.ToString()}";
                         }
                         else
                         {
-                            DbgServiceName = $"{ServiceName} {CmdId}";
-
                             ServiceCmds.TryGetValue((ServiceName, CmdId), out ProcReq);
+
+                            DbgServiceName = $"{ServiceName} {ProcReq?.Method.Name ?? CmdId.ToString()}";
                         }
                     }
 
diff --git a/Ryujinx/OsHle/Ipc/ServiceProcessRequest.cs b/Ryujinx/OsHle/Ipc/ServiceProcessRequest.cs
new file mode 100644
index 0000000000..838a6aea85
--- /dev/null
+++ b/Ryujinx/OsHle/Ipc/ServiceProcessRequest.cs
@@ -0,0 +1,4 @@
+namespace Ryujinx.OsHle.Ipc
+{
+    delegate long ServiceProcessRequest(ServiceCtx Context);
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Acc/IManagerForApplication.cs b/Ryujinx/OsHle/Objects/Acc/IManagerForApplication.cs
new file mode 100644
index 0000000000..404ee7da64
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Acc/IManagerForApplication.cs
@@ -0,0 +1,33 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Acc
+{
+    class IManagerForApplication : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IManagerForApplication()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, CheckAvailability },
+                { 1, GetAccountId      }
+            };
+        }
+
+        public long CheckAvailability(ServiceCtx Context)
+        {           
+            return 0;
+        }
+
+        public long GetAccountId(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(0xcafeL);
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Acc/IProfile.cs b/Ryujinx/OsHle/Objects/Acc/IProfile.cs
new file mode 100644
index 0000000000..c84c7ae286
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Acc/IProfile.cs
@@ -0,0 +1,33 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Acc
+{
+    class IProfile : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IProfile()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 1, GetBase }
+            };
+        }
+
+        public long GetBase(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(0L);
+            Context.ResponseData.Write(0L);
+            Context.ResponseData.Write(0L);
+            Context.ResponseData.Write(0L);
+            Context.ResponseData.Write(0L);
+            Context.ResponseData.Write(0L);
+            Context.ResponseData.Write(0L);
+            
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AccIManagerForApplication.cs b/Ryujinx/OsHle/Objects/AccIManagerForApplication.cs
deleted file mode 100644
index 8e2a002ba0..0000000000
--- a/Ryujinx/OsHle/Objects/AccIManagerForApplication.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AccIManagerForApplication
-    {
-        public static long CheckAvailability(ServiceCtx Context)
-        {           
-            return 0;
-        }
-
-        public static long GetAccountId(ServiceCtx Context)
-        {
-            Context.ResponseData.Write(0xcafeL);
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AccIProfile.cs b/Ryujinx/OsHle/Objects/AccIProfile.cs
deleted file mode 100644
index 2dbe189d71..0000000000
--- a/Ryujinx/OsHle/Objects/AccIProfile.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AccIProfile
-    {
-        public static long GetBase(ServiceCtx Context)
-        {
-            Context.ResponseData.Write(0L);
-            Context.ResponseData.Write(0L);
-            Context.ResponseData.Write(0L);
-            Context.ResponseData.Write(0L);
-            Context.ResponseData.Write(0L);
-            Context.ResponseData.Write(0L);
-            Context.ResponseData.Write(0L);
-            
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIApplicationFunctions.cs b/Ryujinx/OsHle/Objects/Am/IApplicationFunctions.cs
similarity index 59%
rename from Ryujinx/OsHle/Objects/AmIApplicationFunctions.cs
rename to Ryujinx/OsHle/Objects/Am/IApplicationFunctions.cs
index b5712484e9..138d9084f9 100644
--- a/Ryujinx/OsHle/Objects/AmIApplicationFunctions.cs
+++ b/Ryujinx/OsHle/Objects/Am/IApplicationFunctions.cs
@@ -1,22 +1,39 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
 using System.IO;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.Am
 {
-    class AmIApplicationFunctions
+    class IApplicationFunctions : IIpcInterface
     {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IApplicationFunctions()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                {  1, PopLaunchParameter },
+                { 20, EnsureSaveData     },
+                { 21, GetDesiredLanguage },
+                { 40, NotifyRunning      }
+            };
+        }
+
         private const uint LaunchParamsMagic = 0xc79497ca;
 
-        public static long PopLaunchParameter(ServiceCtx Context)
+        public long PopLaunchParameter(ServiceCtx Context)
         {
             //Only the first 0x18 bytes of the Data seems to be actually used.
-            MakeObject(Context, new AmIStorage(MakeLaunchParams()));
+            MakeObject(Context, new IStorage(MakeLaunchParams()));
 
             return 0;
         }
 
-        public static long EnsureSaveData(ServiceCtx Context)
+        public long EnsureSaveData(ServiceCtx Context)
         {
             long UIdLow  = Context.RequestData.ReadInt64();
             long UIdHigh = Context.RequestData.ReadInt64();
@@ -26,7 +43,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long GetDesiredLanguage(ServiceCtx Context)
+        public long GetDesiredLanguage(ServiceCtx Context)
         {
             //This is an enumerator where each number is a differnet language.
             //0 is Japanese and 1 is English, need to figure out the other codes.
@@ -35,14 +52,14 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long NotifyRunning(ServiceCtx Context)
+        public long NotifyRunning(ServiceCtx Context)
         {
             Context.ResponseData.Write(1);
 
             return 0;
         }
 
-        private static byte[] MakeLaunchParams()
+        private byte[] MakeLaunchParams()
         {
             //Size needs to be at least 0x88 bytes otherwise application errors.
             using (MemoryStream MS = new MemoryStream())
diff --git a/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs b/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs
new file mode 100644
index 0000000000..15940f6708
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs
@@ -0,0 +1,86 @@
+using Ryujinx.OsHle.Ipc;
+using Ryujinx.OsHle.Objects.Am;
+using System.Collections.Generic;
+
+using static Ryujinx.OsHle.Objects.ObjHelper;
+
+namespace Ryujinx.OsHle.Objects
+{
+    class IApplicationProxy : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IApplicationProxy()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                {    0, GetCommonStateGetter    },
+                {    1, GetSelfController       },
+                {    2, GetWindowController     },
+                {    3, GetAudioController      },
+                {    4, GetDisplayController    },
+                {   11, GetLibraryAppletCreator },
+                {   20, GetApplicationFunctions },
+                { 1000, GetDebugFunctions       }
+            };
+        }
+
+        public long GetCommonStateGetter(ServiceCtx Context)
+        {
+            MakeObject(Context, new ICommonStateGetter());
+
+            return 0;
+        }
+
+        public long GetSelfController(ServiceCtx Context)
+        {
+            MakeObject(Context, new ISelfController());
+
+            return 0;
+        }
+
+        public long GetWindowController(ServiceCtx Context)
+        {
+            MakeObject(Context, new IWindowController());
+
+            return 0;
+        }
+
+        public long GetAudioController(ServiceCtx Context)
+        {
+            MakeObject(Context, new IAudioController());
+
+            return 0;
+        }
+
+        public long GetDisplayController(ServiceCtx Context)
+        {
+            MakeObject(Context, new IDisplayController());
+
+            return 0;
+        }
+
+        public long GetLibraryAppletCreator(ServiceCtx Context)
+        {
+            MakeObject(Context, new ILibraryAppletCreator());
+
+            return 0;
+        }
+
+        public long GetApplicationFunctions(ServiceCtx Context)
+        {
+            MakeObject(Context, new IApplicationFunctions());
+
+            return 0;
+        }
+
+        public long GetDebugFunctions(ServiceCtx Context)
+        {
+            MakeObject(Context, new IDebugFunctions());
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/IAudioController.cs b/Ryujinx/OsHle/Objects/Am/IAudioController.cs
new file mode 100644
index 0000000000..0ca49f892c
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IAudioController.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class IAudioController : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IAudioController()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/ICommonStateGetter.cs b/Ryujinx/OsHle/Objects/Am/ICommonStateGetter.cs
new file mode 100644
index 0000000000..5a3af8e113
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/ICommonStateGetter.cs
@@ -0,0 +1,74 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class ICommonStateGetter : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ICommonStateGetter()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, GetEventHandle       },
+                { 1, ReceiveMessage       },
+                { 5, GetOperationMode     },
+                { 6, GetPerformanceMode   },
+                { 9, GetCurrentFocusState },
+            };
+        }
+
+        private enum FocusState
+        {
+            InFocus    = 1,
+            OutOfFocus = 2
+        }
+
+        private enum OperationMode
+        {
+            Handheld = 0,
+            Docked   = 1
+        }
+
+        public long GetEventHandle(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(0L);
+
+            return 0;
+        }
+
+        public long ReceiveMessage(ServiceCtx Context)
+        {
+            //Program expects 0xF at 0x17ae70 on puyo sdk,
+            //otherwise runs on a infinite loop until it reads said value.
+            //What it means is still unknown.
+            Context.ResponseData.Write(0xfL);
+
+            return 0; //0x680;
+        }
+
+        public long GetOperationMode(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((byte)OperationMode.Handheld);
+
+            return 0;
+        }
+
+        public long GetPerformanceMode(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((byte)0);
+
+            return 0;
+        }
+
+        public long GetCurrentFocusState(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((byte)FocusState.InFocus);
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/IDebugFunctions.cs b/Ryujinx/OsHle/Objects/Am/IDebugFunctions.cs
new file mode 100644
index 0000000000..dc57e8e6e8
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IDebugFunctions.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class IDebugFunctions : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IDebugFunctions()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/IDisplayController.cs b/Ryujinx/OsHle/Objects/Am/IDisplayController.cs
new file mode 100644
index 0000000000..8861208667
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IDisplayController.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class IDisplayController : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IDisplayController()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/ILibraryAppletCreator.cs b/Ryujinx/OsHle/Objects/Am/ILibraryAppletCreator.cs
new file mode 100644
index 0000000000..91fae3dd0f
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/ILibraryAppletCreator.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class ILibraryAppletCreator : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ILibraryAppletCreator()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/IParentalControlService.cs b/Ryujinx/OsHle/Objects/Am/IParentalControlService.cs
new file mode 100644
index 0000000000..c462ff07fc
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IParentalControlService.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class IParentalControlService : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IParentalControlService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/ISelfController.cs b/Ryujinx/OsHle/Objects/Am/ISelfController.cs
new file mode 100644
index 0000000000..c46396c559
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/ISelfController.cs
@@ -0,0 +1,53 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class ISelfController : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ISelfController()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 11, SetOperationModeChangedNotification   },
+                { 12, SetPerformanceModeChangedNotification },
+                { 13, SetFocusHandlingMode                  },
+                { 16, SetOutOfFocusSuspendingEnabled        }
+            };
+        }
+
+        public long SetOperationModeChangedNotification(ServiceCtx Context)
+        {
+            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
+
+            return 0;
+        }
+
+        public long SetPerformanceModeChangedNotification(ServiceCtx Context)
+        {
+            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
+
+            return 0;
+        }
+
+        public long SetFocusHandlingMode(ServiceCtx Context)
+        {
+            bool Flag1 = Context.RequestData.ReadByte() != 0 ? true : false;
+            bool Flag2 = Context.RequestData.ReadByte() != 0 ? true : false;
+            bool Flag3 = Context.RequestData.ReadByte() != 0 ? true : false;
+
+            return 0;
+        }
+
+        public long SetOutOfFocusSuspendingEnabled(ServiceCtx Context)
+        {
+            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Am/IStorage.cs b/Ryujinx/OsHle/Objects/Am/IStorage.cs
new file mode 100644
index 0000000000..53bb5cf1fb
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IStorage.cs
@@ -0,0 +1,35 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+using static Ryujinx.OsHle.Objects.ObjHelper;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class IStorage : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public byte[] Data { get; private set; }
+
+        public IStorage(byte[] Data)
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, Open }
+            };
+
+            this.Data = Data;
+        }
+
+        public long Open(ServiceCtx Context)
+        {
+            IStorage Storage = Context.GetObject<IStorage>();
+
+            MakeObject(Context, new IStorageAccessor(Storage));
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIStorageAccessor.cs b/Ryujinx/OsHle/Objects/Am/IStorageAccessor.cs
similarity index 53%
rename from Ryujinx/OsHle/Objects/AmIStorageAccessor.cs
rename to Ryujinx/OsHle/Objects/Am/IStorageAccessor.cs
index 62007ef817..fdd5474425 100644
--- a/Ryujinx/OsHle/Objects/AmIStorageAccessor.cs
+++ b/Ryujinx/OsHle/Objects/Am/IStorageAccessor.cs
@@ -1,31 +1,43 @@
 using ChocolArm64.Memory;
+using Ryujinx.OsHle.Ipc;
 using System;
+using System.Collections.Generic;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.Am
 {
-    class AmIStorageAccessor
+    class IStorageAccessor : IIpcInterface
     {
-        public AmIStorage Storage { get; private set; }
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
 
-        public AmIStorageAccessor(AmIStorage Storage)
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IStorage Storage { get; private set; }
+
+        public IStorageAccessor(IStorage Storage)
         {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                {  0, GetSize },
+                { 11, Read    }
+            };
+
             this.Storage = Storage;
         }
 
-        public static long GetSize(ServiceCtx Context)
+        public long GetSize(ServiceCtx Context)
         {
-            AmIStorageAccessor Accessor = Context.GetObject<AmIStorageAccessor>();
+            IStorageAccessor Accessor = Context.GetObject<IStorageAccessor>();
 
             Context.ResponseData.Write((long)Accessor.Storage.Data.Length);
 
             return 0;
         }
 
-        public static long Read(ServiceCtx Context)
+        public long Read(ServiceCtx Context)
         {
-            AmIStorageAccessor Accessor = Context.GetObject<AmIStorageAccessor>();
+            IStorageAccessor Accessor = Context.GetObject<IStorageAccessor>();
 
-            AmIStorage Storage = Accessor.Storage;
+            IStorage Storage = Accessor.Storage;
 
             long ReadPosition = Context.RequestData.ReadInt64();
 
diff --git a/Ryujinx/OsHle/Objects/Am/IWindowController.cs b/Ryujinx/OsHle/Objects/Am/IWindowController.cs
new file mode 100644
index 0000000000..1796644e3e
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Am/IWindowController.cs
@@ -0,0 +1,33 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Am
+{
+    class IWindowController : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IWindowController()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                {  1, GetAppletResourceUserId },
+                { 10, AcquireForegroundRights }
+            };
+        }
+
+        public long GetAppletResourceUserId(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(0L);
+
+            return 0;
+        }
+
+        public long AcquireForegroundRights(ServiceCtx Context)
+        {
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIApplicationProxy.cs b/Ryujinx/OsHle/Objects/AmIApplicationProxy.cs
deleted file mode 100644
index 2b0bc346d4..0000000000
--- a/Ryujinx/OsHle/Objects/AmIApplicationProxy.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using static Ryujinx.OsHle.Objects.ObjHelper;
-
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIApplicationProxy
-    {
-        public static long GetCommonStateGetter(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmICommonStateGetter());
-
-            return 0;
-        }
-
-        public static long GetSelfController(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmISelfController());
-
-            return 0;
-        }
-
-        public static long GetWindowController(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmIWindowController());
-
-            return 0;
-        }
-
-        public static long GetAudioController(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmIAudioController());
-
-            return 0;
-        }
-
-        public static long GetDisplayController(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmIDisplayController());
-
-            return 0;
-        }
-
-        public static long GetLibraryAppletCreator(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmILibraryAppletCreator());
-
-            return 0;
-        }
-
-        public static long GetApplicationFunctions(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmIApplicationFunctions());
-
-            return 0;
-        }
-
-        public static long GetDebugFunctions(ServiceCtx Context)
-        {
-            MakeObject(Context, new AmIDebugFunctions());
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIAudioController.cs b/Ryujinx/OsHle/Objects/AmIAudioController.cs
deleted file mode 100644
index 59d94bda49..0000000000
--- a/Ryujinx/OsHle/Objects/AmIAudioController.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIAudioController
-    {
-        
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmICommonStateGetter.cs b/Ryujinx/OsHle/Objects/AmICommonStateGetter.cs
deleted file mode 100644
index 32f065c81b..0000000000
--- a/Ryujinx/OsHle/Objects/AmICommonStateGetter.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmICommonStateGetter
-    {
-        private enum FocusState
-        {
-            InFocus    = 1,
-            OutOfFocus = 2
-        }
-
-        private enum OperationMode
-        {
-            Handheld = 0,
-            Docked   = 1
-        }
-
-        public static long GetEventHandle(ServiceCtx Context)
-        {
-            Context.ResponseData.Write(0L);
-
-            return 0;
-        }
-
-        public static long ReceiveMessage(ServiceCtx Context)
-        {
-            //Program expects 0xF at 0x17ae70 on puyo sdk,
-            //otherwise runs on a infinite loop until it reads said value.
-            //What it means is still unknown.
-            Context.ResponseData.Write(0xfL);
-
-            return 0; //0x680;
-        }
-
-        public static long GetOperationMode(ServiceCtx Context)
-        {
-            Context.ResponseData.Write((byte)OperationMode.Handheld);
-
-            return 0;
-        }
-
-        public static long GetPerformanceMode(ServiceCtx Context)
-        {
-            Context.ResponseData.Write((byte)0);
-
-            return 0;
-        }
-
-        public static long GetCurrentFocusState(ServiceCtx Context)
-        {
-            Context.ResponseData.Write((byte)FocusState.InFocus);
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIDebugFunctions.cs b/Ryujinx/OsHle/Objects/AmIDebugFunctions.cs
deleted file mode 100644
index 9794c43f40..0000000000
--- a/Ryujinx/OsHle/Objects/AmIDebugFunctions.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIDebugFunctions
-    {
-
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIDisplayController.cs b/Ryujinx/OsHle/Objects/AmIDisplayController.cs
deleted file mode 100644
index be36ca0ca1..0000000000
--- a/Ryujinx/OsHle/Objects/AmIDisplayController.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIDisplayController
-    {
-        
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmILibraryAppletCreator.cs b/Ryujinx/OsHle/Objects/AmILibraryAppletCreator.cs
deleted file mode 100644
index 585df9e99b..0000000000
--- a/Ryujinx/OsHle/Objects/AmILibraryAppletCreator.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmILibraryAppletCreator
-    {
-        
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIParentalControlService.cs b/Ryujinx/OsHle/Objects/AmIParentalControlService.cs
deleted file mode 100644
index 12c3c2a96d..0000000000
--- a/Ryujinx/OsHle/Objects/AmIParentalControlService.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIParentalControlService
-    {
-
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmISelfController.cs b/Ryujinx/OsHle/Objects/AmISelfController.cs
deleted file mode 100644
index 8affb92b6e..0000000000
--- a/Ryujinx/OsHle/Objects/AmISelfController.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmISelfController
-    {
-        public static long SetOperationModeChangedNotification(ServiceCtx Context)
-        {
-            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
-
-            return 0;
-        }
-
-        public static long SetPerformanceModeChangedNotification(ServiceCtx Context)
-        {
-            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
-
-            return 0;
-        }
-
-        public static long SetFocusHandlingMode(ServiceCtx Context)
-        {
-            bool Flag1 = Context.RequestData.ReadByte() != 0 ? true : false;
-            bool Flag2 = Context.RequestData.ReadByte() != 0 ? true : false;
-            bool Flag3 = Context.RequestData.ReadByte() != 0 ? true : false;
-
-            return 0;
-        }
-
-        public static long SetOutOfFocusSuspendingEnabled(ServiceCtx Context)
-        {
-            bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIStorage.cs b/Ryujinx/OsHle/Objects/AmIStorage.cs
deleted file mode 100644
index 7e608ac8cf..0000000000
--- a/Ryujinx/OsHle/Objects/AmIStorage.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using static Ryujinx.OsHle.Objects.ObjHelper;
-
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIStorage
-    {
-        public byte[] Data { get; private set; }
-
-        public AmIStorage(byte[] Data)
-        {
-            this.Data = Data;
-        }
-
-        public static long Open(ServiceCtx Context)
-        {
-            AmIStorage Storage = Context.GetObject<AmIStorage>();
-
-            MakeObject(Context, new AmIStorageAccessor(Storage));
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AmIWindowController.cs b/Ryujinx/OsHle/Objects/AmIWindowController.cs
deleted file mode 100644
index ea967ae84a..0000000000
--- a/Ryujinx/OsHle/Objects/AmIWindowController.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class AmIWindowController
-    {
-        public static long GetAppletResourceUserId(ServiceCtx Context)
-        {
-            Context.ResponseData.Write(0L);
-
-            return 0;
-        }
-
-        public static long AcquireForegroundRights(ServiceCtx Context)
-        {
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Apm/ISession.cs b/Ryujinx/OsHle/Objects/Apm/ISession.cs
new file mode 100644
index 0000000000..f3965b484d
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Apm/ISession.cs
@@ -0,0 +1,28 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Apm
+{
+    class ISession : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ISession()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, SetPerformanceConfiguration }
+            };
+        }
+
+        public long SetPerformanceConfiguration(ServiceCtx Context)
+        {
+            int PerfMode   = Context.RequestData.ReadInt32();
+            int PerfConfig = Context.RequestData.ReadInt32();
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/ApmISession.cs b/Ryujinx/OsHle/Objects/ApmISession.cs
deleted file mode 100644
index 2b2c035158..0000000000
--- a/Ryujinx/OsHle/Objects/ApmISession.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class ApmISession
-    {
-        public static long SetPerformanceConfiguration(ServiceCtx Context)
-        {
-            int PerfMode   = Context.RequestData.ReadInt32();
-            int PerfConfig = Context.RequestData.ReadInt32();
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/AudIAudioOut.cs b/Ryujinx/OsHle/Objects/Aud/IAudioOut.cs
similarity index 69%
rename from Ryujinx/OsHle/Objects/AudIAudioOut.cs
rename to Ryujinx/OsHle/Objects/Aud/IAudioOut.cs
index 029c058f2f..5feb67d89e 100644
--- a/Ryujinx/OsHle/Objects/AudIAudioOut.cs
+++ b/Ryujinx/OsHle/Objects/Aud/IAudioOut.cs
@@ -1,16 +1,36 @@
 using ChocolArm64.Memory;
-using OpenTK.Audio;
-using OpenTK.Audio.OpenAL;
 using Ryujinx.OsHle.Handles;
 using Ryujinx.OsHle.Ipc;
+using OpenTK.Audio;
+using OpenTK.Audio.OpenAL;
 using System;
 using System.Collections.Generic;
 using System.IO;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.Aud
 {
-    class AudIAudioOut
+    class IAudioOut : IIpcInterface
     {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IAudioOut()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, GetAudioOutState             },
+                { 1, StartAudioOut                },
+                { 2, StopAudioOut                 },
+                { 3, AppendAudioOutBuffer         },
+                { 4, RegisterBufferEvent          },
+                { 5, GetReleasedAudioOutBuffer    },
+                { 6, ContainsAudioOutBuffer       },
+                { 7, AppendAudioOutBuffer_ex      },
+                { 8, GetReleasedAudioOutBuffer_ex }
+            };
+        }
+
         enum AudioOutState
         {
             Started,
@@ -18,24 +38,24 @@ namespace Ryujinx.OsHle.Objects
         };
 
         //IAudioOut
-        private static AudioOutState State = AudioOutState.Stopped;
-        private static Queue<long> KeysQueue = new Queue<long>();
+        private AudioOutState State = AudioOutState.Stopped;
+        private Queue<long> KeysQueue = new Queue<long>();
 
         //OpenAL
-        private static bool OpenALInstalled = true;
-        private static AudioContext AudioCtx;
-        private static int Source;
-        private static int Buffer;
+        private bool OpenALInstalled = true;
+        private AudioContext AudioCtx;
+        private int Source;
+        private int Buffer;
 
         //Return State of IAudioOut
-        public static long GetAudioOutState(ServiceCtx Context)
+        public long GetAudioOutState(ServiceCtx Context)
         {
             Context.ResponseData.Write((int)State);
 
             return 0;
         }
 
-        public static long StartAudioOut(ServiceCtx Context)
+        public long StartAudioOut(ServiceCtx Context)
         {
             if (State == AudioOutState.Stopped)
             {
@@ -57,7 +77,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long StopAudioOut(ServiceCtx Context)
+        public long StopAudioOut(ServiceCtx Context)
         {
             if (State == AudioOutState.Started)
             {
@@ -75,7 +95,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long AppendAudioOutBuffer(ServiceCtx Context)
+        public long AppendAudioOutBuffer(ServiceCtx Context)
         {
             long BufferId = Context.RequestData.ReadInt64();
 
@@ -109,7 +129,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long RegisterBufferEvent(ServiceCtx Context)
+        public long RegisterBufferEvent(ServiceCtx Context)
         {
             int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
 
@@ -118,7 +138,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long GetReleasedAudioOutBuffer(ServiceCtx Context)
+        public long GetReleasedAudioOutBuffer(ServiceCtx Context)
         {
             long TempKey = 0;
 
@@ -141,17 +161,17 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long ContainsAudioOutBuffer(ServiceCtx Context)
+        public long ContainsAudioOutBuffer(ServiceCtx Context)
         {
             return 0;
         }
 
-        public static long AppendAudioOutBuffer_ex(ServiceCtx Context)
+        public long AppendAudioOutBuffer_ex(ServiceCtx Context)
         {
             return 0;
         }
 
-        public static long GetReleasedAudioOutBuffer_ex(ServiceCtx Context)
+        public long GetReleasedAudioOutBuffer_ex(ServiceCtx Context)
         {
             return 0;
         }
diff --git a/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs b/Ryujinx/OsHle/Objects/Aud/IAudioRenderer.cs
similarity index 58%
rename from Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
rename to Ryujinx/OsHle/Objects/Aud/IAudioRenderer.cs
index 35a5b82da2..a953d82a0e 100644
--- a/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
+++ b/Ryujinx/OsHle/Objects/Aud/IAudioRenderer.cs
@@ -1,13 +1,29 @@
 using Ryujinx.OsHle.Handles;
 using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.Aud
 {
-    class AudIAudioRenderer
+    class IAudioRenderer : IIpcInterface
     {
-        public static long RequestUpdateAudioRenderer(ServiceCtx Context)
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IAudioRenderer()
         {
-            //buffer < unknown, 5, 0 >) -> (buffer < unknown, 6, 0 >, buffer < unknown, 6, 0 >
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 4, RequestUpdateAudioRenderer },
+                { 5, StartAudioRenderer         },
+                { 6, StopAudioRenderer          },
+                { 7, QuerySystemEvent           }
+            };
+        }
+
+        public long RequestUpdateAudioRenderer(ServiceCtx Context)
+        {
+            //(buffer<unknown, 5, 0>) -> (buffer<unknown, 6, 0>, buffer<unknown, 6, 0>)
 
             long Position = Context.Request.ReceiveBuff[0].Position;
 
@@ -28,17 +44,17 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long StartAudioRenderer(ServiceCtx Context)
+        public long StartAudioRenderer(ServiceCtx Context)
         {
             return 0;
         }
 
-        public static long StopAudioRenderer(ServiceCtx Context)
+        public long StopAudioRenderer(ServiceCtx Context)
         {
             return 0;
         }
 
-        public static long QuerySystemEvent(ServiceCtx Context)
+        public long QuerySystemEvent(ServiceCtx Context)
         {
             int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
 
diff --git a/Ryujinx/OsHle/Objects/Friend/IFriendService.cs b/Ryujinx/OsHle/Objects/Friend/IFriendService.cs
new file mode 100644
index 0000000000..41084f8dab
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Friend/IFriendService.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Friend
+{
+    class IFriendService : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IFriendService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/FriendIFriendService.cs b/Ryujinx/OsHle/Objects/FriendIFriendService.cs
deleted file mode 100644
index 9a39380a5a..0000000000
--- a/Ryujinx/OsHle/Objects/FriendIFriendService.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class FriendIFriendService
-    {
-        
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/FspSrvIFile.cs b/Ryujinx/OsHle/Objects/FspSrv/IFile.cs
similarity index 66%
rename from Ryujinx/OsHle/Objects/FspSrvIFile.cs
rename to Ryujinx/OsHle/Objects/FspSrv/IFile.cs
index 4b9f8c37b2..1c6cc2e29e 100644
--- a/Ryujinx/OsHle/Objects/FspSrvIFile.cs
+++ b/Ryujinx/OsHle/Objects/FspSrv/IFile.cs
@@ -1,23 +1,32 @@
 using ChocolArm64.Memory;
+using Ryujinx.OsHle.Ipc;
 using System;
-
+using System.Collections.Generic;
 using System.IO;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.FspSrv
 {
-    class FspSrvIFile : IDisposable
+    class IFile : IIpcInterface, IDisposable
     {
-        public Stream BaseStream { get; private set; }
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
 
-        public FspSrvIFile(Stream BaseStream)
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        private Stream BaseStream;
+
+        public IFile(Stream BaseStream)
         {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, Read  },
+                { 1, Write }
+            };
+
             this.BaseStream = BaseStream;
         }
 
-        public static long Read(ServiceCtx Context)
+        public long Read(ServiceCtx Context)
         {
-            FspSrvIFile File = Context.GetObject<FspSrvIFile>();
-
             long Position = Context.Request.ReceiveBuff[0].Position;
 
             long Zero   = Context.RequestData.ReadInt64();
@@ -26,7 +35,7 @@ namespace Ryujinx.OsHle.Objects
 
             byte[] Data = new byte[Size];
 
-            int ReadSize = File.BaseStream.Read(Data, 0, (int)Size);
+            int ReadSize = BaseStream.Read(Data, 0, (int)Size);
 
             AMemoryHelper.WriteBytes(Context.Memory, Position, Data);
 
@@ -38,10 +47,8 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long Write(ServiceCtx Context)
+        public long Write(ServiceCtx Context)
         {
-            FspSrvIFile File = Context.GetObject<FspSrvIFile>();
-
             long Position = Context.Request.SendBuff[0].Position;
 
             long Zero   = Context.RequestData.ReadInt64();
@@ -50,8 +57,8 @@ namespace Ryujinx.OsHle.Objects
 
             byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, (int)Size);
 
-            File.BaseStream.Seek(Offset, SeekOrigin.Begin);
-            File.BaseStream.Write(Data, 0, (int)Size);
+            BaseStream.Seek(Offset, SeekOrigin.Begin);
+            BaseStream.Write(Data, 0, (int)Size);
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Objects/FspSrvIFileSystem.cs b/Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs
similarity index 53%
rename from Ryujinx/OsHle/Objects/FspSrvIFileSystem.cs
rename to Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs
index fed1c55acc..bf501594f7 100644
--- a/Ryujinx/OsHle/Objects/FspSrvIFileSystem.cs
+++ b/Ryujinx/OsHle/Objects/FspSrv/IFileSystem.cs
@@ -1,28 +1,39 @@
 using ChocolArm64.Memory;
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
 using System.IO;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.FspSrv
 {
-    class FspSrvIFileSystem
+    class IFileSystem : IIpcInterface
     {
-        public string FilePath { get; private set; }
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
 
-        public FspSrvIFileSystem(string Path)
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        private string Path;
+
+        public IFileSystem(string Path)
         {
-            this.FilePath = Path;
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                {  7, GetEntryType },
+                {  8, OpenFile     },
+                { 10, Commit       }
+            };
+
+            this.Path = Path;
         }
 
-        public static long GetEntryType(ServiceCtx Context)
+        public long GetEntryType(ServiceCtx Context)
         {
-            FspSrvIFileSystem FileSystem = Context.GetObject<FspSrvIFileSystem>();
-
             long Position = Context.Request.PtrBuff[0].Position;
 
             string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position);
 
-            string FileName = Context.Ns.VFs.GetFullPath(FileSystem.FilePath, Name);
+            string FileName = Context.Ns.VFs.GetFullPath(Path, Name);
 
             if (FileName == null)
             {
@@ -37,17 +48,15 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long OpenFile(ServiceCtx Context)
+        public long OpenFile(ServiceCtx Context)
         {
-            FspSrvIFileSystem FileSystem = Context.GetObject<FspSrvIFileSystem>();
-
             long Position = Context.Request.PtrBuff[0].Position;
 
             int FilterFlags = Context.RequestData.ReadInt32();
 
             string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position);
 
-            string FileName = Context.Ns.VFs.GetFullPath(FileSystem.FilePath, Name);
+            string FileName = Context.Ns.VFs.GetFullPath(Path, Name);
 
             if (FileName == null)
             {
@@ -57,12 +66,12 @@ namespace Ryujinx.OsHle.Objects
 
             FileStream Stream = new FileStream(FileName, FileMode.OpenOrCreate);
 
-            MakeObject(Context, new FspSrvIFile(Stream));
+            MakeObject(Context, new IFile(Stream));
 
             return 0;
         }
 
-        public static long Commit(ServiceCtx Context)
+        public long Commit(ServiceCtx Context)
         {
             return 0;
         }
diff --git a/Ryujinx/OsHle/Objects/FspSrvIStorage.cs b/Ryujinx/OsHle/Objects/FspSrv/IStorage.cs
similarity index 67%
rename from Ryujinx/OsHle/Objects/FspSrvIStorage.cs
rename to Ryujinx/OsHle/Objects/FspSrv/IStorage.cs
index 76ad8917ae..2068a2cba0 100644
--- a/Ryujinx/OsHle/Objects/FspSrvIStorage.cs
+++ b/Ryujinx/OsHle/Objects/FspSrv/IStorage.cs
@@ -1,21 +1,31 @@
 using ChocolArm64.Memory;
 using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
 using System.IO;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.FspSrv
 {
-    class FspSrvIStorage
+    class IStorage : IIpcInterface
     {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
         public Stream BaseStream { get; private set; }
 
-        public FspSrvIStorage(Stream BaseStream)
+        public IStorage(Stream BaseStream)
         {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, Read }
+            };
+
             this.BaseStream = BaseStream;
         }
 
         public static long Read(ServiceCtx Context)
         {
-            FspSrvIStorage Storage = Context.GetObject<FspSrvIStorage>();
+            IStorage Storage = Context.GetObject<IStorage>();
 
             long Offset = Context.RequestData.ReadInt64();
             long Size   = Context.RequestData.ReadInt64();
diff --git a/Ryujinx/OsHle/Objects/Hid/IAppletResource.cs b/Ryujinx/OsHle/Objects/Hid/IAppletResource.cs
new file mode 100644
index 0000000000..ac7ccf5649
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Hid/IAppletResource.cs
@@ -0,0 +1,32 @@
+using Ryujinx.OsHle.Handles;
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Hid
+{
+    class IAppletResource : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public HSharedMem Handle;
+
+        public IAppletResource(HSharedMem Handle)
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, GetSharedMemoryHandle }
+            };
+
+            this.Handle = Handle;
+        }
+
+        public static long GetSharedMemoryHandle(ServiceCtx Context)
+        {
+            Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Context.Ns.Os.HidHandle);
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/HidIAppletResource.cs b/Ryujinx/OsHle/Objects/HidIAppletResource.cs
deleted file mode 100644
index 73b948df7a..0000000000
--- a/Ryujinx/OsHle/Objects/HidIAppletResource.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Ryujinx.OsHle.Handles;
-using Ryujinx.OsHle.Ipc;
-
-namespace Ryujinx.OsHle.Objects
-{
-    class HidIAppletResource
-    {
-        public HSharedMem Handle;
-
-        public HidIAppletResource(HSharedMem Handle)
-        {
-            this.Handle = Handle;
-        }
-
-        public static long GetSharedMemoryHandle(ServiceCtx Context)
-        {
-            Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Context.Ns.Os.HidHandle);
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/IIpcInterface.cs b/Ryujinx/OsHle/Objects/IIpcInterface.cs
new file mode 100644
index 0000000000..af0594cc16
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/IIpcInterface.cs
@@ -0,0 +1,10 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects
+{
+    interface IIpcInterface
+    {
+        IReadOnlyDictionary<int, ServiceProcessRequest> Commands { get; } 
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Time/ISteadyClock.cs b/Ryujinx/OsHle/Objects/Time/ISteadyClock.cs
new file mode 100644
index 0000000000..a5139bab00
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Time/ISteadyClock.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Time
+{
+    class ISteadyClock : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ISteadyClock()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Time/ISystemClock.cs b/Ryujinx/OsHle/Objects/Time/ISystemClock.cs
new file mode 100644
index 0000000000..2c5b898b7d
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Time/ISystemClock.cs
@@ -0,0 +1,30 @@
+using Ryujinx.OsHle.Ipc;
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Time
+{
+    class ISystemClock : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+        public ISystemClock()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, GetCurrentTime }
+            };
+        }
+
+        public long GetCurrentTime(ServiceCtx Context)
+        {
+            Context.ResponseData.Write((long)(DateTime.Now - Epoch).TotalSeconds);
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Time/ITimeZoneService.cs b/Ryujinx/OsHle/Objects/Time/ITimeZoneService.cs
new file mode 100644
index 0000000000..29e7ec9276
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Time/ITimeZoneService.cs
@@ -0,0 +1,20 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Time
+{
+    class ITimeZoneService : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ITimeZoneService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/TimeISteadyClock.cs b/Ryujinx/OsHle/Objects/TimeISteadyClock.cs
deleted file mode 100644
index ead8c41a18..0000000000
--- a/Ryujinx/OsHle/Objects/TimeISteadyClock.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class TimeISteadyClock
-    {
-
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/TimeISystemClock.cs b/Ryujinx/OsHle/Objects/TimeISystemClock.cs
deleted file mode 100644
index d9a3a073ec..0000000000
--- a/Ryujinx/OsHle/Objects/TimeISystemClock.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace Ryujinx.OsHle.Objects
-{
-    class TimeISystemClock
-    {
-        private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
-        public static long GetCurrentTime(ServiceCtx Context)
-        {
-            Context.ResponseData.Write((long)(DateTime.Now - Epoch).TotalSeconds);
-
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/TimeITimeZoneService.cs b/Ryujinx/OsHle/Objects/TimeITimeZoneService.cs
deleted file mode 100644
index af5490a613..0000000000
--- a/Ryujinx/OsHle/Objects/TimeITimeZoneService.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class TimeITimeZoneService
-    {
-
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/ViIApplicationDisplayService.cs b/Ryujinx/OsHle/Objects/Vi/IApplicationDisplayService.cs
similarity index 64%
rename from Ryujinx/OsHle/Objects/ViIApplicationDisplayService.cs
rename to Ryujinx/OsHle/Objects/Vi/IApplicationDisplayService.cs
index 174c97b4fe..4fa3592800 100644
--- a/Ryujinx/OsHle/Objects/ViIApplicationDisplayService.cs
+++ b/Ryujinx/OsHle/Objects/Vi/IApplicationDisplayService.cs
@@ -1,44 +1,65 @@
 using ChocolArm64.Memory;
 using Ryujinx.OsHle.Handles;
 using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
 using System.IO;
 
 using static Ryujinx.OsHle.Objects.Android.Parcel;
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.Vi
 {
-    class ViIApplicationDisplayService
+    class IApplicationDisplayService : IIpcInterface
     {
-        public static long GetRelayService(ServiceCtx Context)
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IApplicationDisplayService()
         {
-            MakeObject(Context, new ViIHOSBinderDriver());
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                {  100, GetRelayService                      },
+                {  101, GetSystemDisplayService              },
+                {  102, GetManagerDisplayService             },
+                {  103, GetIndirectDisplayTransactionService },
+                { 1010, OpenDisplay                          },
+                { 2020, OpenLayer                            },
+                { 2030, CreateStrayLayer                     },
+                { 2101, SetLayerScalingMode                  },
+                { 5202, GetDisplayVSyncEvent                 }
+            };
+        }
+
+        public long GetRelayService(ServiceCtx Context)
+        {
+            MakeObject(Context, new IHOSBinderDriver());
 
             return 0;
         }
 
-        public static long GetSystemDisplayService(ServiceCtx Context)
+        public long GetSystemDisplayService(ServiceCtx Context)
         {
-            MakeObject(Context, new ViISystemDisplayService());
+            MakeObject(Context, new ISystemDisplayService());
 
             return 0;
         }
 
-        public static long GetManagerDisplayService(ServiceCtx Context)
+        public long GetManagerDisplayService(ServiceCtx Context)
         {
-            MakeObject(Context, new ViIManagerDisplayService());
+            MakeObject(Context, new IManagerDisplayService());
 
             return 0;
         }
 
-        public static long GetIndirectDisplayTransactionService(ServiceCtx Context)
+        public long GetIndirectDisplayTransactionService(ServiceCtx Context)
         {
-            MakeObject(Context, new ViIHOSBinderDriver());
+            MakeObject(Context, new IHOSBinderDriver());
 
             return 0;
         }
 
-        public static long OpenDisplay(ServiceCtx Context)
+        public long OpenDisplay(ServiceCtx Context)
         {
             string Name = GetDisplayName(Context);
 
@@ -49,7 +70,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long OpenLayer(ServiceCtx Context)
+        public long OpenLayer(ServiceCtx Context)
         {
             long LayerId = Context.RequestData.ReadInt64();
             long UserId  = Context.RequestData.ReadInt64();
@@ -65,7 +86,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long CreateStrayLayer(ServiceCtx Context)
+        public long CreateStrayLayer(ServiceCtx Context)
         {
             long LayerFlags = Context.RequestData.ReadInt64();
             long DisplayId  = Context.RequestData.ReadInt64();
@@ -84,7 +105,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long SetLayerScalingMode(ServiceCtx Context)
+        public long SetLayerScalingMode(ServiceCtx Context)
         {
             int  ScalingMode = Context.RequestData.ReadInt32();
             long Unknown     = Context.RequestData.ReadInt64();
@@ -92,7 +113,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long GetDisplayVSyncEvent(ServiceCtx Context)
+        public long GetDisplayVSyncEvent(ServiceCtx Context)
         {
             string Name = GetDisplayName(Context);
 
@@ -103,7 +124,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        private static byte[] MakeIGraphicsBufferProducer(long BasePtr)
+        private byte[] MakeIGraphicsBufferProducer(long BasePtr)
         {
             long Id        = 0x20;
             long CookiePtr = 0L;
@@ -133,7 +154,7 @@ namespace Ryujinx.OsHle.Objects
             }
         }
 
-        private static string GetDisplayName(ServiceCtx Context)
+        private string GetDisplayName(ServiceCtx Context)
         {
             string Name = string.Empty;
 
diff --git a/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs b/Ryujinx/OsHle/Objects/Vi/IHOSBinderDriver.cs
similarity index 83%
rename from Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs
rename to Ryujinx/OsHle/Objects/Vi/IHOSBinderDriver.cs
index 13393eafcb..3c3211c7f2 100644
--- a/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs
+++ b/Ryujinx/OsHle/Objects/Vi/IHOSBinderDriver.cs
@@ -9,14 +9,18 @@ using System.Text;
 
 using static Ryujinx.OsHle.Objects.Android.Parcel;
 
-namespace Ryujinx.OsHle.Objects
+namespace Ryujinx.OsHle.Objects.Vi
 {
-    class ViIHOSBinderDriver
+    class IHOSBinderDriver : IIpcInterface
     {
-        private delegate long ServiceProcessRequest(ServiceCtx Context, byte[] ParcelData);
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
 
-        private static Dictionary<(string, int), ServiceProcessRequest> InterfaceMthd =
-                   new Dictionary<(string, int), ServiceProcessRequest>()
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        private delegate long ServiceProcessRequest2(ServiceCtx Context, byte[] ParcelData);
+
+        private Dictionary<(string, int), ServiceProcessRequest2> InterfaceMthd =
+            new Dictionary<(string, int), ServiceProcessRequest2>()
         {
             { ("android.gui.IGraphicBufferProducer", 0x1), GraphicBufferProducerRequestBuffer },
             { ("android.gui.IGraphicBufferProducer", 0x3), GraphicBufferProducerDequeueBuffer },
@@ -36,12 +40,19 @@ namespace Ryujinx.OsHle.Objects
 
         public byte[] Gbfr;
 
-        public ViIHOSBinderDriver()
+        public IHOSBinderDriver()
         {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, TransactParcel  },
+                { 1, AdjustRefcount  },
+                { 2, GetNativeHandle }
+            };
+
             BufferSlots = new IdPoolWithObj();
         }
 
-        public static long TransactParcel(ServiceCtx Context)
+        public long TransactParcel(ServiceCtx Context)
         {
             int Id   = Context.RequestData.ReadInt32();
             int Code = Context.RequestData.ReadInt32();
@@ -63,7 +74,7 @@ namespace Ryujinx.OsHle.Objects
 
                 string InterfaceName = Encoding.Unicode.GetString(Data, 8, StrSize * 2);
 
-                if (InterfaceMthd.TryGetValue((InterfaceName, Code), out ServiceProcessRequest ProcReq))
+                if (InterfaceMthd.TryGetValue((InterfaceName, Code), out ServiceProcessRequest2 ProcReq))
                 {
                     return ProcReq(Context, Data);
                 }
@@ -76,7 +87,7 @@ namespace Ryujinx.OsHle.Objects
 
         private static long GraphicBufferProducerRequestBuffer(ServiceCtx Context, byte[] ParcelData)
         {
-            ViIHOSBinderDriver BinderDriver = Context.GetObject<ViIHOSBinderDriver>();
+            IHOSBinderDriver BinderDriver = Context.GetObject<IHOSBinderDriver>();
 
             int GbfrSize = BinderDriver.Gbfr?.Length ?? 0;
 
@@ -92,7 +103,7 @@ namespace Ryujinx.OsHle.Objects
 
         private static long GraphicBufferProducerDequeueBuffer(ServiceCtx Context, byte[] ParcelData)
         {
-            ViIHOSBinderDriver BinderDriver = Context.GetObject<ViIHOSBinderDriver>();
+            IHOSBinderDriver BinderDriver = Context.GetObject<IHOSBinderDriver>();
 
             //Note: It seems that the maximum number of slots is 64, because if we return
             //a Slot number > 63, it seems to cause a buffer overrun and it reads garbage.
@@ -109,7 +120,7 @@ namespace Ryujinx.OsHle.Objects
 
         private static long GraphicBufferProducerCancelBuffer(ServiceCtx Context, byte[] ParcelData)
         {
-            ViIHOSBinderDriver BinderDriver = Context.GetObject<ViIHOSBinderDriver>();
+            IHOSBinderDriver BinderDriver = Context.GetObject<IHOSBinderDriver>();
 
             using (MemoryStream MS = new MemoryStream(ParcelData))
             {
@@ -137,7 +148,7 @@ namespace Ryujinx.OsHle.Objects
 
         private static long GraphicBufferPreallocateBuffer(ServiceCtx Context, byte[] ParcelData)
         {
-            ViIHOSBinderDriver BinderDriver = Context.GetObject<ViIHOSBinderDriver>();
+            IHOSBinderDriver BinderDriver = Context.GetObject<IHOSBinderDriver>();
 
             int GbfrSize = ParcelData.Length - 0x54;
 
@@ -188,7 +199,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long AdjustRefcount(ServiceCtx Context)
+        public long AdjustRefcount(ServiceCtx Context)
         {
             int Id     = Context.RequestData.ReadInt32();
             int AddVal = Context.RequestData.ReadInt32();
@@ -197,7 +208,7 @@ namespace Ryujinx.OsHle.Objects
             return 0;
         }
 
-        public static long GetNativeHandle(ServiceCtx Context)
+        public long GetNativeHandle(ServiceCtx Context)
         {
             int  Id  = Context.RequestData.ReadInt32();
             uint Unk = Context.RequestData.ReadUInt32();
diff --git a/Ryujinx/OsHle/Objects/Vi/IManagerDisplayService.cs b/Ryujinx/OsHle/Objects/Vi/IManagerDisplayService.cs
new file mode 100644
index 0000000000..c2bbf43b28
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Vi/IManagerDisplayService.cs
@@ -0,0 +1,33 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Vi
+{
+    class IManagerDisplayService : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IManagerDisplayService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 2010, CreateManagedLayer },
+                { 6000, AddToLayerStack    }
+            };
+        }
+
+        public static long CreateManagedLayer(ServiceCtx Context)
+        {
+            Context.ResponseData.Write(0L); //LayerId
+
+            return 0;
+        }
+
+        public static long AddToLayerStack(ServiceCtx Context)
+        {
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/Vi/ISystemDisplayService.cs b/Ryujinx/OsHle/Objects/Vi/ISystemDisplayService.cs
new file mode 100644
index 0000000000..39d1978640
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/Vi/ISystemDisplayService.cs
@@ -0,0 +1,25 @@
+using Ryujinx.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.OsHle.Objects.Vi
+{
+    class ISystemDisplayService : IIpcInterface
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public ISystemDisplayService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 2205, SetLayerZ }
+            };
+        }
+
+        public static long SetLayerZ(ServiceCtx Context)
+        {
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/ViIManagerDisplayService.cs b/Ryujinx/OsHle/Objects/ViIManagerDisplayService.cs
deleted file mode 100644
index 0fdca3bac2..0000000000
--- a/Ryujinx/OsHle/Objects/ViIManagerDisplayService.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class ViIManagerDisplayService
-    {
-        public static long CreateManagedLayer(ServiceCtx Context)
-        {
-            Context.ResponseData.Write(0L); //LayerId
-
-            return 0;
-        }
-
-        public static long AddToLayerStack(ServiceCtx Context)
-        {
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/ViISystemDisplayService.cs b/Ryujinx/OsHle/Objects/ViISystemDisplayService.cs
deleted file mode 100644
index 8d3a51f4eb..0000000000
--- a/Ryujinx/OsHle/Objects/ViISystemDisplayService.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.OsHle.Objects
-{
-    class ViISystemDisplayService
-    {
-        public static long SetLayerZ(ServiceCtx Context)
-        {
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Services/ServiceAcc.cs b/Ryujinx/OsHle/Services/ServiceAcc.cs
index 14a3e83ea3..632fb41c25 100644
--- a/Ryujinx/OsHle/Services/ServiceAcc.cs
+++ b/Ryujinx/OsHle/Services/ServiceAcc.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Acc;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -13,7 +13,7 @@ namespace Ryujinx.OsHle.Services
 
         public static long AccU0GetProfile(ServiceCtx Context)
         {
-            MakeObject(Context, new AccIProfile());
+            MakeObject(Context, new IProfile());
 
             return 0;
         }
@@ -25,7 +25,7 @@ namespace Ryujinx.OsHle.Services
 
         public static long AccU0GetBaasAccountManagerForApplication(ServiceCtx Context)
         {
-            MakeObject(Context, new AccIManagerForApplication());
+            MakeObject(Context, new IManagerForApplication());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceApm.cs b/Ryujinx/OsHle/Services/ServiceApm.cs
index f0df462b7b..81e68680a8 100644
--- a/Ryujinx/OsHle/Services/ServiceApm.cs
+++ b/Ryujinx/OsHle/Services/ServiceApm.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Apm;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -8,7 +8,7 @@ namespace Ryujinx.OsHle.Services
     {
         public static long ApmOpenSession(ServiceCtx Context)
         {
-            MakeObject(Context, new ApmISession());
+            MakeObject(Context, new ISession());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceAppletOE.cs b/Ryujinx/OsHle/Services/ServiceAppletOE.cs
index 2f98a20143..cd0ed92bcb 100644
--- a/Ryujinx/OsHle/Services/ServiceAppletOE.cs
+++ b/Ryujinx/OsHle/Services/ServiceAppletOE.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.OsHle.Services
     {
         public static long AppletOpenApplicationProxy(ServiceCtx Context)
         {
-            MakeObject(Context, new AmIApplicationProxy());
+            MakeObject(Context, new IApplicationProxy());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceAud.cs b/Ryujinx/OsHle/Services/ServiceAud.cs
index 18401ae952..6d1367cf1a 100644
--- a/Ryujinx/OsHle/Services/ServiceAud.cs
+++ b/Ryujinx/OsHle/Services/ServiceAud.cs
@@ -1,5 +1,5 @@
 using ChocolArm64.Memory;
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Aud;
 using System.Text;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
@@ -21,7 +21,7 @@ namespace Ryujinx.OsHle.Services
 
         public static long AudOutOpenAudioOut(ServiceCtx Context)
         {
-            MakeObject(Context, new AudIAudioOut());
+            MakeObject(Context, new IAudioOut());
 
             Context.ResponseData.Write(48000); //Sample Rate
             Context.ResponseData.Write(2); //Channel Count
@@ -42,7 +42,7 @@ namespace Ryujinx.OsHle.Services
 
         public static long AudRenOpenAudioRenderer(ServiceCtx Context)
         {
-            MakeObject(Context, new AudIAudioRenderer());
+            MakeObject(Context, new IAudioRenderer());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceFriend.cs b/Ryujinx/OsHle/Services/ServiceFriend.cs
index 980d421967..10c23aaea4 100644
--- a/Ryujinx/OsHle/Services/ServiceFriend.cs
+++ b/Ryujinx/OsHle/Services/ServiceFriend.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Friend;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -8,7 +8,7 @@ namespace Ryujinx.OsHle.Services
     {
         public static long FriendCreateFriendService(ServiceCtx Context)
         {
-            MakeObject(Context, new FriendIFriendService());
+            MakeObject(Context, new IFriendService());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceFspSrv.cs b/Ryujinx/OsHle/Services/ServiceFspSrv.cs
index 7f431f267f..17aa3bda7d 100644
--- a/Ryujinx/OsHle/Services/ServiceFspSrv.cs
+++ b/Ryujinx/OsHle/Services/ServiceFspSrv.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.FspSrv;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -13,28 +13,28 @@ namespace Ryujinx.OsHle.Services
 
         public static long FspSrvMountSdCard(ServiceCtx Context)
         {
-            MakeObject(Context, new FspSrvIFileSystem(Context.Ns.VFs.GetSdCardPath()));
+            MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetSdCardPath()));
 
             return 0;
         }
 
         public static long FspSrvMountSaveData(ServiceCtx Context)
         {
-            MakeObject(Context, new FspSrvIFileSystem(Context.Ns.VFs.GetGameSavesPath()));
+            MakeObject(Context, new IFileSystem(Context.Ns.VFs.GetGameSavesPath()));
 
             return 0;
         }
 
         public static long FspSrvOpenDataStorageByCurrentProcess(ServiceCtx Context)
         {
-            MakeObject(Context, new FspSrvIStorage(Context.Ns.VFs.RomFs));
+            MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs));
 
             return 0;
         }
 
         public static long FspSrvOpenRomStorage(ServiceCtx Context)
         {
-            MakeObject(Context, new FspSrvIStorage(Context.Ns.VFs.RomFs));
+            MakeObject(Context, new IStorage(Context.Ns.VFs.RomFs));
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceHid.cs b/Ryujinx/OsHle/Services/ServiceHid.cs
index 30093f49fc..176c7842cc 100644
--- a/Ryujinx/OsHle/Services/ServiceHid.cs
+++ b/Ryujinx/OsHle/Services/ServiceHid.cs
@@ -1,5 +1,5 @@
 using Ryujinx.OsHle.Handles;
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Hid;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -11,7 +11,7 @@ namespace Ryujinx.OsHle.Services
         {
             HSharedMem HidHndData = Context.Ns.Os.Handles.GetData<HSharedMem>(Context.Ns.Os.HidHandle);
 
-            MakeObject(Context, new HidIAppletResource(HidHndData));
+            MakeObject(Context, new IAppletResource(HidHndData));
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServicePctl.cs b/Ryujinx/OsHle/Services/ServicePctl.cs
index 62537f2874..a0a5aaf3f8 100644
--- a/Ryujinx/OsHle/Services/ServicePctl.cs
+++ b/Ryujinx/OsHle/Services/ServicePctl.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Am;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -8,7 +8,7 @@ namespace Ryujinx.OsHle.Services
     {
         public static long PctlCreateService(ServiceCtx Context)
         {
-            MakeObject(Context, new AmIParentalControlService());
+            MakeObject(Context, new IParentalControlService());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceTime.cs b/Ryujinx/OsHle/Services/ServiceTime.cs
index 2b93e3db82..4f8e34e97b 100644
--- a/Ryujinx/OsHle/Services/ServiceTime.cs
+++ b/Ryujinx/OsHle/Services/ServiceTime.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Time;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -8,28 +8,28 @@ namespace Ryujinx.OsHle.Services
     {
         public static long TimeGetStandardUserSystemClock(ServiceCtx Context)
         {
-            MakeObject(Context, new TimeISystemClock());
+            MakeObject(Context, new ISystemClock());
 
             return 0;
         }
 
         public static long TimeGetStandardNetworkSystemClock(ServiceCtx Context)
         {
-            MakeObject(Context, new TimeISystemClock());
+            MakeObject(Context, new ISystemClock());
 
             return 0;
         }
 
         public static long TimeGetStandardSteadyClock(ServiceCtx Context)
         {
-            MakeObject(Context, new TimeISteadyClock());
+            MakeObject(Context, new ISteadyClock());
 
             return 0;
         }
 
         public static long TimeGetTimeZoneService(ServiceCtx Context)
         {
-            MakeObject(Context, new TimeITimeZoneService());
+            MakeObject(Context, new ITimeZoneService());
 
             return 0;
         }
diff --git a/Ryujinx/OsHle/Services/ServiceVi.cs b/Ryujinx/OsHle/Services/ServiceVi.cs
index d5c86bfc26..096bc18f01 100644
--- a/Ryujinx/OsHle/Services/ServiceVi.cs
+++ b/Ryujinx/OsHle/Services/ServiceVi.cs
@@ -1,4 +1,4 @@
-using Ryujinx.OsHle.Objects;
+using Ryujinx.OsHle.Objects.Vi;
 
 using static Ryujinx.OsHle.Objects.ObjHelper;
 
@@ -10,7 +10,7 @@ namespace Ryujinx.OsHle.Services
         {
             int Unknown = Context.RequestData.ReadInt32();
 
-            MakeObject(Context, new ViIApplicationDisplayService());
+            MakeObject(Context, new IApplicationDisplayService());
 
             return 0;
         }