diff --git a/ChocolArm64/AOptimizations.cs b/ChocolArm64/AOptimizations.cs
index a3c82dccd..2627c2368 100644
--- a/ChocolArm64/AOptimizations.cs
+++ b/ChocolArm64/AOptimizations.cs
@@ -1,4 +1,6 @@
 public static class AOptimizations
 {
     public static bool DisableMemoryChecks = false;
+
+    public static bool GenerateCallStack = true;
 }
\ No newline at end of file
diff --git a/ChocolArm64/Instruction/AInstEmitException.cs b/ChocolArm64/Instruction/AInstEmitException.cs
index 3964c9497..041e2890a 100644
--- a/ChocolArm64/Instruction/AInstEmitException.cs
+++ b/ChocolArm64/Instruction/AInstEmitException.cs
@@ -8,8 +8,6 @@ namespace ChocolArm64.Instruction
 {
     static partial class AInstEmit
     {
-        private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
-
         public static void Brk(AILEmitterCtx Context)
         {
             EmitExceptionCall(Context, nameof(AThreadState.OnBreak));
@@ -30,9 +28,7 @@ namespace ChocolArm64.Instruction
 
             Context.EmitLdc_I4(Op.Id);
 
-            MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
-
-            Context.EmitCall(MthdInfo);
+            Context.EmitPrivateCall(typeof(AThreadState), MthdName);
 
             //Check if the thread should still be running, if it isn't then we return 0
             //to force a return to the dispatcher and then exit the thread.
@@ -73,11 +69,7 @@ namespace ChocolArm64.Instruction
             Context.EmitLdc_I8(Op.Position);
             Context.EmitLdc_I4(Op.RawOpCode);
 
-            string MthdName = nameof(AThreadState.OnUndefined);
-
-            MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
-
-            Context.EmitCall(MthdInfo);
+            Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.OnUndefined));
 
             if (Context.CurrBlock.Next != null)
             {
diff --git a/ChocolArm64/Instruction/AInstEmitFlow.cs b/ChocolArm64/Instruction/AInstEmitFlow.cs
index 91262834f..89979d050 100644
--- a/ChocolArm64/Instruction/AInstEmitFlow.cs
+++ b/ChocolArm64/Instruction/AInstEmitFlow.cs
@@ -35,6 +35,14 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp;
 
+            if (AOptimizations.GenerateCallStack)
+            {
+                Context.EmitLdarg(ATranslatedSub.StateArgIdx);
+                Context.EmitLdc_I8(Op.Imm);
+
+                Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.EnterMethod));
+            }
+
             Context.EmitLdc_I(Op.Position + 4);
             Context.EmitStint(AThreadState.LRIndex);
             Context.EmitStoreState();
@@ -72,6 +80,14 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
 
+            if (AOptimizations.GenerateCallStack)
+            {
+                Context.EmitLdarg(ATranslatedSub.StateArgIdx);
+                Context.EmitLdintzr(Op.Rn);
+
+                Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.EnterMethod));
+            }
+
             Context.EmitLdc_I(Op.Position + 4);
             Context.EmitStint(AThreadState.LRIndex);
             Context.EmitStoreState();
@@ -84,6 +100,14 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
 
+            if (AOptimizations.GenerateCallStack)
+            {
+                Context.EmitLdarg(ATranslatedSub.StateArgIdx);
+                Context.EmitLdintzr(Op.Rn);
+
+                Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.JumpMethod));
+            }
+
             Context.EmitStoreState();
             Context.EmitLdintzr(Op.Rn);
 
@@ -105,6 +129,13 @@ namespace ChocolArm64.Instruction
 
         public static void Ret(AILEmitterCtx Context)
         {
+            if (AOptimizations.GenerateCallStack)
+            {
+                Context.EmitLdarg(ATranslatedSub.StateArgIdx);
+
+                Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.ExitMethod));
+            }
+
             Context.EmitStoreState();
             Context.EmitLdint(AThreadState.LRIndex);
 
diff --git a/ChocolArm64/State/AThreadState.cs b/ChocolArm64/State/AThreadState.cs
index 6f3f62f69..ce1278866 100644
--- a/ChocolArm64/State/AThreadState.cs
+++ b/ChocolArm64/State/AThreadState.cs
@@ -1,5 +1,6 @@
 using ChocolArm64.Events;
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 
 namespace ChocolArm64.State
@@ -56,10 +57,17 @@ namespace ChocolArm64.State
         public event EventHandler<AInstExceptionEventArgs> SvcCall;
         public event EventHandler<AInstUndefinedEventArgs> Undefined;
 
+        private Stack<long> CallStack;
+
         private static Stopwatch TickCounter;
 
         private static double HostTickFreq;
 
+        public AThreadState()
+        {
+            CallStack = new Stack<long>();
+        }
+
         static AThreadState()
         {
             HostTickFreq = 1.0 / Stopwatch.Frequency;
@@ -83,5 +91,27 @@ namespace ChocolArm64.State
         {
             Undefined?.Invoke(this, new AInstUndefinedEventArgs(Position, RawOpCode));
         }
+
+        internal void EnterMethod(long Position)
+        {
+            CallStack.Push(Position);
+        }
+
+        internal void ExitMethod()
+        {
+            CallStack.TryPop(out _);
+        }
+
+        internal void JumpMethod(long Position)
+        {
+            CallStack.TryPop(out _);
+
+            CallStack.Push(Position);
+        }
+
+        public long[] GetCallStack()
+        {
+            return CallStack.ToArray();
+        }
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Translation/AILEmitterCtx.cs b/ChocolArm64/Translation/AILEmitterCtx.cs
index 2f4a67e1b..a004a9665 100644
--- a/ChocolArm64/Translation/AILEmitterCtx.cs
+++ b/ChocolArm64/Translation/AILEmitterCtx.cs
@@ -461,6 +461,21 @@ namespace ChocolArm64.Translation
             EmitCall(ObjType.GetMethod(MthdName));
         }
 
+        public void EmitPrivateCall(Type ObjType, string MthdName)
+        {
+            if (ObjType == null)
+            {
+                throw new ArgumentNullException(nameof(ObjType));
+            }
+
+            if (MthdName == null)
+            {
+                throw new ArgumentNullException(nameof(MthdName));
+            }
+
+            EmitCall(ObjType.GetMethod(MthdName, BindingFlags.Instance | BindingFlags.NonPublic));
+        }
+
         public void EmitCall(MethodInfo MthdInfo)
         {
             if (MthdInfo == null)
diff --git a/Ryujinx.Core/Loaders/Executable.cs b/Ryujinx.Core/Loaders/Executable.cs
index 943b8e510..39ee9618b 100644
--- a/Ryujinx.Core/Loaders/Executable.cs
+++ b/Ryujinx.Core/Loaders/Executable.cs
@@ -7,14 +7,16 @@ namespace Ryujinx.Core.Loaders
 {
     class Executable
     {
-        private AMemory Memory;
-
         private List<ElfDyn> Dynamic;
 
         private Dictionary<long, string> m_SymbolTable;
 
         public IReadOnlyDictionary<long, string> SymbolTable => m_SymbolTable;
 
+        public string Name { get; private set; }
+
+        private AMemory Memory;
+
         public long ImageBase { get; private set; }
         public long ImageEnd  { get; private set; }
 
@@ -24,6 +26,8 @@ namespace Ryujinx.Core.Loaders
 
             m_SymbolTable = new Dictionary<long, string>();
 
+            Name = Exe.Name;
+
             this.Memory    = Memory;
             this.ImageBase = ImageBase;
             this.ImageEnd  = ImageBase;
diff --git a/Ryujinx.Core/Loaders/Executables/IExecutable.cs b/Ryujinx.Core/Loaders/Executables/IExecutable.cs
index 09d0aab23..412058d88 100644
--- a/Ryujinx.Core/Loaders/Executables/IExecutable.cs
+++ b/Ryujinx.Core/Loaders/Executables/IExecutable.cs
@@ -2,6 +2,8 @@ namespace Ryujinx.Core.Loaders.Executables
 {
     public interface IExecutable
     {
+        string Name { get; }
+
         byte[] Text { get; }
         byte[] RO   { get; }
         byte[] Data { get; }
diff --git a/Ryujinx.Core/Loaders/Executables/Nro.cs b/Ryujinx.Core/Loaders/Executables/Nro.cs
index 9f4ef59f5..c3411d226 100644
--- a/Ryujinx.Core/Loaders/Executables/Nro.cs
+++ b/Ryujinx.Core/Loaders/Executables/Nro.cs
@@ -4,6 +4,8 @@ namespace Ryujinx.Core.Loaders.Executables
 {
     class Nro : IExecutable
     {
+        public string Name { get; private set; }
+
         public byte[] Text { get; private set; }
         public byte[] RO   { get; private set; }
         public byte[] Data { get; private set; }
@@ -14,8 +16,10 @@ namespace Ryujinx.Core.Loaders.Executables
         public int DataOffset { get; private set; }
         public int BssSize    { get; private set; }
 
-        public Nro(Stream Input)
+        public Nro(Stream Input, string Name)
         {
+            this.Name = Name;
+
             BinaryReader Reader = new BinaryReader(Input);
 
             Input.Seek(4, SeekOrigin.Begin);
diff --git a/Ryujinx.Core/Loaders/Executables/Nso.cs b/Ryujinx.Core/Loaders/Executables/Nso.cs
index 7341ba622..bfe159d7c 100644
--- a/Ryujinx.Core/Loaders/Executables/Nso.cs
+++ b/Ryujinx.Core/Loaders/Executables/Nso.cs
@@ -6,6 +6,8 @@ namespace Ryujinx.Core.Loaders.Executables
 {
     class Nso : IExecutable
     {
+        public string Name { get; private set; }
+
         public byte[] Text { get; private set; }
         public byte[] RO   { get; private set; }
         public byte[] Data { get; private set; }
@@ -27,8 +29,10 @@ namespace Ryujinx.Core.Loaders.Executables
             HasDataHash      = 1 << 5
         }
 
-        public Nso(Stream Input)
+        public Nso(Stream Input, string Name)
         {
+            this.Name = Name;
+
             BinaryReader Reader = new BinaryReader(Input);
 
             Input.Seek(0, SeekOrigin.Begin);
diff --git a/Ryujinx.Core/LogClass.cs b/Ryujinx.Core/LogClass.cs
index 60a8de787..014b57325 100644
--- a/Ryujinx.Core/LogClass.cs
+++ b/Ryujinx.Core/LogClass.cs
@@ -16,6 +16,7 @@
         ServiceApm,
         ServiceAudio,
         ServiceBsd,
+        ServiceCaps,
         ServiceFriend,
         ServiceFs,
         ServiceHid,
diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs
index 9e113080c..6c625b09d 100644
--- a/Ryujinx.Core/OsHle/Horizon.cs
+++ b/Ryujinx.Core/OsHle/Horizon.cs
@@ -58,7 +58,9 @@ namespace Ryujinx.Core.OsHle
 
                     using (FileStream Input = new FileStream(File, FileMode.Open))
                     {
-                        Nso Program = new Nso(Input);
+                        string Name = Path.GetFileNameWithoutExtension(File);
+
+                        Nso Program = new Nso(Input, Name);
 
                         MainProcess.LoadProgram(Program);
                     }
@@ -80,13 +82,15 @@ namespace Ryujinx.Core.OsHle
         {
             bool IsNro = Path.GetExtension(FileName).ToLower() == ".nro";
 
+            string Name = Path.GetFileNameWithoutExtension(FileName);
+
             Process MainProcess = MakeProcess();
 
             using (FileStream Input = new FileStream(FileName, FileMode.Open))
             {
                 MainProcess.LoadProgram(IsNro
-                    ? (IExecutable)new Nro(Input)
-                    : (IExecutable)new Nso(Input));
+                    ? (IExecutable)new Nro(Input, Name)
+                    : (IExecutable)new Nso(Input, Name));
             }
 
             MainProcess.SetEmptyArgs();
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
index 1e4d61b4f..e1300b739 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
@@ -156,13 +156,13 @@ namespace Ryujinx.Core.OsHle.Kernel
         private void SvcSetThreadActivity(AThreadState ThreadState)
         {
             int  Handle = (int)ThreadState.X0;
-            bool Active = (int)ThreadState.X1 != 0;
+            bool Active = (int)ThreadState.X1 == 0;
 
-            KThread CurrThread = Process.HandleTable.GetData<KThread>(Handle);
+            KThread Thread = Process.HandleTable.GetData<KThread>(Handle);
 
-            if (CurrThread != null)
+            if (Thread != null)
             {
-                Process.Scheduler.SetThreadActivity(CurrThread, Active);
+                Process.Scheduler.SetThreadActivity(Thread, Active);
 
                 ThreadState.X0 = 0;
             }
diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs
index bd4ff1ff2..0f8c726c6 100644
--- a/Ryujinx.Core/OsHle/Process.cs
+++ b/Ryujinx.Core/OsHle/Process.cs
@@ -1,6 +1,7 @@
 using ChocolArm64;
 using ChocolArm64.Events;
 using ChocolArm64.Memory;
+using ChocolArm64.State;
 using Ryujinx.Core.Loaders;
 using Ryujinx.Core.Loaders.Executables;
 using Ryujinx.Core.OsHle.Exceptions;
@@ -10,6 +11,7 @@ using Ryujinx.Core.OsHle.Services.Nv;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Text;
 
 namespace Ryujinx.Core.OsHle
 {
@@ -47,9 +49,11 @@ namespace Ryujinx.Core.OsHle
 
         private ConcurrentDictionary<long, KThread> Threads;
 
+        private KThread MainThread;
+
         private List<Executable> Executables;
 
-        private KThread MainThread;
+        private Dictionary<long, string> SymbolTable;
 
         private long ImageBase;
 
@@ -121,6 +125,8 @@ namespace Ryujinx.Core.OsHle
                 return false;
             }
 
+            MakeSymbolTable();
+
             MapRWMemRegion(
                 MemoryRegions.MainStackAddress,
                 MemoryRegions.MainStackSize,
@@ -227,20 +233,23 @@ namespace Ryujinx.Core.OsHle
             throw new UndefinedInstructionException(e.Position, e.RawOpCode);
         }
 
+        private void MakeSymbolTable()
+        {
+            SymbolTable = new Dictionary<long, string>();
+
+            foreach (Executable Exe in Executables)
+            {
+                foreach (KeyValuePair<long, string> KV in Exe.SymbolTable)
+                {
+                    SymbolTable.TryAdd(Exe.ImageBase + KV.Key, KV.Value);
+                }
+            }
+        }
+
         private ATranslator GetTranslator()
         {
             if (Translator == null)
             {
-                Dictionary<long, string> SymbolTable = new Dictionary<long, string>();
-
-                foreach (Executable Exe in Executables)
-                {
-                    foreach (KeyValuePair<long, string> KV in Exe.SymbolTable)
-                    {
-                        SymbolTable.TryAdd(Exe.ImageBase + KV.Key, KV.Value);
-                    }
-                }
-
                 Translator = new ATranslator(SymbolTable);
 
                 Translator.CpuTrace += CpuTraceHandler;
@@ -249,6 +258,16 @@ namespace Ryujinx.Core.OsHle
             return Translator;
         }
 
+        public void EnableCpuTracing()
+        {
+            Translator.EnableCpuTrace = true;
+        }
+
+        public void DisableCpuTracing()
+        {
+            Translator.EnableCpuTrace = false;
+        }
+
         private void CpuTraceHandler(object sender, ACpuTraceEventArgs e)
         {
             string NsoName = string.Empty;
@@ -263,17 +282,47 @@ namespace Ryujinx.Core.OsHle
                 }
             }
 
-            Logging.Trace(LogClass.Loader, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}");
+            Logging.Trace(LogClass.CPU, $"Executing at 0x{e.Position:x16} {e.SubName} {NsoName}");
         }
 
-        public void EnableCpuTracing()
+        public void PrintStackTrace(AThreadState ThreadState)
         {
-            Translator.EnableCpuTrace = true;
+            long[] Positions = ThreadState.GetCallStack();
+
+            StringBuilder Trace = new StringBuilder();
+
+            Trace.AppendLine("Guest stack trace:");
+
+            foreach (long Position in Positions)
+            {
+                if (!SymbolTable.TryGetValue(Position, out string SubName))
+                {
+                    SubName = $"Sub{Position:x16}";
+                }
+
+                Trace.AppendLine(" " + SubName + " (" + GetNsoNameAndAddress(Position) + ")");
+            }
+
+            Logging.Trace(LogClass.CPU, Trace.ToString());
         }
 
-        public void DisableCpuTracing()
+        private string GetNsoNameAndAddress(long Position)
         {
-            Translator.EnableCpuTrace = false;
+            string Name = string.Empty;
+
+            for (int Index = Executables.Count - 1; Index >= 0; Index--)
+            {
+                if (Position >= Executables[Index].ImageBase)
+                {
+                    long Offset = Position - Executables[Index].ImageBase;
+
+                    Name = $"{Executables[Index].Name}:{Offset:x8}";
+
+                    break;
+                }
+            }
+
+            return Name;
         }
 
         private int GetFreeTlsSlot(AThread Thread)
diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
index ca4e368a6..f1c63fac5 100644
--- a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
+++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs
@@ -18,6 +18,7 @@ namespace Ryujinx.Core.OsHle.Services.Am
                 { 20, EnsureSaveData     },
                 { 21, GetDesiredLanguage },
                 { 22, SetTerminateResult },
+                { 23, GetDisplayVersion  },
                 { 40, NotifyRunning      }
             };
         }
@@ -67,6 +68,15 @@ namespace Ryujinx.Core.OsHle.Services.Am
             return 0;
         }
 
+        public long GetDisplayVersion(ServiceCtx Context)
+        {
+            //FIXME: Need to check correct version on a switch.
+            Context.ResponseData.Write(1L);
+            Context.ResponseData.Write(0L);
+
+            return 0;
+        }
+
         public long NotifyRunning(ServiceCtx Context)
         {
             Context.ResponseData.Write(1);
diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs
similarity index 83%
rename from Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs
rename to Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs
index b27d14489..039a4413f 100644
--- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs
+++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs
@@ -6,7 +6,7 @@ using System.Text;
 
 namespace Ryujinx.Core.OsHle.Services.Aud
 {
-    class IAudioDeviceService : IpcService
+    class IAudioDevice : IpcService
     {
         private Dictionary<int, ServiceProcessRequest> m_Commands;
 
@@ -14,12 +14,13 @@ namespace Ryujinx.Core.OsHle.Services.Aud
 
         private KEvent SystemEvent;
 
-        public IAudioDeviceService()
+        public IAudioDevice()
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
                 { 0, ListAudioDeviceName         },
                 { 1, SetAudioDeviceOutputVolume  },
+                { 3, GetActiveAudioDeviceName    },
                 { 4, QueryAudioDeviceSystemEvent },
                 { 5, GetActiveChannelCount       }
             };
@@ -72,6 +73,20 @@ namespace Ryujinx.Core.OsHle.Services.Aud
             return 0;
         }
 
+        public long GetActiveAudioDeviceName(ServiceCtx Context)
+        {
+            string Name = "FIXME";
+
+            long Position = Context.Request.ReceiveBuff[0].Position;
+            long Size     = Context.Request.ReceiveBuff[0].Size;
+
+            byte[] Buffer = Encoding.ASCII.GetBytes(Name + '\0');
+
+            AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer);
+
+            return 0;
+        }
+
         public long QueryAudioDeviceSystemEvent(ServiceCtx Context)
         {
             int Handle = Context.Process.HandleTable.OpenHandle(SystemEvent);
diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs
index eee47089e..dcf3c7b7c 100644
--- a/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs
+++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioRendererManager.cs
@@ -53,7 +53,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
         {
             long UserId = Context.RequestData.ReadInt64();
 
-            MakeObject(Context, new IAudioDeviceService());
+            MakeObject(Context, new IAudioDevice());
 
             return 0;
         }
diff --git a/Ryujinx.Core/OsHle/Services/Caps/IAlbumAccessorService.cs b/Ryujinx.Core/OsHle/Services/Caps/IAlbumAccessorService.cs
new file mode 100644
index 000000000..d92f3e53c
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Caps/IAlbumAccessorService.cs
@@ -0,0 +1,20 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.Services.Caps
+{
+    class IAlbumAccessorService : IpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IAlbumAccessorService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Caps/IScreenshotService.cs b/Ryujinx.Core/OsHle/Services/Caps/IScreenshotService.cs
new file mode 100644
index 000000000..af9b53a8b
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Caps/IScreenshotService.cs
@@ -0,0 +1,20 @@
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+
+namespace Ryujinx.Core.OsHle.Services.Caps
+{
+    class IScreenshotService : IpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IScreenshotService()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                //...
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
index 11a5e46ab..8e639b949 100644
--- a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
+++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs
@@ -3,6 +3,7 @@ using Ryujinx.Core.OsHle.Services.Am;
 using Ryujinx.Core.OsHle.Services.Apm;
 using Ryujinx.Core.OsHle.Services.Aud;
 using Ryujinx.Core.OsHle.Services.Bsd;
+using Ryujinx.Core.OsHle.Services.Caps;
 using Ryujinx.Core.OsHle.Services.Friend;
 using Ryujinx.Core.OsHle.Services.FspSrv;
 using Ryujinx.Core.OsHle.Services.Hid;
@@ -57,9 +58,18 @@ namespace Ryujinx.Core.OsHle.Services
                 case "bsd:u":
                     return new IClient();
 
+                case "caps:a":
+                    return new IAlbumAccessorService();
+
+                case "caps:ss":
+                    return new IScreenshotService();
+
                 case "friend:a":
                     return new IServiceCreator();
 
+                case "friend:u":
+                    return new IServiceCreator();
+
                 case "fsp-srv":
                     return new IFileSystemProxy();
 
diff --git a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs
index 767d3cc74..ec50c82f4 100644
--- a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs
+++ b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs
@@ -16,10 +16,23 @@ namespace Ryujinx.Core.OsHle.Services.Time
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 101,  ToCalendarTimeWithMyRule }
+                {   0, GetDeviceLocationName    },
+                { 101, ToCalendarTimeWithMyRule }
             };
         }
 
+        public long GetDeviceLocationName(ServiceCtx Context)
+        {
+            Logging.Stub(LogClass.ServiceTime, "Stubbed");
+
+            for (int Index = 0; Index < 0x24; Index++)
+            {
+                Context.ResponseData.Write((byte)0);
+            }
+
+            return 0;
+        }
+
         public long ToCalendarTimeWithMyRule(ServiceCtx Context)
         {
             long PosixTime = Context.RequestData.ReadInt64();