mirror of https://github.com/PCSX2/pcsx2.git
clang-format: pcsx2/IopBios.h and pcsx2/IopBios.cpp
This commit is contained in:
parent
4bf3819778
commit
4402bbda55
|
@ -1,5 +1,5 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||||
*
|
*
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
|
@ -26,7 +26,8 @@
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
unsigned int attr;
|
unsigned int attr;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
@ -36,7 +37,8 @@ typedef struct {
|
||||||
unsigned int hisize;
|
unsigned int hisize;
|
||||||
} fio_stat_t;
|
} fio_stat_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
fio_stat_t stat;
|
fio_stat_t stat;
|
||||||
char name[256];
|
char name[256];
|
||||||
unsigned int unknown;
|
unsigned int unknown;
|
||||||
|
@ -48,42 +50,44 @@ void Hle_SetElfPath(const char* elfFileName)
|
||||||
{
|
{
|
||||||
DevCon.WriteLn("HLE Host: Will load ELF: %s\n", elfFileName);
|
DevCon.WriteLn("HLE Host: Will load ELF: %s\n", elfFileName);
|
||||||
|
|
||||||
const char* pos1 = strrchr(elfFileName,'/');
|
const char* pos1 = strrchr(elfFileName, '/');
|
||||||
const char* pos2 = strrchr(elfFileName,'\\');
|
const char* pos2 = strrchr(elfFileName, '\\');
|
||||||
|
|
||||||
if(pos2 > pos1) // we want the LAST path separator
|
if (pos2 > pos1) // we want the LAST path separator
|
||||||
pos1=pos2;
|
pos1 = pos2;
|
||||||
|
|
||||||
if(!pos1) // if pos1 is NULL, then pos2 was not > pos1, so it must also be NULL
|
if (!pos1) // if pos1 is NULL, then pos2 was not > pos1, so it must also be NULL
|
||||||
{
|
{
|
||||||
Console.WriteLn("HLE Notice: ELF does not have a path.\n");
|
Console.WriteLn("HLE Notice: ELF does not have a path.\n");
|
||||||
|
|
||||||
// use %CD%/host/
|
// use %CD%/host/
|
||||||
char* cwd = getcwd(HostRoot,1000); // save the other 23 chars to append /host/ :P
|
char* cwd = getcwd(HostRoot, 1000); // save the other 23 chars to append /host/ :P
|
||||||
HostRoot[1000]=0; // Be Safe.
|
HostRoot[1000] = 0; // Be Safe.
|
||||||
if (cwd == nullptr) {
|
if (cwd == nullptr)
|
||||||
|
{
|
||||||
Console.Error("Hle_SetElfPath: getcwd: buffer is too small");
|
Console.Error("Hle_SetElfPath: getcwd: buffer is too small");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* last = HostRoot + strlen(HostRoot) - 1;
|
char* last = HostRoot + strlen(HostRoot) - 1;
|
||||||
|
|
||||||
if((*last!='/') && (*last!='\\')) // PathAppend()-ish
|
if ((*last != '/') && (*last != '\\')) // PathAppend()-ish
|
||||||
last++;
|
last++;
|
||||||
|
|
||||||
strcpy(last,"/host/");
|
strcpy(last, "/host/");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = pos1-elfFileName+1;
|
int len = pos1 - elfFileName + 1;
|
||||||
memcpy(HostRoot,elfFileName,len); // include the / (or \\)
|
memcpy(HostRoot, elfFileName, len); // include the / (or \\)
|
||||||
HostRoot[len] = 0;
|
HostRoot[len] = 0;
|
||||||
|
|
||||||
Console.WriteLn("HLE Host: Set 'host:' root path to: %s\n", HostRoot);
|
Console.WriteLn("HLE Host: Set 'host:' root path to: %s\n", HostRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace R3000A {
|
namespace R3000A
|
||||||
|
{
|
||||||
|
|
||||||
#define v0 (psxRegs.GPR.n.v0)
|
#define v0 (psxRegs.GPR.n.v0)
|
||||||
#define a0 (psxRegs.GPR.n.a0)
|
#define a0 (psxRegs.GPR.n.a0)
|
||||||
|
@ -107,18 +111,18 @@ namespace R3000A {
|
||||||
#define FIO_SO_IFREG 0x0010
|
#define FIO_SO_IFREG 0x0010
|
||||||
#define FIO_SO_IFDIR 0x0020
|
#define FIO_SO_IFDIR 0x0020
|
||||||
|
|
||||||
static std::string host_path(const std::string path)
|
static std::string host_path(const std::string path)
|
||||||
{
|
{
|
||||||
// We are NOT allowing to use the root of the host unit.
|
// We are NOT allowing to use the root of the host unit.
|
||||||
// For now it just supports relative folders from the location of the elf
|
// For now it just supports relative folders from the location of the elf
|
||||||
if (path.rfind(HostRoot, 0) == 0)
|
if (path.rfind(HostRoot, 0) == 0)
|
||||||
return path;
|
return path;
|
||||||
else // relative paths
|
else // relative paths
|
||||||
return HostRoot + path;
|
return HostRoot + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int host_stat(const std::string path, fio_stat_t *host_stats)
|
static int host_stat(const std::string path, fio_stat_t* host_stats)
|
||||||
{
|
{
|
||||||
struct stat file_stats;
|
struct stat file_stats;
|
||||||
|
|
||||||
if (::stat(path.c_str(), &file_stats))
|
if (::stat(path.c_str(), &file_stats))
|
||||||
|
@ -130,13 +134,22 @@ static int host_stat(const std::string path, fio_stat_t *host_stats)
|
||||||
// Convert the mode.
|
// Convert the mode.
|
||||||
host_stats->mode = (file_stats.st_mode & (FIO_SO_IROTH | FIO_SO_IWOTH | FIO_SO_IXOTH));
|
host_stats->mode = (file_stats.st_mode & (FIO_SO_IROTH | FIO_SO_IWOTH | FIO_SO_IXOTH));
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (S_ISLNK(file_stats.st_mode)) { host_stats->mode |= FIO_SO_IFLNK; }
|
if (S_ISLNK(file_stats.st_mode))
|
||||||
|
{
|
||||||
|
host_stats->mode |= FIO_SO_IFLNK;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (S_ISREG(file_stats.st_mode)) { host_stats->mode |= FIO_SO_IFREG; }
|
if (S_ISREG(file_stats.st_mode))
|
||||||
if (S_ISDIR(file_stats.st_mode)) { host_stats->mode |= FIO_SO_IFDIR; }
|
{
|
||||||
|
host_stats->mode |= FIO_SO_IFREG;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(file_stats.st_mode))
|
||||||
|
{
|
||||||
|
host_stats->mode |= FIO_SO_IFDIR;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the creation time.
|
// Convert the creation time.
|
||||||
struct tm *loctime;
|
struct tm* loctime;
|
||||||
loctime = localtime(&(file_stats.st_ctime));
|
loctime = localtime(&(file_stats.st_ctime));
|
||||||
host_stats->ctime[6] = (unsigned char)loctime->tm_year;
|
host_stats->ctime[6] = (unsigned char)loctime->tm_year;
|
||||||
host_stats->ctime[5] = (unsigned char)loctime->tm_mon + 1;
|
host_stats->ctime[5] = (unsigned char)loctime->tm_mon + 1;
|
||||||
|
@ -164,12 +177,12 @@ static int host_stat(const std::string path, fio_stat_t *host_stats)
|
||||||
host_stats->mtime[1] = (unsigned char)loctime->tm_sec;
|
host_stats->mtime[1] = (unsigned char)loctime->tm_sec;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sandbox option, other permissions
|
// TODO: sandbox option, other permissions
|
||||||
class HostFile : public IOManFile
|
class HostFile : public IOManFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
HostFile(int hostfd)
|
HostFile(int hostfd)
|
||||||
|
@ -184,7 +197,7 @@ public:
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
switch(err)
|
switch (err)
|
||||||
{
|
{
|
||||||
case -ENOENT:
|
case -ENOENT:
|
||||||
return -IOP_ENOENT;
|
return -IOP_ENOENT;
|
||||||
|
@ -198,22 +211,31 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open(IOManFile **file, const std::string &full_path, s32 flags, u16 mode)
|
static int open(IOManFile** file, const std::string& full_path, s32 flags, u16 mode)
|
||||||
{
|
{
|
||||||
const std::string path = full_path.substr(full_path.find(':') + 1);
|
const std::string path = full_path.substr(full_path.find(':') + 1);
|
||||||
int native_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; // 0644
|
int native_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644
|
||||||
int native_flags = O_BINARY; // necessary in Windows.
|
int native_flags = O_BINARY; // necessary in Windows.
|
||||||
|
|
||||||
switch(flags&IOP_O_RDWR)
|
switch (flags & IOP_O_RDWR)
|
||||||
{
|
{
|
||||||
case IOP_O_RDONLY: native_flags |= O_RDONLY; break;
|
case IOP_O_RDONLY:
|
||||||
case IOP_O_WRONLY: native_flags |= O_WRONLY; break;
|
native_flags |= O_RDONLY;
|
||||||
case IOP_O_RDWR: native_flags |= O_RDWR; break;
|
break;
|
||||||
|
case IOP_O_WRONLY:
|
||||||
|
native_flags |= O_WRONLY;
|
||||||
|
break;
|
||||||
|
case IOP_O_RDWR:
|
||||||
|
native_flags |= O_RDWR;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags&IOP_O_APPEND) native_flags |= O_APPEND;
|
if (flags & IOP_O_APPEND)
|
||||||
if(flags&IOP_O_CREAT) native_flags |= O_CREAT;
|
native_flags |= O_APPEND;
|
||||||
if(flags&IOP_O_TRUNC) native_flags |= O_TRUNC;
|
if (flags & IOP_O_CREAT)
|
||||||
|
native_flags |= O_CREAT;
|
||||||
|
if (flags & IOP_O_TRUNC)
|
||||||
|
native_flags |= O_TRUNC;
|
||||||
|
|
||||||
int hostfd = ::open(host_path(path).data(), native_flags, native_mode);
|
int hostfd = ::open(host_path(path).data(), native_flags, native_mode);
|
||||||
if (hostfd < 0)
|
if (hostfd < 0)
|
||||||
|
@ -254,24 +276,24 @@ public:
|
||||||
return translate_error(err);
|
return translate_error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int read(void *buf, u32 count)
|
virtual int read(void* buf, u32 count)
|
||||||
{
|
{
|
||||||
return translate_error(::read(fd, buf, count));
|
return translate_error(::read(fd, buf, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int write(void *buf, u32 count)
|
virtual int write(void* buf, u32 count)
|
||||||
{
|
{
|
||||||
return translate_error(::write(fd, buf, count));
|
return translate_error(::write(fd, buf, count));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HostDir : public IOManDir
|
class HostDir : public IOManDir
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DIR *dir;
|
DIR* dir;
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
HostDir(DIR *native_dir, const std::string native_path)
|
HostDir(DIR* native_dir, const std::string native_path)
|
||||||
{
|
{
|
||||||
dir = native_dir;
|
dir = native_dir;
|
||||||
path = native_path;
|
path = native_path;
|
||||||
|
@ -284,7 +306,7 @@ public:
|
||||||
const std::string relativePath = full_path.substr(full_path.find(':') + 1);
|
const std::string relativePath = full_path.substr(full_path.find(':') + 1);
|
||||||
const std::string path = host_path(relativePath);
|
const std::string path = host_path(relativePath);
|
||||||
|
|
||||||
DIR *dirent = ::opendir(path.c_str());
|
DIR* dirent = ::opendir(path.c_str());
|
||||||
if (!dirent)
|
if (!dirent)
|
||||||
return -IOP_ENOENT; // Should return ENOTDIR if path is a file?
|
return -IOP_ENOENT; // Should return ENOTDIR if path is a file?
|
||||||
|
|
||||||
|
@ -295,10 +317,10 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int read(void *buf)
|
virtual int read(void* buf)
|
||||||
{
|
{
|
||||||
fio_dirent_t *hostcontent = (fio_dirent_t *)buf;
|
fio_dirent_t* hostcontent = (fio_dirent_t*)buf;
|
||||||
struct dirent *dire = ::readdir(dir);
|
struct dirent* dire = ::readdir(dir);
|
||||||
|
|
||||||
if (dire == NULL)
|
if (dire == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -314,10 +336,10 @@ public:
|
||||||
::closedir(dir);
|
::closedir(dir);
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
};
|
namespace ioman
|
||||||
|
{
|
||||||
namespace ioman {
|
|
||||||
const int firstfd = 0x100;
|
const int firstfd = 0x100;
|
||||||
const int maxfds = 0x100;
|
const int maxfds = 0x100;
|
||||||
int openfds = 0;
|
int openfds = 0;
|
||||||
|
@ -329,22 +351,38 @@ namespace ioman {
|
||||||
|
|
||||||
struct filedesc
|
struct filedesc
|
||||||
{
|
{
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
FILE_FREE,
|
FILE_FREE,
|
||||||
FILE_FILE,
|
FILE_FILE,
|
||||||
FILE_DIR,
|
FILE_DIR,
|
||||||
} type;
|
} type;
|
||||||
union {
|
union
|
||||||
IOManFile *file;
|
{
|
||||||
IOManDir *dir;
|
IOManFile* file;
|
||||||
|
IOManDir* dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr filedesc(): type(FILE_FREE), file(nullptr) {}
|
constexpr filedesc()
|
||||||
|
: type(FILE_FREE)
|
||||||
|
, file(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
operator bool() const { return type != FILE_FREE; }
|
operator bool() const { return type != FILE_FREE; }
|
||||||
operator IOManFile*() const { return type == FILE_FILE ? file : NULL; }
|
operator IOManFile*() const { return type == FILE_FILE ? file : NULL; }
|
||||||
operator IOManDir*() const { return type == FILE_DIR ? dir : NULL; }
|
operator IOManDir*() const { return type == FILE_DIR ? dir : NULL; }
|
||||||
void operator=(IOManFile *f) { type = FILE_FILE; file = f; openfds++; }
|
void operator=(IOManFile* f)
|
||||||
void operator=(IOManDir *d) { type = FILE_DIR; dir = d; openfds++; }
|
{
|
||||||
|
type = FILE_FILE;
|
||||||
|
file = f;
|
||||||
|
openfds++;
|
||||||
|
}
|
||||||
|
void operator=(IOManDir* d)
|
||||||
|
{
|
||||||
|
type = FILE_DIR;
|
||||||
|
dir = d;
|
||||||
|
openfds++;
|
||||||
|
}
|
||||||
|
|
||||||
void close()
|
void close()
|
||||||
{
|
{
|
||||||
|
@ -369,7 +407,7 @@ namespace ioman {
|
||||||
|
|
||||||
filedesc fds[maxfds];
|
filedesc fds[maxfds];
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T* getfd(int fd)
|
T* getfd(int fd)
|
||||||
{
|
{
|
||||||
fd -= firstfd;
|
fd -= firstfd;
|
||||||
|
@ -381,7 +419,7 @@ namespace ioman {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int allocfd(T *obj)
|
int allocfd(T* obj)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < maxfds; i++)
|
for (int i = 0; i < maxfds; i++)
|
||||||
{
|
{
|
||||||
|
@ -426,7 +464,7 @@ namespace ioman {
|
||||||
|
|
||||||
int open_HLE()
|
int open_HLE()
|
||||||
{
|
{
|
||||||
IOManFile *file = NULL;
|
IOManFile* file = NULL;
|
||||||
const std::string path = Ra0;
|
const std::string path = Ra0;
|
||||||
s32 flags = a1;
|
s32 flags = a1;
|
||||||
u16 mode = a2;
|
u16 mode = a2;
|
||||||
|
@ -481,7 +519,7 @@ namespace ioman {
|
||||||
|
|
||||||
int dopen_HLE()
|
int dopen_HLE()
|
||||||
{
|
{
|
||||||
IOManDir *dir = NULL;
|
IOManDir* dir = NULL;
|
||||||
const std::string path = Ra0;
|
const std::string path = Ra0;
|
||||||
|
|
||||||
int err = HostDir::open(&dir, path);
|
int err = HostDir::open(&dir, path);
|
||||||
|
@ -525,7 +563,7 @@ namespace ioman {
|
||||||
s32 fh = a0;
|
s32 fh = a0;
|
||||||
u32 data = a1;
|
u32 data = a1;
|
||||||
|
|
||||||
if (IOManDir *dir = getfd<IOManDir>(fh))
|
if (IOManDir* dir = getfd<IOManDir>(fh))
|
||||||
{
|
{
|
||||||
std::unique_ptr<char[]> buf(new char[sizeof(fio_dirent_t)]);
|
std::unique_ptr<char[]> buf(new char[sizeof(fio_dirent_t)]);
|
||||||
v0 = dir->read(buf.get());
|
v0 = dir->read(buf.get());
|
||||||
|
@ -549,7 +587,7 @@ namespace ioman {
|
||||||
{
|
{
|
||||||
const std::string full_path = host_path(path.substr(path.find(':') + 1));
|
const std::string full_path = host_path(path.substr(path.find(':') + 1));
|
||||||
std::unique_ptr<char[]> buf(new char[sizeof(fio_stat_t)]);
|
std::unique_ptr<char[]> buf(new char[sizeof(fio_stat_t)]);
|
||||||
v0 = host_stat(full_path, (fio_stat_t *)buf.get());
|
v0 = host_stat(full_path, (fio_stat_t*)buf.get());
|
||||||
|
|
||||||
for (s32 i = 0; i < (s32)sizeof(fio_stat_t); i++)
|
for (s32 i = 0; i < (s32)sizeof(fio_stat_t); i++)
|
||||||
iopMemWrite8(data + i, buf[i]);
|
iopMemWrite8(data + i, buf[i]);
|
||||||
|
@ -567,7 +605,7 @@ namespace ioman {
|
||||||
s32 offset = a1;
|
s32 offset = a1;
|
||||||
s32 whence = a2;
|
s32 whence = a2;
|
||||||
|
|
||||||
if (IOManFile *file = getfd<IOManFile>(fd))
|
if (IOManFile* file = getfd<IOManFile>(fd))
|
||||||
{
|
{
|
||||||
v0 = file->lseek(offset, whence);
|
v0 = file->lseek(offset, whence);
|
||||||
pc = ra;
|
pc = ra;
|
||||||
|
@ -588,7 +626,7 @@ namespace ioman {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
tmpError = ::mkdir(host_path(path).data());
|
tmpError = ::mkdir(host_path(path).data());
|
||||||
#else
|
#else
|
||||||
tmpError = ::mkdir(host_path(path).data(), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
|
tmpError = ::mkdir(host_path(path).data(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||||
#endif
|
#endif
|
||||||
v0 = HostFile::translate_error(tmpError);
|
v0 = HostFile::translate_error(tmpError);
|
||||||
pc = ra;
|
pc = ra;
|
||||||
|
@ -604,9 +642,10 @@ namespace ioman {
|
||||||
u32 data = a1;
|
u32 data = a1;
|
||||||
u32 count = a2;
|
u32 count = a2;
|
||||||
|
|
||||||
if (IOManFile *file = getfd<IOManFile>(fd))
|
if (IOManFile* file = getfd<IOManFile>(fd))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
std::unique_ptr<char[]> buf(new char[count]);
|
std::unique_ptr<char[]> buf(new char[count]);
|
||||||
|
|
||||||
v0 = file->read(buf.get(), count);
|
v0 = file->read(buf.get(), count);
|
||||||
|
@ -614,7 +653,8 @@ namespace ioman {
|
||||||
for (s32 i = 0; i < (s32)v0; i++)
|
for (s32 i = 0; i < (s32)v0; i++)
|
||||||
iopMemWrite8(data + i, buf[i]);
|
iopMemWrite8(data + i, buf[i]);
|
||||||
}
|
}
|
||||||
catch (const std::bad_alloc &) {
|
catch (const std::bad_alloc&)
|
||||||
|
{
|
||||||
v0 = -IOP_ENOMEM;
|
v0 = -IOP_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,9 +694,10 @@ namespace ioman {
|
||||||
v0 = a2;
|
v0 = a2;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (IOManFile *file = getfd<IOManFile>(fd))
|
else if (IOManFile* file = getfd<IOManFile>(fd))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
std::unique_ptr<char[]> buf(new char[count]);
|
std::unique_ptr<char[]> buf(new char[count]);
|
||||||
|
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 i = 0; i < count; i++)
|
||||||
|
@ -664,7 +705,8 @@ namespace ioman {
|
||||||
|
|
||||||
v0 = file->write(buf.get(), count);
|
v0 = file->write(buf.get(), count);
|
||||||
}
|
}
|
||||||
catch (const std::bad_alloc &) {
|
catch (const std::bad_alloc&)
|
||||||
|
{
|
||||||
v0 = -IOP_ENOMEM;
|
v0 = -IOP_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,9 +716,10 @@ namespace ioman {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace ioman
|
||||||
|
|
||||||
namespace sysmem {
|
namespace sysmem
|
||||||
|
{
|
||||||
int Kprintf_HLE()
|
int Kprintf_HLE()
|
||||||
{
|
{
|
||||||
// Emulate the expected Kprintf functionality:
|
// Emulate the expected Kprintf functionality:
|
||||||
|
@ -692,11 +735,12 @@ namespace sysmem {
|
||||||
// printf-style formatting processing. This part can be skipped if the user has the
|
// printf-style formatting processing. This part can be skipped if the user has the
|
||||||
// console disabled.
|
// console disabled.
|
||||||
|
|
||||||
if (!SysConsole.iopConsole.IsActive()) return 1;
|
if (!SysConsole.iopConsole.IsActive())
|
||||||
|
return 1;
|
||||||
|
|
||||||
char tmp[1024], tmp2[1024];
|
char tmp[1024], tmp2[1024];
|
||||||
char *ptmp = tmp;
|
char* ptmp = tmp;
|
||||||
int n=1, i=0, j = 0;
|
int n = 1, i = 0, j = 0;
|
||||||
|
|
||||||
while (fmt[i])
|
while (fmt[i])
|
||||||
{
|
{
|
||||||
|
@ -705,7 +749,7 @@ namespace sysmem {
|
||||||
case '%':
|
case '%':
|
||||||
j = 0;
|
j = 0;
|
||||||
tmp2[j++] = '%';
|
tmp2[j++] = '%';
|
||||||
_start:
|
_start:
|
||||||
switch (fmt[++i])
|
switch (fmt[++i])
|
||||||
{
|
{
|
||||||
case '.':
|
case '.':
|
||||||
|
@ -726,29 +770,36 @@ _start:
|
||||||
|
|
||||||
switch (fmt[i])
|
switch (fmt[i])
|
||||||
{
|
{
|
||||||
case 'f': case 'F':
|
case 'f':
|
||||||
ptmp+= sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4));
|
case 'F':
|
||||||
|
ptmp += sprintf(ptmp, tmp2, (float)iopMemRead32(sp + n * 4));
|
||||||
n++;
|
n++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a': case 'A':
|
case 'a':
|
||||||
case 'e': case 'E':
|
case 'A':
|
||||||
case 'g': case 'G':
|
case 'e':
|
||||||
ptmp+= sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4));
|
case 'E':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
ptmp += sprintf(ptmp, tmp2, (double)iopMemRead32(sp + n * 4));
|
||||||
n++;
|
n++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd': case 'D':
|
case 'd':
|
||||||
case 'o': case 'O':
|
case 'D':
|
||||||
case 'x': case 'X':
|
case 'o':
|
||||||
ptmp+= sprintf(ptmp, tmp2, (u32)iopMemRead32(sp + n * 4));
|
case 'O':
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
ptmp += sprintf(ptmp, tmp2, (u32)iopMemRead32(sp + n * 4));
|
||||||
n++;
|
n++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
ptmp+= sprintf(ptmp, tmp2, (u8)iopMemRead32(sp + n * 4));
|
ptmp += sprintf(ptmp, tmp2, (u8)iopMemRead32(sp + n * 4));
|
||||||
n++;
|
n++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -776,21 +827,24 @@ _start:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*ptmp = 0;
|
*ptmp = 0;
|
||||||
iopConLog( ShiftJIS_ConvertString(tmp, 1023) );
|
iopConLog(ShiftJIS_ConvertString(tmp, 1023));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
} // namespace sysmem
|
||||||
|
|
||||||
namespace loadcore {
|
namespace loadcore
|
||||||
|
{
|
||||||
void RegisterLibraryEntries_DEBUG()
|
void RegisterLibraryEntries_DEBUG()
|
||||||
{
|
{
|
||||||
const std::string modname = iopMemReadString(a0 + 12);
|
const std::string modname = iopMemReadString(a0 + 12);
|
||||||
DevCon.WriteLn(Color_Gray, "RegisterLibraryEntries: %8.8s version %x.%02x", modname.data(), (unsigned)iopMemRead8(a0 + 9), (unsigned)iopMemRead8(a0 + 8));
|
DevCon.WriteLn(Color_Gray, "RegisterLibraryEntries: %8.8s version %x.%02x", modname.data(), (unsigned)iopMemRead8(a0 + 9), (unsigned)iopMemRead8(a0 + 8));
|
||||||
}
|
}
|
||||||
}
|
} // namespace loadcore
|
||||||
|
|
||||||
namespace intrman {
|
namespace intrman
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
static const char* intrname[] = {
|
static const char* intrname[] = {
|
||||||
"INT_VBLANK", "INT_GM", "INT_CDROM", "INT_DMA", //00
|
"INT_VBLANK", "INT_GM", "INT_CDROM", "INT_DMA", //00
|
||||||
"INT_RTC0", "INT_RTC1", "INT_RTC2", "INT_SIO0", //04
|
"INT_RTC0", "INT_RTC1", "INT_RTC2", "INT_SIO0", //04
|
||||||
|
@ -810,56 +864,76 @@ namespace intrman {
|
||||||
"INT_3C", "INT_3D", "INT_3E", "INT_3F", //3C
|
"INT_3C", "INT_3D", "INT_3E", "INT_3F", //3C
|
||||||
"INT_MAX" //40
|
"INT_MAX" //40
|
||||||
};
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
void RegisterIntrHandler_DEBUG()
|
void RegisterIntrHandler_DEBUG()
|
||||||
{
|
{
|
||||||
DevCon.WriteLn(Color_Gray, "RegisterIntrHandler: intr %s, handler %x", intrname[a0], a2);
|
DevCon.WriteLn(Color_Gray, "RegisterIntrHandler: intr %s, handler %x", intrname[a0], a2);
|
||||||
}
|
}
|
||||||
}
|
} // namespace intrman
|
||||||
|
|
||||||
namespace sifcmd {
|
namespace sifcmd
|
||||||
|
{
|
||||||
void sceSifRegisterRpc_DEBUG()
|
void sceSifRegisterRpc_DEBUG()
|
||||||
{
|
{
|
||||||
DevCon.WriteLn( Color_Gray, "sifcmd sceSifRegisterRpc: rpc_id %x", a1);
|
DevCon.WriteLn(Color_Gray, "sifcmd sceSifRegisterRpc: rpc_id %x", a1);
|
||||||
}
|
}
|
||||||
}
|
} // namespace sifcmd
|
||||||
|
|
||||||
u32 irxImportTableAddr(u32 entrypc)
|
u32 irxImportTableAddr(u32 entrypc)
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
i = entrypc - 0x18;
|
i = entrypc - 0x18;
|
||||||
while (entrypc - i < 0x2000) {
|
while (entrypc - i < 0x2000)
|
||||||
|
{
|
||||||
if (iopMemRead32(i) == 0x41e00000)
|
if (iopMemRead32(i) == 0x41e00000)
|
||||||
return i;
|
return i;
|
||||||
i -= 4;
|
i -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* irxImportFuncname(const std::string &libname, u16 index)
|
const char* irxImportFuncname(const std::string& libname, u16 index)
|
||||||
{
|
{
|
||||||
#include "IopModuleNames.cpp"
|
#include "IopModuleNames.cpp"
|
||||||
|
|
||||||
switch (index) {
|
switch (index)
|
||||||
case 0: return "start";
|
{
|
||||||
|
case 0:
|
||||||
|
return "start";
|
||||||
// case 1: reinit?
|
// case 1: reinit?
|
||||||
case 2: return "shutdown";
|
case 2:
|
||||||
|
return "shutdown";
|
||||||
// case 3: ???
|
// case 3: ???
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MODULE(n) if (#n == libname) { using namespace n; switch (index) {
|
// clang-format off
|
||||||
#define END_MODULE }}
|
#define MODULE(n) \
|
||||||
#define EXPORT_D(i, n) case (i): return n ## _DEBUG;
|
if (#n == libname) \
|
||||||
#define EXPORT_H(i, n) case (i): return n ## _HLE;
|
{ \
|
||||||
|
using namespace n; \
|
||||||
|
switch (index) \
|
||||||
|
{
|
||||||
|
#define END_MODULE \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define EXPORT_D(i, n) \
|
||||||
|
case (i): \
|
||||||
|
return n##_DEBUG;
|
||||||
|
#define EXPORT_H(i, n) \
|
||||||
|
case (i): \
|
||||||
|
return n##_HLE;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
irxHLE irxImportHLE(const std::string &libname, u16 index)
|
irxHLE irxImportHLE(const std::string& libname, u16 index)
|
||||||
{
|
{
|
||||||
// debugging output
|
// debugging output
|
||||||
|
// clang-format off
|
||||||
MODULE(sysmem)
|
MODULE(sysmem)
|
||||||
EXPORT_H( 14, Kprintf)
|
EXPORT_H( 14, Kprintf)
|
||||||
END_MODULE
|
END_MODULE
|
||||||
|
@ -877,12 +951,14 @@ irxHLE irxImportHLE(const std::string &libname, u16 index)
|
||||||
EXPORT_H( 15, dread)
|
EXPORT_H( 15, dread)
|
||||||
EXPORT_H( 16, getStat)
|
EXPORT_H( 16, getStat)
|
||||||
END_MODULE
|
END_MODULE
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
irxDEBUG irxImportDebug(const std::string &libname, u16 index)
|
irxDEBUG irxImportDebug(const std::string& libname, u16 index)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
MODULE(loadcore)
|
MODULE(loadcore)
|
||||||
EXPORT_D( 6, RegisterLibraryEntries)
|
EXPORT_D( 6, RegisterLibraryEntries)
|
||||||
END_MODULE
|
END_MODULE
|
||||||
|
@ -892,34 +968,35 @@ irxDEBUG irxImportDebug(const std::string &libname, u16 index)
|
||||||
MODULE(sifcmd)
|
MODULE(sifcmd)
|
||||||
EXPORT_D( 17, sceSifRegisterRpc)
|
EXPORT_D( 17, sceSifRegisterRpc)
|
||||||
END_MODULE
|
END_MODULE
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MODULE
|
#undef MODULE
|
||||||
#undef END_MODULE
|
#undef END_MODULE
|
||||||
#undef EXPORT_D
|
#undef EXPORT_D
|
||||||
#undef EXPORT_H
|
#undef EXPORT_H
|
||||||
|
|
||||||
void irxImportLog(const std::string &libname, u16 index, const char *funcname)
|
void irxImportLog(const std::string& libname, u16 index, const char* funcname)
|
||||||
{
|
{
|
||||||
PSXBIOS_LOG("%8.8s.%03d: %s (%x, %x, %x, %x)",
|
PSXBIOS_LOG("%8.8s.%03d: %s (%x, %x, %x, %x)",
|
||||||
libname.data(), index, funcname ? funcname : "unknown",
|
libname.data(), index, funcname ? funcname : "unknown",
|
||||||
a0, a1, a2, a3);
|
a0, a1, a2, a3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __fastcall irxImportLog_rec(u32 import_table, u16 index, const char *funcname)
|
void __fastcall irxImportLog_rec(u32 import_table, u16 index, const char* funcname)
|
||||||
{
|
{
|
||||||
irxImportLog(iopMemReadString(import_table + 12, 8), index, funcname);
|
irxImportLog(iopMemReadString(import_table + 12, 8), index, funcname);
|
||||||
}
|
}
|
||||||
|
|
||||||
int irxImportExec(u32 import_table, u16 index)
|
int irxImportExec(u32 import_table, u16 index)
|
||||||
{
|
{
|
||||||
if (!import_table)
|
if (!import_table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::string libname = iopMemReadString(import_table + 12, 8);
|
std::string libname = iopMemReadString(import_table + 12, 8);
|
||||||
const char *funcname = irxImportFuncname(libname, index);
|
const char* funcname = irxImportFuncname(libname, index);
|
||||||
irxHLE hle = irxImportHLE(libname, index);
|
irxHLE hle = irxImportHLE(libname, index);
|
||||||
irxDEBUG debug = irxImportDebug(libname, index);
|
irxDEBUG debug = irxImportDebug(libname, index);
|
||||||
|
|
||||||
|
@ -932,6 +1009,6 @@ int irxImportExec(u32 import_table, u16 index)
|
||||||
return hle();
|
return hle();
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace R3000A
|
} // end namespace R3000A
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
* Copyright (C) 2002-2021 PCSX2 Dev Team
|
||||||
*
|
*
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
|
@ -37,9 +37,10 @@
|
||||||
#define IOP_SEEK_CUR 1
|
#define IOP_SEEK_CUR 1
|
||||||
#define IOP_SEEK_END 2
|
#define IOP_SEEK_END 2
|
||||||
|
|
||||||
class IOManFile {
|
class IOManFile
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
static int open(IOManFile **file, const std::string &path, s32 flags, u16 mode)
|
static int open(IOManFile** file, const std::string& path, s32 flags, u16 mode)
|
||||||
{
|
{
|
||||||
return -IOP_ENODEV;
|
return -IOP_ENODEV;
|
||||||
}
|
}
|
||||||
|
@ -47,22 +48,23 @@ public:
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
virtual int lseek(s32 offset, s32 whence) { return -IOP_EIO; }
|
virtual int lseek(s32 offset, s32 whence) { return -IOP_EIO; }
|
||||||
virtual int read(void *buf, u32 count) { return -IOP_EIO; }
|
virtual int read(void* buf, u32 count) { return -IOP_EIO; }
|
||||||
virtual int write(void *buf, u32 count) { return -IOP_EIO; }
|
virtual int write(void* buf, u32 count) { return -IOP_EIO; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class IOManDir {
|
class IOManDir
|
||||||
|
{
|
||||||
// Don't think about it until we know the loaded ioman version.
|
// Don't think about it until we know the loaded ioman version.
|
||||||
// The dirent structure changed between versions.
|
// The dirent structure changed between versions.
|
||||||
public:
|
public:
|
||||||
static int open(IOManDir **dir, const std::string &full_path)
|
static int open(IOManDir** dir, const std::string& full_path)
|
||||||
{
|
{
|
||||||
return -IOP_ENODEV;
|
return -IOP_ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
virtual int read(void *buf) { return -IOP_EIO; }
|
virtual int read(void* buf) { return -IOP_EIO; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*irxHLE)(); // return 1 if handled, otherwise 0
|
typedef int (*irxHLE)(); // return 1 if handled, otherwise 0
|
||||||
|
@ -71,18 +73,18 @@ typedef void (*irxDEBUG)();
|
||||||
namespace R3000A
|
namespace R3000A
|
||||||
{
|
{
|
||||||
u32 irxImportTableAddr(u32 entrypc);
|
u32 irxImportTableAddr(u32 entrypc);
|
||||||
const char* irxImportFuncname(const std::string &libname, u16 index);
|
const char* irxImportFuncname(const std::string& libname, u16 index);
|
||||||
irxHLE irxImportHLE(const std::string &libnam, u16 index);
|
irxHLE irxImportHLE(const std::string& libnam, u16 index);
|
||||||
irxDEBUG irxImportDebug(const std::string & libname, u16 index);
|
irxDEBUG irxImportDebug(const std::string& libname, u16 index);
|
||||||
void irxImportLog(const std::string &libnameptr, u16 index, const char *funcname);
|
void irxImportLog(const std::string& libnameptr, u16 index, const char* funcname);
|
||||||
void __fastcall irxImportLog_rec(u32 import_table, u16 index, const char *funcname);
|
void __fastcall irxImportLog_rec(u32 import_table, u16 index, const char* funcname);
|
||||||
int irxImportExec(u32 import_table, u16 index);
|
int irxImportExec(u32 import_table, u16 index);
|
||||||
|
|
||||||
namespace ioman
|
namespace ioman
|
||||||
{
|
{
|
||||||
void reset();
|
void reset();
|
||||||
}
|
}
|
||||||
}
|
} // namespace R3000A
|
||||||
|
|
||||||
extern void Hle_SetElfPath(const char* elfFileName);
|
extern void Hle_SetElfPath(const char* elfFileName);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue