diff --git a/pcsx2/IopBios.cpp b/pcsx2/IopBios.cpp
index 2b38a3f703..c070988fd5 100644
--- a/pcsx2/IopBios.cpp
+++ b/pcsx2/IopBios.cpp
@@ -56,6 +56,18 @@ typedef struct
 	unsigned char mtime[8];
 	unsigned int hisize;
 } fio_stat_t;
+typedef struct
+{
+	fio_stat_t _fioStat;
+	/** Number of subs (main) / subpart number (sub) */
+	unsigned int private_0;
+	unsigned int private_1;
+	unsigned int private_2;
+	unsigned int private_3;
+	unsigned int private_4;
+	/** Sector start.  */
+	unsigned int private_5;
+} fxio_stat_t;
 
 typedef struct
 {
@@ -64,6 +76,13 @@ typedef struct
 	unsigned int unknown;
 } fio_dirent_t;
 
+typedef struct
+{
+	fxio_stat_t stat;
+	char name[256];
+	unsigned int unknown;
+} fxio_dirent_t;
+
 static std::string hostRoot;
 
 void Hle_SetElfPath(const char* elfFileName)
@@ -201,6 +220,11 @@ namespace R3000A
 		return 0;
 	}
 
+	static int host_stat(const std::string path, fxio_stat_t* host_stats)
+	{
+		return host_stat(path, &host_stats->_fioStat);
+	}
+
 	// TODO: sandbox option, other permissions
 	class HostFile : public IOManFile
 	{
@@ -347,14 +371,23 @@ namespace R3000A
 			return 0;
 		}
 
-		virtual int read(void* buf) /* Flawfinder: ignore */
+		virtual int read(void* buf, bool iomanX) /* Flawfinder: ignore */
 		{
-			fio_dirent_t* hostcontent = (fio_dirent_t*)buf;
 			if (dir == results.end())
 				return 0;
 
-			StringUtil::Strlcpy(hostcontent->name, dir->FileName, sizeof(hostcontent->name));
-			host_stat(host_path(Path::Combine(basedir, dir->FileName), true), &hostcontent->stat);
+			if (iomanX)
+			{
+				fxio_dirent_t* hostcontent = (fxio_dirent_t*)buf;
+				StringUtil::Strlcpy(hostcontent->name, dir->FileName, sizeof(hostcontent->name));
+				host_stat(host_path(Path::Combine(basedir, dir->FileName), true), &hostcontent->stat);
+			}
+			else
+			{
+				fio_dirent_t* hostcontent = (fio_dirent_t*)buf;
+				StringUtil::Strlcpy(hostcontent->name, dir->FileName, sizeof(hostcontent->name));
+				host_stat(host_path(Path::Combine(basedir, dir->FileName), true), &hostcontent->stat);
+			}
 
 			dir = std::next(dir);
 			return 1;
@@ -591,19 +624,75 @@ namespace R3000A
 			return 0;
 		}
 
-		int dread_HLE()
+		int _dread_HLE(bool iomanX)
 		{
 			s32 fh = a0;
 			u32 data = a1;
-
-			if (IOManDir* dir = getfd<IOManDir>(fh))
+			if (iomanX)
 			{
-				char buf[sizeof(fio_dirent_t)];
-				v0 = dir->read(&buf); /* Flawfinder: ignore */
+				if (IOManDir* dir = getfd<IOManDir>(fh))
+				{
+					char buf[sizeof(fxio_dirent_t)];
+					v0 = dir->read(&buf, iomanX); /* Flawfinder: ignore */
 
-				for (s32 i = 0; i < (s32)sizeof(fio_dirent_t); i++)
-					iopMemWrite8(data + i, buf[i]);
+					for (s32 i = 0; i < (s32)sizeof(fxio_dirent_t); i++)
+						iopMemWrite8(data + i, buf[i]);
 
+					pc = ra;
+					return 1;
+				}
+			}
+			else
+			{
+				if (IOManDir* dir = getfd<IOManDir>(fh))
+				{
+					char buf[sizeof(fio_dirent_t)];
+					v0 = dir->read(&buf); /* Flawfinder: ignore */
+
+					for (s32 i = 0; i < (s32)sizeof(fio_dirent_t); i++)
+						iopMemWrite8(data + i, buf[i]);
+
+					pc = ra;
+					return 1;
+				}
+			}
+			return 0;
+		}
+
+		int dread_HLE()
+		{
+			return _dread_HLE(false);
+		}
+
+		int dreadx_HLE()
+		{
+			return _dread_HLE(true);
+		}
+
+		int _getStat_HLE(bool iomanx)
+		{
+			const std::string path = clean_path(Ra0);
+			u32 data = a1;
+
+			if (is_host(path))
+			{
+				const std::string full_path = host_path(path.substr(path.find(':') + 1), true);
+				if (iomanx)
+				{
+					char buf[sizeof(fxio_stat_t)];
+					v0 = host_stat(full_path, (fxio_stat_t*)&buf);
+
+					for (size_t i = 0; i < sizeof(fxio_stat_t); i++)
+						iopMemWrite8(data + i, buf[i]);
+				}
+				else
+				{
+					char buf[sizeof(fio_stat_t)];
+					v0 = host_stat(full_path, (fio_stat_t*)&buf);
+
+					for (size_t i = 0; i < sizeof(fio_stat_t); i++)
+						iopMemWrite8(data + i, buf[i]);
+				}
 				pc = ra;
 				return 1;
 			}
@@ -613,23 +702,12 @@ namespace R3000A
 
 		int getStat_HLE()
 		{
-			const std::string path = clean_path(Ra0);
-			u32 data = a1;
+			return _getStat_HLE(false);
+		}
 
-			if (is_host(path))
-			{
-				const std::string full_path = host_path(path.substr(path.find(':') + 1), true);
-				char buf[sizeof(fio_stat_t)];
-				v0 = host_stat(full_path, (fio_stat_t*)&buf);
-
-				for (s32 i = 0; i < (s32)sizeof(fio_stat_t); i++)
-					iopMemWrite8(data + i, buf[i]);
-
-				pc = ra;
-				return 1;
-			}
-
-			return 0;
+		int getStatx_HLE()
+		{
+			return _getStat_HLE(true);
 		}
 
 		int lseek_HLE()
@@ -964,12 +1042,6 @@ namespace R3000A
 		using namespace n; \
 		switch (index)     \
 		{
-#define MODULE_2(n1, n2)          \
-	if (#n1 == libname || #n2 == libname)     \
-	{                      \
-		using namespace n1; \
-		switch (index)     \
-		{
 #define END_MODULE \
 	}              \
 	}
@@ -989,22 +1061,37 @@ namespace R3000A
 			EXPORT_H( 14, Kprintf)
 		END_MODULE
 
-		MODULE_2(ioman, iomanx)
-			EXPORT_H(  4, open)
-			EXPORT_H(  5, close)
-			EXPORT_H(  6, read)
-			EXPORT_H(  7, write)
-			EXPORT_H(  8, lseek)
-			EXPORT_H( 10, remove)
-			EXPORT_H( 11, mkdir)
-			EXPORT_H( 12, rmdir)
-			EXPORT_H( 13, dopen)
-			EXPORT_H( 14, dclose)
-			EXPORT_H( 15, dread)
-			EXPORT_H( 16, getStat)
-		END_MODULE
+		// Special case with ioman and iomanX
+		// They are mostly compatible excluding stat structures
+		if(libname == "ioman" || libname == "iomanx")
+		{
+			const bool use_ioman = libname == "ioman";
+			using namespace ioman;
+				switch(index)
+				{
+					EXPORT_H(  4, open)
+					EXPORT_H(  5, close)
+					EXPORT_H(  6, read)
+					EXPORT_H(  7, write)
+					EXPORT_H(  8, lseek)
+					EXPORT_H( 10, remove)
+					EXPORT_H( 11, mkdir)
+					EXPORT_H( 12, rmdir)
+					EXPORT_H( 13, dopen)
+					EXPORT_H( 14, dclose)
+					case 15: // dread
+					if(use_ioman)
+						return dread_HLE;
+					else
+						return dreadx_HLE;
+					case 16: // getStat
+					if(use_ioman)
+						return getStat_HLE;
+					else
+						return getStatx_HLE;
+				}
+		}
 		// clang-format on
-
 		return 0;
 	}
 
diff --git a/pcsx2/IopBios.h b/pcsx2/IopBios.h
index 730f013bfb..3e5d47f62e 100644
--- a/pcsx2/IopBios.h
+++ b/pcsx2/IopBios.h
@@ -63,7 +63,7 @@ public:
 
 	virtual void close() = 0;
 
-	virtual int read(void* buf) { return -IOP_EIO; } /* Flawfinder: ignore */
+	virtual int read(void* buf, bool iomanX = false) { return -IOP_EIO; } /* Flawfinder: ignore */
 };
 
 typedef int (*irxHLE)(); // return 1 if handled, otherwise 0