diff --git a/Ryujinx.HLE/FileSystem/SaveDataType.cs b/Ryujinx.HLE/FileSystem/SaveDataType.cs
new file mode 100644
index 0000000000..edfe8ab1d9
--- /dev/null
+++ b/Ryujinx.HLE/FileSystem/SaveDataType.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.FileSystem
+{
+    enum SaveDataType : byte
+    {
+        SystemSaveData,
+        SaveData,
+        BcatDeliveryCacheStorage,
+        DeviceSaveData,
+        TemporaryStorage,
+        CacheStorage
+    }
+}
diff --git a/Ryujinx.HLE/FileSystem/SaveHelper.cs b/Ryujinx.HLE/FileSystem/SaveHelper.cs
new file mode 100644
index 0000000000..67f010169c
--- /dev/null
+++ b/Ryujinx.HLE/FileSystem/SaveHelper.cs
@@ -0,0 +1,46 @@
+using Ryujinx.HLE.HOS;
+using System.IO;
+
+using static Ryujinx.HLE.FileSystem.VirtualFileSystem;
+
+namespace Ryujinx.HLE.FileSystem
+{
+    static class SaveHelper
+    {
+        public static string GetSavePath(SaveInfo SaveMetaData, ServiceCtx Context)
+        {
+            string BaseSavePath   = NandPath;
+            long   CurrentTitleId = SaveMetaData.TitleId;
+
+            switch (SaveMetaData.SaveSpaceId)
+            {
+                case SaveSpaceId.NandUser:
+                    BaseSavePath = UserNandPath;
+                    break;
+                case SaveSpaceId.NandSystem:
+                    BaseSavePath = SystemNandPath;
+                    break;
+                case SaveSpaceId.SdCard:
+                    BaseSavePath = Path.Combine(SdCardPath, "Nintendo");
+                    break;
+            }
+
+            BaseSavePath = Path.Combine(BaseSavePath, "save");
+
+            if (SaveMetaData.TitleId == 0 && SaveMetaData.SaveDataType == SaveDataType.SaveData)
+            {
+                if (Context.Process.MetaData != null)
+                {
+                    CurrentTitleId = Context.Process.MetaData.ACI0.TitleId;
+                }
+            }
+
+            string SavePath = Path.Combine(BaseSavePath,
+                SaveMetaData.SaveId.ToString("x16"),
+                SaveMetaData.UserId.ToString(),
+                SaveMetaData.SaveDataType == SaveDataType.SaveData ? CurrentTitleId.ToString("x16") : string.Empty);
+
+            return SavePath;
+        }
+    }
+}
diff --git a/Ryujinx.HLE/FileSystem/SaveInfo.cs b/Ryujinx.HLE/FileSystem/SaveInfo.cs
new file mode 100644
index 0000000000..f3790ec787
--- /dev/null
+++ b/Ryujinx.HLE/FileSystem/SaveInfo.cs
@@ -0,0 +1,28 @@
+using Ryujinx.HLE.HOS.SystemState;
+
+namespace Ryujinx.HLE.FileSystem
+{
+    struct SaveInfo
+    {
+        public long   TitleId { get; private set; }
+        public long   SaveId  { get; private set; }
+        public UserId UserId  { get; private set; }
+
+        public SaveDataType SaveDataType { get; private set; }
+        public SaveSpaceId  SaveSpaceId  { get; private set; }
+
+        public SaveInfo(
+            long         TitleId,
+            long         SaveId,
+            SaveDataType SaveDataType,
+            UserId       UserId,
+            SaveSpaceId  SaveSpaceId)
+        {
+            this.TitleId      = TitleId;
+            this.UserId       = UserId;
+            this.SaveId       = SaveId;
+            this.SaveDataType = SaveDataType;
+            this.SaveSpaceId  = SaveSpaceId;
+        }
+    }
+}
diff --git a/Ryujinx.HLE/FileSystem/SaveSpaceId.cs b/Ryujinx.HLE/FileSystem/SaveSpaceId.cs
new file mode 100644
index 0000000000..5a2b32d635
--- /dev/null
+++ b/Ryujinx.HLE/FileSystem/SaveSpaceId.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.HLE.FileSystem
+{
+    enum SaveSpaceId : byte
+    {
+        NandSystem,
+        NandUser,
+        SdCard,
+        TemporaryStorage
+    }
+}
diff --git a/Ryujinx.HLE/VirtualFileSystem.cs b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs
similarity index 82%
rename from Ryujinx.HLE/VirtualFileSystem.cs
rename to Ryujinx.HLE/FileSystem/VirtualFileSystem.cs
index 133538f93a..e621ec2b11 100644
--- a/Ryujinx.HLE/VirtualFileSystem.cs
+++ b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs
@@ -1,14 +1,18 @@
+using Ryujinx.HLE.HOS;
 using System;
 using System.IO;
 
-namespace Ryujinx.HLE
+namespace Ryujinx.HLE.FileSystem
 {
     class VirtualFileSystem : IDisposable
     {
-        private const string BasePath   = "RyuFs";
-        private const string NandPath   = "nand";
-        private const string SdCardPath = "sdmc";
-        private const string SystemPath = "system";
+        public const string BasePath   = "RyuFs";
+        public const string NandPath   = "nand";
+        public const string SdCardPath = "sdmc";
+        public const string SystemPath = "system";
+
+        public static string SystemNandPath = Path.Combine(NandPath, "system");
+        public static string UserNandPath   = Path.Combine(NandPath, "user");
 
         public Stream RomFs { get; private set; }
 
@@ -50,10 +54,15 @@ namespace Ryujinx.HLE
 
         public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
 
-        public string GetGameSavesPath() => MakeDirAndGetFullPath(NandPath);
+        public string GetNandPath() => MakeDirAndGetFullPath(NandPath);
 
         public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);
 
+        public string GetGameSavePath(SaveInfo Save, ServiceCtx Context)
+        {
+            return MakeDirAndGetFullPath(SaveHelper.GetSavePath(Save, Context));
+        }
+
         public string SwitchPathToSystemPath(string SwitchPath)
         {
             string[] Parts = SwitchPath.Split(":");
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index 92a87661df..2e216cdf18 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -109,7 +109,7 @@ namespace Ryujinx.HLE.HOS
                 }
             }
 
-            if (!MainProcess.MetaData.Is64Bits)
+            if (!(MainProcess.MetaData?.Is64Bits ?? true))
             {
                 throw new NotImplementedException("32-bit titles are unsupported!");
             }
diff --git a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs
index 14edcc759e..937ea6d6bf 100644
--- a/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs
+++ b/Ryujinx.HLE/HOS/Services/FspSrv/IFileSystemProxy.cs
@@ -1,5 +1,6 @@
+using Ryujinx.HLE.FileSystem;
 using Ryujinx.HLE.HOS.Ipc;
-using Ryujinx.HLE.Logging;
+using Ryujinx.HLE.HOS.SystemState;
 using System.Collections.Generic;
 
 namespace Ryujinx.HLE.HOS.Services.FspSrv
@@ -14,13 +15,13 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 1,    SetCurrentProcess                    },
-                { 18,   OpenSdCardFileSystem                 },
-                { 22,   CreateSaveDataFileSystem             },
-                { 51,   OpenSaveDataFileSystem               },
-                { 200,  OpenDataStorageByCurrentProcess      },
-                { 203,  OpenPatchDataStorageByCurrentProcess },
-                { 1005, GetGlobalAccessLogMode               }
+                { 1,    SetCurrentProcess                        },
+                { 18,   OpenSdCardFileSystem                     },
+                { 51,   OpenSaveDataFileSystem                   },
+                { 52,   OpenSaveDataFileSystemBySystemSaveDataId },
+                { 200,  OpenDataStorageByCurrentProcess          },
+                { 203,  OpenPatchDataStorageByCurrentProcess     },
+                { 1005, GetGlobalAccessLogMode                   }
             };
         }
 
@@ -36,16 +37,16 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
             return 0;
         }
 
-        public long CreateSaveDataFileSystem(ServiceCtx Context)
+        public long OpenSaveDataFileSystem(ServiceCtx Context)
         {
-            Context.Device.Log.PrintStub(LogClass.ServiceFs, "Stubbed.");
+            LoadSaveDataFileSystem(Context);
 
             return 0;
         }
 
-        public long OpenSaveDataFileSystem(ServiceCtx Context)
+        public long OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx Context)
         {
-            MakeObject(Context, new IFileSystem(Context.Device.FileSystem.GetGameSavesPath()));
+            LoadSaveDataFileSystem(Context);
 
             return 0;
         }
@@ -70,5 +71,24 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
 
             return 0;
         }
+
+        public void LoadSaveDataFileSystem(ServiceCtx Context)
+        {
+            SaveSpaceId SaveSpaceId = (SaveSpaceId)Context.RequestData.ReadInt64();
+
+            long TitleId = Context.RequestData.ReadInt64();
+
+            UserId UserId = new UserId(
+                Context.RequestData.ReadInt64(), 
+                Context.RequestData.ReadInt64());
+
+            long SaveId = Context.RequestData.ReadInt64();
+
+            SaveDataType SaveDataType = (SaveDataType)Context.RequestData.ReadByte();
+
+            SaveInfo SaveInfo = new SaveInfo(TitleId, SaveId, SaveDataType, UserId, SaveSpaceId);
+
+            MakeObject(Context, new IFileSystem(Context.Device.FileSystem.GetGameSavePath(SaveInfo, Context)));
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs
index 090aae111e..70bd7060ec 100644
--- a/Ryujinx.HLE/Switch.cs
+++ b/Ryujinx.HLE/Switch.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Audio;
 using Ryujinx.Graphics;
 using Ryujinx.Graphics.Gal;
+using Ryujinx.HLE.FileSystem;
 using Ryujinx.HLE.HOS;
 using Ryujinx.HLE.Input;
 using Ryujinx.HLE.Logging;