IOPBios: Differentiate ioman and iomanx dread & getStat HLE

Structure differences with fio_stat_t and fxio_stat_t make them incompatible
This commit is contained in:
Ty Lamontagne 2022-09-17 15:59:37 -04:00 committed by refractionpcsx2
parent 4ad563f8fc
commit 435b5a2b27
2 changed files with 136 additions and 49 deletions

View File

@ -56,6 +56,18 @@ typedef struct
unsigned char mtime[8]; unsigned char mtime[8];
unsigned int hisize; unsigned int hisize;
} fio_stat_t; } 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 typedef struct
{ {
@ -64,6 +76,13 @@ typedef struct
unsigned int unknown; unsigned int unknown;
} fio_dirent_t; } fio_dirent_t;
typedef struct
{
fxio_stat_t stat;
char name[256];
unsigned int unknown;
} fxio_dirent_t;
static std::string hostRoot; static std::string hostRoot;
void Hle_SetElfPath(const char* elfFileName) void Hle_SetElfPath(const char* elfFileName)
@ -201,6 +220,11 @@ namespace R3000A
return 0; 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 // TODO: sandbox option, other permissions
class HostFile : public IOManFile class HostFile : public IOManFile
{ {
@ -347,14 +371,23 @@ namespace R3000A
return 0; 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()) if (dir == results.end())
return 0; return 0;
if (iomanX)
{
fxio_dirent_t* hostcontent = (fxio_dirent_t*)buf;
StringUtil::Strlcpy(hostcontent->name, dir->FileName, sizeof(hostcontent->name)); StringUtil::Strlcpy(hostcontent->name, dir->FileName, sizeof(hostcontent->name));
host_stat(host_path(Path::Combine(basedir, dir->FileName), true), &hostcontent->stat); 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); dir = std::next(dir);
return 1; return 1;
@ -591,11 +624,26 @@ namespace R3000A
return 0; return 0;
} }
int dread_HLE() int _dread_HLE(bool iomanX)
{ {
s32 fh = a0; s32 fh = a0;
u32 data = a1; u32 data = a1;
if (iomanX)
{
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(fxio_dirent_t); i++)
iopMemWrite8(data + i, buf[i]);
pc = ra;
return 1;
}
}
else
{
if (IOManDir* dir = getfd<IOManDir>(fh)) if (IOManDir* dir = getfd<IOManDir>(fh))
{ {
char buf[sizeof(fio_dirent_t)]; char buf[sizeof(fio_dirent_t)];
@ -607,11 +655,21 @@ namespace R3000A
pc = ra; pc = ra;
return 1; return 1;
} }
}
return 0; return 0;
} }
int getStat_HLE() 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); const std::string path = clean_path(Ra0);
u32 data = a1; u32 data = a1;
@ -619,12 +677,22 @@ namespace R3000A
if (is_host(path)) if (is_host(path))
{ {
const std::string full_path = host_path(path.substr(path.find(':') + 1), true); 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)]; char buf[sizeof(fio_stat_t)];
v0 = host_stat(full_path, (fio_stat_t*)&buf); v0 = host_stat(full_path, (fio_stat_t*)&buf);
for (s32 i = 0; i < (s32)sizeof(fio_stat_t); i++) for (size_t i = 0; i < sizeof(fio_stat_t); i++)
iopMemWrite8(data + i, buf[i]); iopMemWrite8(data + i, buf[i]);
}
pc = ra; pc = ra;
return 1; return 1;
} }
@ -632,6 +700,16 @@ namespace R3000A
return 0; return 0;
} }
int getStat_HLE()
{
return _getStat_HLE(false);
}
int getStatx_HLE()
{
return _getStat_HLE(true);
}
int lseek_HLE() int lseek_HLE()
{ {
s32 fd = a0; s32 fd = a0;
@ -964,12 +1042,6 @@ namespace R3000A
using namespace n; \ using namespace n; \
switch (index) \ switch (index) \
{ {
#define MODULE_2(n1, n2) \
if (#n1 == libname || #n2 == libname) \
{ \
using namespace n1; \
switch (index) \
{
#define END_MODULE \ #define END_MODULE \
} \ } \
} }
@ -989,7 +1061,14 @@ namespace R3000A
EXPORT_H( 14, Kprintf) EXPORT_H( 14, Kprintf)
END_MODULE END_MODULE
MODULE_2(ioman, iomanx) // 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( 4, open)
EXPORT_H( 5, close) EXPORT_H( 5, close)
EXPORT_H( 6, read) EXPORT_H( 6, read)
@ -1000,11 +1079,19 @@ namespace R3000A
EXPORT_H( 12, rmdir) EXPORT_H( 12, rmdir)
EXPORT_H( 13, dopen) EXPORT_H( 13, dopen)
EXPORT_H( 14, dclose) EXPORT_H( 14, dclose)
EXPORT_H( 15, dread) case 15: // dread
EXPORT_H( 16, getStat) if(use_ioman)
END_MODULE return dread_HLE;
else
return dreadx_HLE;
case 16: // getStat
if(use_ioman)
return getStat_HLE;
else
return getStatx_HLE;
}
}
// clang-format on // clang-format on
return 0; return 0;
} }

View File

@ -63,7 +63,7 @@ public:
virtual void close() = 0; 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 typedef int (*irxHLE)(); // return 1 if handled, otherwise 0