diff --git a/CMakeLists.txt b/CMakeLists.txt
index 45b4971a69..f4c018c551 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1425,6 +1425,7 @@ if(UNITTEST)
unittest/TestVertexJit.h
unittest/TestVFS.cpp
unittest/TestZipSlip.cpp
+ unittest/TestPS1Eboot.cpp
unittest/TestLzrc.cpp
unittest/TestCwCheat.cpp
unittest/TestMpegCsc.cpp
diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt
index 9a585939ae..c5d74a0f96 100644
--- a/Core/CMakeLists.txt
+++ b/Core/CMakeLists.txt
@@ -612,6 +612,8 @@ add_library(Core STATIC
FileLoaders/HTTPFileLoader.h
FileLoaders/LocalFileLoader.cpp
FileLoaders/LocalFileLoader.h
+ FileLoaders/PS1EbootFileLoader.cpp
+ FileLoaders/PS1EbootFileLoader.h
FileLoaders/RamCachingFileLoader.cpp
FileLoaders/RamCachingFileLoader.h
FileLoaders/RetryingFileLoader.cpp
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 4098967edf..010a5d2ea2 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -587,6 +587,7 @@
+
@@ -931,6 +932,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index a0b8550a09..4556eb843d 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -619,6 +619,9 @@
FileLoaders
+
+ FileLoaders
+
FileLoaders
@@ -1978,6 +1981,9 @@
FileLoaders
+
+ FileLoaders
+
FileLoaders
diff --git a/Core/ELF/ParamSFO.cpp b/Core/ELF/ParamSFO.cpp
index d5c010f1b7..3a7745af14 100644
--- a/Core/ELF/ParamSFO.cpp
+++ b/Core/ELF/ParamSFO.cpp
@@ -473,6 +473,16 @@ GameRegion DetectGameRegionFromID(std::string_view id_full) {
* 'X' -> first-party Minis
* 'Z' -> third-party Minis
*/
+ } else if (id_letters[0] == 'S' && (id_letters[1] == 'L' || id_letters[1] == 'C' || id_letters[1] == 'I')) {
+ // PS1 discs: (S)ony, then (L)icensed, (C)opyrighted or (I)nternational, then the region.
+ switch (id_letters[2]) {
+ case 'U': return GameRegion::USA;
+ case 'E': return GameRegion::EUROPE;
+ case 'P': return GameRegion::JAPAN;
+ case 'K': return GameRegion::KOREA;
+ case 'A': return GameRegion::ASIA;
+ default: break;
+ }
// Misc patterns
} else if (id_letters == "UTST") {
return GameRegion::TEST;
diff --git a/Core/FileLoaders/PS1EbootFileLoader.cpp b/Core/FileLoaders/PS1EbootFileLoader.cpp
new file mode 100644
index 0000000000..36b22bae30
--- /dev/null
+++ b/Core/FileLoaders/PS1EbootFileLoader.cpp
@@ -0,0 +1,1053 @@
+// Copyright (c) 2012- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#include
+#include
+#include