From b3cdec7069ecd2fbaead298e15f8e4b3c791fa22 Mon Sep 17 00:00:00 2001 From: Maximus32 Date: Thu, 28 Nov 2024 21:39:24 +0100 Subject: [PATCH] Fix Formula One 2001 and improve compat modes --- README.md | 4 +- ee/ee_core/include/ee_core.h | 8 +-- ee/loader/Makefile | 2 +- ee/loader/src/compat.c | 91 ++++++++++++++++++++++---------- ee/loader/src/compat.h | 3 +- ee/loader/src/main.c | 44 ++++++++------- iop/cdvdman_emu/src/cdvdman.c | 16 +++--- iop/cdvdman_emu/src/ncmd.c | 4 +- iop/cdvdman_emu/src/scmd.c | 2 +- iop/cdvdman_emu/src/searchfile.c | 6 +-- iop/cdvdman_emu/src/streaming.c | 22 ++++---- iop/common/cdvd_config.h | 9 ++-- 12 files changed, 119 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index b69237b..5ead3db 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,8 @@ Options: Defaults to cd for size<=650MiB, and dvd for size>650MiB -gc= Game compatibility modes, supported are: - - 0: Disable builtin compat flags - - 1: IOP: Accurate reads (sceCdRead) + - 0: IOP: Fast reads (sceCdRead) + - 1: dummy - 2: IOP: Sync reads (sceCdRead) - 3: EE : Unhook syscalls - 5: IOP: Emulate DVD-DL diff --git a/ee/ee_core/include/ee_core.h b/ee/ee_core/include/ee_core.h index cd32107..58758d1 100644 --- a/ee/ee_core/include/ee_core.h +++ b/ee/ee_core/include/ee_core.h @@ -40,13 +40,7 @@ extern int iop_reboot_count; extern u32 g_compat_mask; -#define COMPAT_MODE_1 0x01 // Accurate reads (sceCdRead) -#define COMPAT_MODE_2 0x02 // Sync reads (sceCdRead) -#define COMPAT_MODE_3 0x04 // Unhook syscalls -//#define COMPAT_MODE_4 0x08 // Skip videos - not supported! -#define COMPAT_MODE_5 0x10 // Emulate DVD-DL -//#define COMPAT_MODE_6 0x20 // Disable IGR - not supported! -#define COMPAT_MODE_7 0x40 // Patch IOP buffer overrun (game bug) +#define EECORE_COMPAT_UNHOOK (1<<0) // Unhook syscalls extern char GameID[16]; extern int GameMode; diff --git a/ee/loader/Makefile b/ee/loader/Makefile index f2c8989..3170c61 100644 --- a/ee/loader/Makefile +++ b/ee/loader/Makefile @@ -31,7 +31,6 @@ all: $(EE_BIN_PACKED) #GAME = 'DVD/Inuyasha - Feudal Combat (U).iso' # neutrino github issue 8: UDPBD: sfx missing or random freezes when starting match #GAME = 'DVD/Scooby-Doo! Mystery Mayhem (U).iso' # neutrino github issue 19: When starting a new game, the cutscene freezes #GAME = 'DVD/Silent Hill 3 (U).iso' # neutrino github issue 30: USB: freezes on startup logo, only on real ps2, works in pcsx2 -#GAME = 'DVD/Formula One 2001 (E).iso' # Games that use the HDD in one way or another #GAME = 'DVD/The Sims 2 (U).iso' @@ -123,6 +122,7 @@ GAME = 'DVD/Ratchet Clank - Up Your Arsenal (U).iso' #GAME = 'DVD/Auto Modellista (E).iso' #GAME = 'DVD/Disney's Treasure Planet (E).iso' # buffer overrun issue #GAME = 'DVD/Donkey Xote (E).iso' # buffer overrun issue +#GAME = 'DVD/Formula One 2001 (E).iso' # cdvdman break command # Example arguments #-bsd=udpbd -dvd=mass:$(GAME) diff --git a/ee/loader/src/compat.c b/ee/loader/src/compat.c index 5100b2d..2edf7f4 100644 --- a/ee/loader/src/compat.c +++ b/ee/loader/src/compat.c @@ -3,53 +3,88 @@ // Other #include "compat.h" -#include "ee_core.h" +#include "ee_core.h" // EECORE compat flags +#include "../../../iop/common/cdvd_config.h" // CDVDMAN compat flags -/**************************************************************************** - * Compatibility options: - * #define COMPAT_MODE_1 0x01 // Accurate reads (sceCdRead) - * #define COMPAT_MODE_2 0x02 // Sync reads (sceCdRead) - * #define COMPAT_MODE_3 0x04 // Unhook syscalls - * #define COMPAT_MODE_4 0x08 // Skip videos - not supported! - * #define COMPAT_MODE_5 0x10 // Emulate DVD-DL - * #define COMPAT_MODE_6 0x20 // Disable IGR - not supported! - * #define COMPAT_MODE_7 0x40 // Patch IOP buffer overrun (bug in the game) - */ +typedef struct +{ + uint32_t flag; + uint32_t eecore_flags; + uint32_t cdvdman_flags; + const char *ioppatch; +} flagcompat_t; +static const flagcompat_t flag_compat[] = { + {1<<0, 0, CDVDMAN_COMPAT_FAST_READS, NULL }, // MODE 0 + {1<<2, 0, CDVDMAN_COMPAT_ALT_READ, NULL }, // MODE 2 + {1<<3, EECORE_COMPAT_UNHOOK, 0, NULL }, // MODE 3 + {1<<5, 0, CDVDMAN_COMPAT_EMU_DVDDL, NULL }, // MODE 5 + {1<<7, 0, 0, "patch_membo.irx" }, // MODE 7 + {0<<0, 0, 0, NULL}, +}; + +void get_compat_flag(uint32_t flags, uint32_t *eecore, uint32_t *cdvdman, const char **ioppatch) +{ + // Game specific compatibility mode + const flagcompat_t *p = &flag_compat[0]; + while (p->flag != 0) { + if ((p->flag & flags) != 0) { + *eecore |= p->eecore_flags; // multiple flags possible + *cdvdman |= p->cdvdman_flags; // multiple flags possible + *ioppatch = p->ioppatch; // only 1 patch possible + } + p++; + } +} typedef struct { char *game; - uint32_t flags; + uint32_t eecore_flags; + uint32_t cdvdman_flags; + const char *ioppatch; } gamecompat_t; -static const gamecompat_t default_game_compat[] = { - {"SCES_524.12", COMPAT_MODE_2 }, // Jackie Chan Adventures # only needed for USB ? - {"SCUS_971.24", COMPAT_MODE_3 }, // Jak and Daxter - The Precursor Legacy # game writes to 0x84000 region ! - {"SCUS_973.30", COMPAT_MODE_3 }, // Jak 3 # game writes to 0x84000 region ! - {"SCES_524.60", COMPAT_MODE_3 }, // Jak 3 # game writes to 0x84000 region ! - {"SLES_548.38", COMPAT_MODE_7 }, // Donkey Xote # game has IOP buffer overrun issues - {"SCES_511.76", COMPAT_MODE_7 }, // Disney's Treasure Planet # game has IOP buffer overrun issues - {NULL, 0}, +static const gamecompat_t game_compat[] = { + {"SCES_524.12", 0, CDVDMAN_COMPAT_ALT_READ, NULL }, // Jackie Chan Adventures # only needed for USB ? + + // These games write to the EE 0x84000 region, where our EECORE is loaded + {"SCUS_971.24", EECORE_COMPAT_UNHOOK, 0, NULL }, // Jak and Daxter - The Precursor Legacy + {"SCUS_973.30", EECORE_COMPAT_UNHOOK, 0, NULL }, // Jak 3 + {"SCES_524.60", EECORE_COMPAT_UNHOOK, 0, NULL }, // Jak 3 + + // These games have IOP memory buffer overrun issues + {"SLES_548.38", 0, 0, "patch_membo.irx" }, // Donkey Xote + {"SCES_511.76", 0, 0, "patch_membo.irx" }, // Disney's Treasure Planet + + // These games send a cdvd break command from EE directly into IOP memory map + // This causes an interrupt by cdvd, plus a callback that the game needs. + // In PCSX2 you can see the PCSX2 message "Read Abort" every time this happens. + // + // Emulation has so far not been able to reproduce this behaviour, + // as a workaround extra cdvd callbacks are fired. + {"SCUS_971.50", 0, CDVDMAN_COMPAT_F1_2001, NULL }, // Formula One 2001 <- not checked + {"SCES_500.04", 0, CDVDMAN_COMPAT_F1_2001, NULL }, // Formula One 2001 <- checked and working + {"SCED_502.54", 0, CDVDMAN_COMPAT_F1_2001, NULL }, // Formula One 2001 <- not checked + {"SCED_503.13", 0, CDVDMAN_COMPAT_F1_2001, NULL }, // Formula One 2001 <- not checked + {"SCPS_150.19", 0, CDVDMAN_COMPAT_F1_2001, NULL }, // Formula One 2001 <- not checked + {NULL, 0, 0, NULL}, }; -uint32_t get_compat(const char *id) +void get_compat_game(const char *id, uint32_t *eecore, uint32_t *cdvdman, const char **ioppatch) { - // Default compatibility mode - uint32_t compat = COMPAT_MODE_1; - // Game specific compatibility mode - const gamecompat_t *p = &default_game_compat[0]; + const gamecompat_t *p = &game_compat[0]; while (p->game != NULL) { if (strcmp(id, p->game) == 0) { - compat |= p->flags; + *eecore |= p->eecore_flags; // multiple flags possible + *cdvdman |= p->cdvdman_flags; // multiple flags possible + *ioppatch = p->ioppatch; // only 1 patch possible break; } p++; } - - return compat; } diff --git a/ee/loader/src/compat.h b/ee/loader/src/compat.h index 14e6571..bf2e1ff 100644 --- a/ee/loader/src/compat.h +++ b/ee/loader/src/compat.h @@ -5,7 +5,8 @@ #include -uint32_t get_compat(const char *id); +void get_compat_flag(uint32_t flags, uint32_t *eecore, uint32_t *cdvdman, const char **ioppatch); +void get_compat_game(const char *id, uint32_t *eecore, uint32_t *cdvdman, const char **ioppatch); void *get_modstorage(const char *id); diff --git a/ee/loader/src/main.c b/ee/loader/src/main.c index 0632d85..5adcbac 100644 --- a/ee/loader/src/main.c +++ b/ee/loader/src/main.c @@ -110,8 +110,8 @@ void print_usage() printf(" Defaults to cd for size<=650MiB, and dvd for size>650MiB\n"); printf("\n"); printf(" -gc= Game compatibility modes, supported are:\n"); - printf(" - 0: Disable builtin compat flags\n"); - printf(" - 1: IOP: Accurate reads (sceCdRead)\n"); + printf(" - 0: IOP: Fast reads (sceCdRead)\n"); + printf(" - 1: dummy\n"); printf(" - 2: IOP: Sync reads (sceCdRead)\n"); printf(" - 3: EE : Unhook syscalls\n"); printf(" - 5: IOP: Emulate DVD-DL\n"); @@ -1049,14 +1049,12 @@ int main(int argc, char *argv[]) char c = *sys.sGC; switch (c) { case '0': - iCompat |= 1U << 31; // Set dummy flag - break; - case '1': + case '1': // dummy case '2': case '3': case '5': case '7': - iCompat |= 1U << (c - '1'); + iCompat |= 1U << (c - '0'); break; default: printf("ERROR: compat flag %c not supported\n", c); @@ -1067,6 +1065,14 @@ int main(int argc, char *argv[]) } } + /* + * Process user requested compatibility flags + */ + uint32_t eecore_compat = 0; + uint32_t cdvdman_compat = 0; + const char * patch_compat = NULL; + get_compat_flag(iCompat, &eecore_compat, &cdvdman_compat, &patch_compat); + /* * Load backing store driver settings */ @@ -1118,11 +1124,11 @@ int main(int argc, char *argv[]) /* * Load IOP game compatibility modules */ - if (iCompat & COMPAT_MODE_7) { + if (patch_compat != NULL) { struct SModule * m = &drv.mod.mod[drv.mod.count]; drv.mod.count++; - m->sFileName = "patch_membo.irx"; + m->sFileName = (char *)patch_compat; m->env = MOD_ENV_EE; } @@ -1304,7 +1310,7 @@ int main(int argc, char *argv[]) } } else { - if (iCompat != 0) + if (cdvdman_compat != 0) printf("WARNING: compatibility cannot be changed without emulating the DVD\n"); if (eMediaType != SCECdNODISC) printf("WARNING: media type cannot be changed without emulating the DVD\n"); @@ -1366,23 +1372,15 @@ int main(int argc, char *argv[]) /* * Get ELF/game compatibility flags */ - if (iCompat == 0) - iCompat = get_compat(sGameID); - iCompat &= ~(1U << 31); // Clear dummy flag + get_compat_game(sGameID, &eecore_compat, &cdvdman_compat, &patch_compat); + printf("EECORE compat flags: 0x%lX\n", eecore_compat); + printf("CDVDMAN compat flags: 0x%lX\n", cdvdman_compat); /* * Set CDVDMAN compatibility */ - if (sDVDFile != NULL) { - if (iCompat & COMPAT_MODE_1) - set_cdvdman->flags |= IOPCORE_COMPAT_ACCU_READS; - if (iCompat & COMPAT_MODE_2) - set_cdvdman->flags |= IOPCORE_COMPAT_ALT_READ; - if (iCompat & COMPAT_MODE_5) - set_cdvdman->flags |= IOPCORE_COMPAT_EMU_DVDDL; - - printf("Compat flags: 0x%X, IOP=0x%X\n", (unsigned int)iCompat, set_cdvdman->flags); - } + if (sDVDFile != NULL) + set_cdvdman->flags = cdvdman_compat; /* * Set deckard compatibility @@ -1607,7 +1605,7 @@ int main(int argc, char *argv[]) eecc_setELFArgs(&eeconf, argc-iELFArgcStart, (const char **)&argv[iELFArgcStart]); eecc_setKernelConfig(&eeconf, eeloadCopy, initUserMemory); eecc_setModStorageConfig(&eeconf, irxtable, irxptr); - eecc_setCompatFlags(&eeconf, iCompat); + eecc_setCompatFlags(&eeconf, eecore_compat); eecc_setDebugColors(&eeconf, sys.bDebugColors); eecc_setPS2Logo(&eeconf, sys.bLogo); printf("Starting ee_core with following arguments:\n"); diff --git a/iop/cdvdman_emu/src/cdvdman.c b/iop/cdvdman_emu/src/cdvdman.c index 7ebdd33..0834648 100644 --- a/iop/cdvdman_emu/src/cdvdman.c +++ b/iop/cdvdman_emu/src/cdvdman.c @@ -87,7 +87,7 @@ static int cdvdman_read_sectors(u32 lsn, unsigned int sectors, void *buf) //M_DEBUG("cdvdman_read_sectors lsn=%lu sectors=%u buf=%p\n", lsn, sectors, buf); - if (cdvdman_settings.flags & IOPCORE_COMPAT_ACCU_READS) { + if ((cdvdman_settings.flags & CDVDMAN_COMPAT_FAST_READS) == 0) { /* * Limit transfer speed to match the physical drive in the ps2 * @@ -184,7 +184,7 @@ static int cdvdman_read_sectors(u32 lsn, unsigned int sectors, void *buf) for (ptr = buf, remaining = sectors; remaining > 0;) { unsigned int SectorsToRead = remaining; - if (cdvdman_settings.flags & IOPCORE_COMPAT_ACCU_READS) { + if ((cdvdman_settings.flags & CDVDMAN_COMPAT_FAST_READS) == 0) { // Limit transfers to a maximum length of 8, with a restricted transfer rate. iop_sys_clock_t TargetTime; @@ -198,7 +198,7 @@ static int cdvdman_read_sectors(u32 lsn, unsigned int sectors, void *buf) cdvdman_stat.err = DeviceReadSectors(lsn, ptr, SectorsToRead); if (cdvdman_stat.err != SCECdErNO) { - if (cdvdman_settings.flags & IOPCORE_COMPAT_ACCU_READS) + if ((cdvdman_settings.flags & CDVDMAN_COMPAT_FAST_READS) == 0) CancelAlarm(&cdvdemu_read_end_cb, NULL); break; } @@ -227,7 +227,7 @@ static int cdvdman_read_sectors(u32 lsn, unsigned int sectors, void *buf) lsn += SectorsToRead; ReadPos += SectorsToRead * 2048; - if (cdvdman_settings.flags & IOPCORE_COMPAT_ACCU_READS) { + if ((cdvdman_settings.flags & CDVDMAN_COMPAT_FAST_READS) == 0) { // Sleep until the required amount of time has been spent. WaitEventFlag(cdvdman_stat.intr_ef, CDVDEF_READ_END, WEF_AND, NULL); } @@ -623,9 +623,9 @@ static void cdvdman_cdread_Thread(void *args) if (Stm0Callback != NULL) Stm0Callback(); - // Notify external irx that sceCdRead has finished - // 'Formula One 2001' seems to need this for background music - cdvdman_cb_event(SCECdFuncRead); + if (cdvdman_settings.flags & CDVDMAN_COMPAT_F1_2001) + cdvdman_cb_event(SCECdFuncRead); + break; } @@ -699,7 +699,7 @@ int _start(int argc, char **argv) RegisterLibraryEntries(&_exp_cdvdstm); // Setup the callback timer. - USec2SysClock((cdvdman_settings.flags & IOPCORE_COMPAT_ACCU_READS) ? 5000 : 0, &gCallbackSysClock); + USec2SysClock((cdvdman_settings.flags & CDVDMAN_COMPAT_FAST_READS) ? 0 : 5000, &gCallbackSysClock); // Limit min/max sectors if (cdvdman_settings.fs_sectors < 2) diff --git a/iop/cdvdman_emu/src/ncmd.c b/iop/cdvdman_emu/src/ncmd.c index 538ba91..4466a62 100644 --- a/iop/cdvdman_emu/src/ncmd.c +++ b/iop/cdvdman_emu/src/ncmd.c @@ -30,7 +30,7 @@ int sceCdRead(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode) result = sceCdRead_internal(lsn, sectors, buf, mode, ECS_EXTERNAL); - if ((result == 1) && (cdvdman_settings.flags & IOPCORE_COMPAT_ALT_READ) && !QueryIntrContext()) + if ((result == 1) && (cdvdman_settings.flags & CDVDMAN_COMPAT_ALT_READ) && !QueryIntrContext()) WaitEventFlag(cdvdman_stat.intr_ef, CDVDEF_MAN_UNLOCKED, WEF_AND, NULL); return result; @@ -140,7 +140,7 @@ static int cdvdman_fill_toc(u8 *tocBuff) memset(tocBuff, 0, 2048); u8 dual = 0; - if ((!(cdvdman_settings.flags & IOPCORE_COMPAT_EMU_DVDDL)) || (cdvdman_settings.layer1_start > 0)) + if ((!(cdvdman_settings.flags & CDVDMAN_COMPAT_EMU_DVDDL)) || (cdvdman_settings.layer1_start > 0)) dual = 1; // Write only what we need, memset has cleared the above buffers. diff --git a/iop/cdvdman_emu/src/scmd.c b/iop/cdvdman_emu/src/scmd.c index 5e395dd..90dbaa6 100644 --- a/iop/cdvdman_emu/src/scmd.c +++ b/iop/cdvdman_emu/src/scmd.c @@ -200,7 +200,7 @@ int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start) { M_DEBUG("%s(-, -)\n", __FUNCTION__); - if (cdvdman_settings.flags & IOPCORE_COMPAT_EMU_DVDDL) { + if (cdvdman_settings.flags & CDVDMAN_COMPAT_EMU_DVDDL) { // Make layer 1 point to layer 0. *layer1_start = 0; *on_dual = 1; diff --git a/iop/cdvdman_emu/src/searchfile.c b/iop/cdvdman_emu/src/searchfile.c index 416cca0..908b84f 100644 --- a/iop/cdvdman_emu/src/searchfile.c +++ b/iop/cdvdman_emu/src/searchfile.c @@ -128,7 +128,7 @@ static struct dirTocEntry *cdvdman_locatefile(char *name, u32 tocLBA, int tocLen tocLength = tocEntryPointer->fileSize; p = &slash[1]; - if (!(cdvdman_settings.flags & IOPCORE_COMPAT_EMU_DVDDL)) { + if (!(cdvdman_settings.flags & CDVDMAN_COMPAT_EMU_DVDDL)) { int on_dual; unsigned int layer1_start; sceCdReadDvdDualInfo(&on_dual, &layer1_start); @@ -160,7 +160,7 @@ static int cdvdman_findfile(sceCdlFILE *pcdfile, const char *name, int layer) cdvdman_init(); - if (cdvdman_settings.flags & IOPCORE_COMPAT_EMU_DVDDL) + if (cdvdman_settings.flags & CDVDMAN_COMPAT_EMU_DVDDL) layer = 0; pLayerInfo = (layer != 0) ? &layer_info[1] : &layer_info[0]; // SCE CDVDMAN simply treats a non-zero value as a signal for the 2nd layer. @@ -235,7 +235,7 @@ void cdvdman_searchfile_init(void) //M_DEBUG("cdvdman_searchfile_init mediaLsnCount=%d\n", mediaLsnCount); // DVD DL support - if (!(cdvdman_settings.flags & IOPCORE_COMPAT_EMU_DVDDL)) { + if (!(cdvdman_settings.flags & CDVDMAN_COMPAT_EMU_DVDDL)) { int on_dual; unsigned int layer1_start; sceCdReadDvdDualInfo(&on_dual, &layer1_start); diff --git a/iop/cdvdman_emu/src/streaming.c b/iop/cdvdman_emu/src/streaming.c index f1f045c..8747b40 100644 --- a/iop/cdvdman_emu/src/streaming.c +++ b/iop/cdvdman_emu/src/streaming.c @@ -20,17 +20,14 @@ static void StmCallback(void) { int OldState; - // Only update parameters if the streaming system was reading. Otherwise, this callback might have been triggered by the game reading data (BUG!) - if (cdvdman_stat.StreamingData.StIsReading) { - CpuSuspendIntr(&OldState); - cdvdman_stat.StreamingData.Stlsn += cdvdman_stat.StreamingData.StBanksize; - cdvdman_stat.StreamingData.StStreamed += cdvdman_stat.StreamingData.StBanksize; - cdvdman_stat.StreamingData.StWritePtr += cdvdman_stat.StreamingData.StBanksize; - if (cdvdman_stat.StreamingData.StWritePtr >= cdvdman_stat.StreamingData.StBufmax) - cdvdman_stat.StreamingData.StWritePtr = 0; - cdvdman_stat.StreamingData.StIsReading = 0; - CpuResumeIntr(OldState); - } + CpuSuspendIntr(&OldState); + cdvdman_stat.StreamingData.Stlsn += cdvdman_stat.StreamingData.StBanksize; + cdvdman_stat.StreamingData.StStreamed += cdvdman_stat.StreamingData.StBanksize; + cdvdman_stat.StreamingData.StWritePtr += cdvdman_stat.StreamingData.StBanksize; + if (cdvdman_stat.StreamingData.StWritePtr >= cdvdman_stat.StreamingData.StBufmax) + cdvdman_stat.StreamingData.StWritePtr = 0; + cdvdman_stat.StreamingData.StIsReading = 0; + CpuResumeIntr(OldState); //M_DEBUG("StmCallback: %08lx, wr: %u, rd: %u, streamed: %u\n", cdvdman_stat.StreamingData.Stlsn, cdvdman_stat.StreamingData.StWritePtr, cdvdman_stat.StreamingData.StReadPtr, cdvdman_stat.StreamingData.StStreamed); @@ -421,5 +418,8 @@ int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error) result = 0; } + if (cdvdman_settings.flags & CDVDMAN_COMPAT_F1_2001) + cdvdman_cb_event(SCECdFuncRead); + return result; } diff --git a/iop/common/cdvd_config.h b/iop/common/cdvd_config.h index 4d90621..41c40dd 100644 --- a/iop/common/cdvd_config.h +++ b/iop/common/cdvd_config.h @@ -4,11 +4,10 @@ #include // flags -#define IOPCORE_COMPAT_ACCU_READS 0x0008 // MODE_1 -#define IOPCORE_COMPAT_ALT_READ 0x0001 // MODE_2 -//#define IOPCORE_COMPAT_0_SKIP_VIDEOS 0x0002 // MODE_4 - not supported! -#define IOPCORE_COMPAT_EMU_DVDDL 0x0004 // MODE_5 -//#define IOPCORE_ENABLE_POFF 0x0100 // MODE_6 - not supported! +#define CDVDMAN_COMPAT_FAST_READS (1<<0) // ~MODE_1 +#define CDVDMAN_COMPAT_ALT_READ (1<<1) // MODE_2 +#define CDVDMAN_COMPAT_EMU_DVDDL (1<<2) // MODE_5 +#define CDVDMAN_COMPAT_F1_2001 (1<<3) #define MODULE_SETTINGS_MAGIC 0xf1f2f3f4 struct cdvdman_settings_common