diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3396b64866..6293e25b0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1348,6 +1348,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/ELF/ParamSFO.cpp
Core/ELF/ParamSFO.h
Core/FileSystems/tlzrc.cpp
+ Core/FileSystems/BlobFileSystem.cpp
+ Core/FileSystems/BlobFileSystem.h
Core/FileSystems/BlockDevices.cpp
Core/FileSystems/BlockDevices.h
Core/FileSystems/DirectoryFileSystem.cpp
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index ce2cb5033b..e02438f7f9 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -21,7 +21,8 @@
{533F1D30-D04D-47CC-AD71-20F658907E36}
Core
-
+
+
@@ -183,6 +184,7 @@
+
@@ -524,6 +526,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 234ff2172a..79da4d1df0 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -680,6 +680,9 @@
HLE\Libraries
+
+ FileSystems
+
@@ -1250,10 +1253,13 @@
HLE\Libraries
+
+ FileSystems
+
-
+
\ No newline at end of file
diff --git a/Core/FileSystems/BlobFileSystem.cpp b/Core/FileSystems/BlobFileSystem.cpp
new file mode 100644
index 0000000000..059e79199f
--- /dev/null
+++ b/Core/FileSystems/BlobFileSystem.cpp
@@ -0,0 +1,137 @@
+// Copyright (c) 2017- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#include "Core/FileSystems/BlobFileSystem.h"
+
+BlobFileSystem::BlobFileSystem(IHandleAllocator *hAlloc, FileLoader *fileLoader, std::string alias)
+: alloc_(hAlloc), fileLoader_(fileLoader), alias_(alias) {
+}
+
+BlobFileSystem::~BlobFileSystem() {
+ // TODO: Who deletes fileLoader?
+}
+
+void BlobFileSystem::DoState(PointerWrap &p) {
+ // Not used in real emulation.
+}
+
+std::vector BlobFileSystem::GetDirListing(std::string path) {
+ std::vector listing;
+ listing.push_back(GetFileInfo(alias_));
+ return listing;
+}
+
+u32 BlobFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename) {
+ u32 newHandle = alloc_->GetNewHandle();
+ entries_[newHandle] = 0;
+ return newHandle;
+}
+
+void BlobFileSystem::CloseFile(u32 handle) {
+ alloc_->FreeHandle(handle);
+ entries_.erase(handle);
+}
+
+size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) {
+ auto entry = entries_.find(handle);
+ if (entry != entries_.end()) {
+ size_t readSize = fileLoader_->ReadAt(entry->second, size, pointer);
+ entry->second += readSize;
+ return readSize;
+ }
+ return 0;
+}
+
+size_t BlobFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) {
+ usec = 0;
+ return ReadFile(handle, pointer, size);
+}
+
+size_t BlobFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) {
+ return 0;
+}
+
+size_t BlobFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size, int &usec) {
+ return 0;
+}
+
+size_t BlobFileSystem::SeekFile(u32 handle, s32 position, FileMove type) {
+ auto entry = entries_.find(handle);
+ if (entry != entries_.end()) {
+ switch (type) {
+ case FILEMOVE_BEGIN:
+ entry->second = position;
+ break;
+ case FILEMOVE_CURRENT:
+ entry->second += position;
+ break;
+ case FILEMOVE_END:
+ entry->second = fileLoader_->FileSize() + position;
+ break;
+ }
+ return (size_t)entry->second;
+ }
+ return 0;
+}
+
+PSPFileInfo BlobFileSystem::GetFileInfo(std::string filename) {
+ PSPFileInfo info{};
+ info.name = alias_;
+ info.size = fileLoader_->FileSize();
+ info.access = 0666;
+ info.exists = true;
+ info.type = FILETYPE_NORMAL;
+ return info;
+}
+
+bool BlobFileSystem::OwnsHandle(u32 handle) {
+ auto entry = entries_.find(handle);
+ return entry != entries_.end();
+}
+
+int BlobFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen, int &usec) {
+ return -1;
+}
+
+int BlobFileSystem::DevType(u32 handle) {
+ return -1;
+}
+
+bool BlobFileSystem::MkDir(const std::string &dirname) {
+ return false;
+}
+
+bool BlobFileSystem::RmDir(const std::string &dirname) {
+ return false;
+}
+
+int BlobFileSystem::RenameFile(const std::string &from, const std::string &to) {
+ return -1;
+}
+
+bool BlobFileSystem::RemoveFile(const std::string &filename) {
+ return false;
+}
+
+bool BlobFileSystem::GetHostPath(const std::string &inpath, std::string &outpath) {
+ outpath = fileLoader_->Path();
+ return true;
+}
+
+u64 BlobFileSystem::FreeSpace(const std::string &path) {
+ return 0;
+}
diff --git a/Core/FileSystems/BlobFileSystem.h b/Core/FileSystems/BlobFileSystem.h
new file mode 100644
index 0000000000..c26f596dee
--- /dev/null
+++ b/Core/FileSystems/BlobFileSystem.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2017- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#pragma once
+
+// This is used for opening a debug file as a blob, and mounting it.
+
+#include