diff --git a/frontend/drivers/platform_ps2.c b/frontend/drivers/platform_ps2.c index d28986d4d8..fc07094e28 100644 --- a/frontend/drivers/platform_ps2.c +++ b/frontend/drivers/platform_ps2.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -208,12 +209,11 @@ static void frontend_ps2_init(void *data) } /* Initializes CDVD library */ + /* SCECdINoD init without check for a disc. Reduces risk of a lockup if the drive is in a erroneous state. */ + sceCdInit(SCECdINoD); if (CDVD_Init() != 1) { RARCH_ERR("CDVD_Init library not initalizated\n"); } - if (cdInit(CDVD_INIT_INIT) != 1) { - RARCH_ERR("cdInit library not initalizated\n"); - } _init_ps2_io(); @@ -236,7 +236,6 @@ static void frontend_ps2_deinit(void *data) command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); #endif _free_ps2_io(); - cdInit(CDVD_INIT_EXIT); CDVD_Stop(); padEnd(); audsrv_quit(); diff --git a/ps2/compat_files/fileXio_cdvd.c b/ps2/compat_files/fileXio_cdvd.c index 09074c7094..5c61840568 100644 --- a/ps2/compat_files/fileXio_cdvd.c +++ b/ps2/compat_files/fileXio_cdvd.c @@ -2,168 +2,79 @@ #include #include #include +#include #include #include #include #include +#include #include "ps2_devices.h" #include "ps2_descriptor.h" -#define CD_SERVER_INIT 0x80000592 -#define CD_SERVER_SCMD 0x80000593 -#define CD_SCMD_GETDISCTYPE 0x03 - +/* I dont know why but this line is totally needed */ static SifRpcClientData_t clientInit __attribute__ ((aligned(64))); -static u32 initMode __attribute__ ((aligned(64))); -static int cdThreadId = 0; -static int bindSearchFile = -1; -static int bindDiskReady = -1; -static int bindInit = -1; -static int bindNCmd = -1; -static int bindSCmd = -1; -static int nCmdSemaId = -1; // n-cmd semaphore id -static int sCmdSemaId = -1; // s-cmd semaphore id -static int callbackSemaId = -1; // callback semaphore id -static int cdDebug = 0; -static int sCmdNum = 0; -static SifRpcClientData_t clientSCmd __attribute__ ((aligned(64))); -static u8 sCmdRecvBuff[48] __attribute__ ((aligned(64))); -static volatile int cbSema = 0; -static ee_thread_status_t cdThreadParam; -static int callbackThreadId = 0; -volatile int cdCallbackNum __attribute__ ((aligned(64))); - -static void cdSemaInit(void); -static int cdCheckSCmd(int cur_cmd); -static int cdSyncS(int mode); -static void cdSemaExit(void); - -static int first_file_index; - -int cdInit(int mode) -{ - int i; - - if (cdSyncS(1)) - return 0; - SifInitRpc(0); - cdThreadId = GetThreadId(); - bindSearchFile = -1; - bindNCmd = -1; - bindSCmd = -1; - bindDiskReady = -1; - bindInit = -1; - - while (1) { - if (SifBindRpc(&clientInit, CD_SERVER_INIT, 0) >= 0) - if (clientInit.server != 0) break; - i = 0x10000; - while (i--); - } - - bindInit = 0; - initMode = mode; - SifWriteBackDCache(&initMode, 4); - if (SifCallRpc(&clientInit, 0, 0, &initMode, 4, 0, 0, 0, 0) < 0) - return 0; - if (mode == CDVD_INIT_EXIT) { - cdSemaExit(); - nCmdSemaId = -1; - sCmdSemaId = -1; - callbackSemaId = -1; - } else { - cdSemaInit(); - } - return 1; -} - -static void cdSemaExit(void) -{ - if (callbackThreadId) { - cdCallbackNum = -1; - SignalSema(callbackSemaId); - } - DeleteSema(nCmdSemaId); - DeleteSema(sCmdSemaId); - DeleteSema(callbackSemaId); -} - -static void cdSemaInit(void) -{ - struct t_ee_sema semaParam; - - // return if both semaphores are already inited - if (nCmdSemaId != -1 && sCmdSemaId != -1) - return; - - semaParam.init_count = 1; - semaParam.max_count = 1; - semaParam.option = 0; - nCmdSemaId = CreateSema(&semaParam); - sCmdSemaId = CreateSema(&semaParam); - - semaParam.init_count = 0; - callbackSemaId = CreateSema(&semaParam); - - cbSema = 0; -} - -static int cdCheckSCmd(int cur_cmd) -{ - int i; - cdSemaInit(); - if (PollSema(sCmdSemaId) != sCmdSemaId) { - if (cdDebug > 0) - printf("Scmd fail sema cur_cmd:%d keep_cmd:%d\n", cur_cmd, sCmdNum); - return 0; - } - sCmdNum = cur_cmd; - ReferThreadStatus(cdThreadId, &cdThreadParam); - if (cdSyncS(1)) { - SignalSema(sCmdSemaId); - return 0; - } - - SifInitRpc(0); - if (bindSCmd >= 0) - return 1; - while (1) { - if (SifBindRpc(&clientSCmd, CD_SERVER_SCMD, 0) < 0) { - if (cdDebug > 0) - printf("Libcdvd bind err S cmd\n"); - } - if (clientSCmd.server != 0) - break; - - i = 0x10000; - while (i--) - ; - } - - bindSCmd = 0; - return 1; -} - -static int cdSyncS(int mode) -{ - if (mode == 0) { - if (cdDebug > 0) - printf("S cmd wait\n"); - while (SifCheckStatRpc(&clientSCmd)) - ; - return 0; - } - return SifCheckStatRpc(&clientSCmd); -} static int comp_entries_by_filename(const void *elem1, const void *elem2) { - return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename); + return strcmp(((entries*)elem1)->filename, ((entries*)elem2)->filename); } -static inline char* strzncpy(char *d, const char *s, size_t l) -{ - d[0] = 0; return strncat(d, s, l); +static int ps2_cdDiscValid(void) //returns 1 if disc valid, else returns 0 +{ + int cdmode = sceCdGetDiskType(); + + switch (cdmode) { + case SCECdPSCD: + case SCECdPSCDDA: + case SCECdPS2CD: + case SCECdPS2CDDA: + case SCECdPS2DVD: + case SCECdCDDA: + case SCECdDVDV: + return 1; + case SCECdNODISC: + case SCECdDETCT: + case SCECdDETCTCD: + case SCECdDETCTDVDS: + case SCECdDETCTDVDD: + case SCECdUNKNOWN: + case SCECdIllegalMedia: + default: + return 0; + } +} + +static u64 cd_Timer(void) +{ + return (clock() / (CLOCKS_PER_SEC / 1000)); +} + +static void ps2_cdStop(void) +{ + CDVD_Stop(); + sceCdSync(0); +} + +static int prepareCDVD(void) +{ + u64 wait_start; + int cdmode = sceCdGetDiskType(); + + if (sceCdGetDiskType() <= SCECdUNKNOWN) { + wait_start = cd_Timer(); + while ((cd_Timer() < wait_start + 500) && !ps2_cdDiscValid()) { + if (cdmode == SCECdNODISC) + return 0; + } + if (cdmode == SCECdNODISC) + return 0; + if ((cdmode < SCECdPSCD) || (cdmode > SCECdPS2DVD)) { + ps2_cdStop(); + return 0; + } + } + + return 1; } static int listcdvd(const char *path, entries *FileEntry) @@ -172,6 +83,7 @@ static int listcdvd(const char *path, entries *FileEntry) char dir[1025]; int i, n; int t = 0; + int first_file_index; strcpy(dir, &path[5]); // Directories first... @@ -187,7 +99,6 @@ static int listcdvd(const char *path, entries *FileEntry) FileEntry[t].dircheck = 1; strcpy(FileEntry[t].filename, TocEntryList[i].filename); - strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63); t++; if (t >= FILEENTRY_SIZE - 2) { @@ -211,7 +122,6 @@ static int listcdvd(const char *path, entries *FileEntry) FileEntry[t].dircheck = 0; strcpy(FileEntry[t].filename, TocEntryList[i].filename); - strzncpy(FileEntry[t].displayname, FileEntry[t].filename, 63); t++; if (t >= FILEENTRY_SIZE - 2) { @@ -227,15 +137,13 @@ static int listcdvd(const char *path, entries *FileEntry) static int fileXioCDDread(int fd, iox_dirent_t *dirent) { DescriptorTranslation *descriptor = __ps2_fd_grab(fd); - if (descriptor->current_folder_position == -1) { - descriptor->current_folder_position = 0; - descriptor->items = listcdvd(descriptor->path, descriptor->FileEntry); - } - if (descriptor->current_folder_position < descriptor->items) { + if (descriptor && descriptor->current_folder_position < descriptor->items) { strcpy(dirent->name, descriptor->FileEntry[descriptor->current_folder_position].filename); if (descriptor->FileEntry[descriptor->current_folder_position].dircheck) { dirent->stat.mode = FIO_S_IFDIR; + } else { + dirent->stat.mode = FIO_S_IFREG; } descriptor->current_folder_position++; } else { @@ -246,14 +154,25 @@ static int fileXioCDDread(int fd, iox_dirent_t *dirent) return 1; } +static int fileXioCDDopen(const char *name) +{ + int fd = -1; + if (prepareCDVD()){ + fd = __ps2_acquire_descriptor(); + DescriptorTranslation *descriptor = __ps2_fd_grab(fd); + descriptor->current_folder_position = 0; + descriptor->items = listcdvd(name, descriptor->FileEntry); + } + return fd; +} + + int ps2fileXioDopen(const char *name) { enum BootDeviceIDs deviceID = getBootDeviceID((char *)name); - int fd; + int fd = -1; if (deviceID == BOOT_DEVICE_CDFS) { - fd = __ps2_acquire_descriptor(); - DescriptorTranslation *descriptor = __ps2_fd_grab(fd); - strcpy(descriptor->path, name); + fd = fileXioCDDopen(name); } else { fd = fileXioDopen(name); } diff --git a/ps2/compat_files/ps2_descriptor.c b/ps2/compat_files/ps2_descriptor.c index 6af1106aac..c46be16c9b 100644 --- a/ps2/compat_files/ps2_descriptor.c +++ b/ps2/compat_files/ps2_descriptor.c @@ -40,6 +40,7 @@ static int __ps2_fd_drop(DescriptorTranslation *map) if (map->ref_count == 1) { map->ref_count--; + map->current_folder_position = -1; free(map->FileEntry); memset(map, 0, sizeof(DescriptorTranslation)); } @@ -57,7 +58,7 @@ int is_fd_valid(int fd) /* Correct fd value */ fd = MAX_OPEN_FILES - fd; - return (fd > 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); + return (fd >= 0) && (fd < MAX_OPEN_FILES) && (__ps2_fdmap[fd] != NULL); } void _init_ps2_io(void) { diff --git a/ps2/include/ps2_descriptor.h b/ps2/include/ps2_descriptor.h index 1d9e84c3a8..f0e17cc53f 100644 --- a/ps2/include/ps2_descriptor.h +++ b/ps2/include/ps2_descriptor.h @@ -22,14 +22,12 @@ #define FILEENTRY_SIZE 2048 typedef struct { - char displayname[64]; - int dircheck; - char filename[256]; + int dircheck; + char filename[256]; } entries; typedef struct { - char path[256]; int ref_count; int items; int current_folder_position;