diff --git a/Config.c b/Config.c index 98c5582..d82a6c7 100644 --- a/Config.c +++ b/Config.c @@ -59,6 +59,14 @@ inline u32 ConfigGetConfig( u32 Config ) { return !!(DMLCfg->Config & Config); } +inline void ConfigSetConfig( u32 Config ) +{ + DMLCfg->Config |= Config; +} +inline void ConfigClearConfig( u32 Config ) +{ + DMLCfg->Config &= ~Config; +} u32 ConfigGetVideMode( void ) { return DMLCfg->VideoMode; diff --git a/Config.h b/Config.h index f01a740..5e68af3 100644 --- a/Config.h +++ b/Config.h @@ -90,6 +90,8 @@ enum VideoModes void ConfigInit( DML_CFG *Cfg ); u32 ConfigGetConfig( u32 Config ); +void ConfigSetConfig( u32 Config ); +void ConfigClearConfig( u32 Config ); u32 ConfigGetVideMode( void ); char *ConfigGetGamePath( void ); diff --git a/DVD.c b/DVD.c index cfa66a4..3172576 100644 --- a/DVD.c +++ b/DVD.c @@ -65,7 +65,7 @@ void DVDInit( void ) default: case FR_DISK_ERR: { - dbgprintf( "DIP: Disk error\n", fres ); + dbgprintf( "DIP:Disk error\n", fres ); while(1); } break; } @@ -73,7 +73,7 @@ void DVDInit( void ) if( fres != FR_OK ) { - dbgprintf( "Could not find any USB device!"); + dbgprintf( "DIP:Could not find any USB device!"); } return; @@ -81,13 +81,14 @@ void DVDInit( void ) s32 DVDSelectGame( void ) { char *str = (char*)malloca( 256, 32 ); + u32 i=0; if( ConfigGetConfig(DML_CFG_GAME_PATH) ) { sprintf( str, "%s", ConfigGetGamePath() ); } else { - dbgprintf("No game path was supplied!\n"); + dbgprintf("DIP:No game path was supplied!\n"); free(str); return -1; } @@ -100,13 +101,40 @@ s32 DVDSelectGame( void ) //Try to switch to FST mode if( !FSTInit() ) { - dbgprintf("Failed to open:\"%s\" fres:%d\n", str, fres ); + dbgprintf("DIP:Failed to open:\"%s\" fres:%d\n", str, fres ); free(str); return -2; } } else { + + f_close( &GameFile ); + + dbgprintf("DIP:Current Gamepath:\"%s\"\n", str ); + + //search the string backwards for '/' + for( i=strlen(str); i > 0; --i ) + if( str[i] == '/' ) + break; + i++; + if( ConfigGetConfig(DML_CFG_BOOT_DISC2) ) + { + sprintf( str+i, "disc2.iso" ); + } else { + sprintf( str+i, "game.iso" ); + } + + dbgprintf("DIP:New Gamepath:\"%s\"\n", str ); + + fres = f_open( &GameFile, str, FA_READ ); + if( fres != FR_OK ) + { + dbgprintf("DIP:Failed to open:\"%s\" fres:%d\n", str, fres ); + free(str); + return -3; + } + f_lseek( &GameFile, 0 ); f_read( &GameFile, (void*)0, 0x20, &read ); diff --git a/Patches.c b/Patches.c index a307ef0..1631a65 100644 --- a/Patches.c +++ b/Patches.c @@ -648,15 +648,15 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset ) for( i=0; i < size; i+=4 ) { if( (PatchCount & 2) == 0 ) - if( (read32( (u32)ptr + i )&0xFC00FFFF) == 0x5400077A && - (read32( (u32)ptr + i + 4 )&0xFC00FFFF) == 0x28000000 && - read32( (u32)ptr + i + 8 ) == 0x41820008 && - (read32( (u32)ptr + i +12 )&0xFC00FFFF) == 0x64002000 - ) + if( (read32( (u32)ptr + i ) & 0xFC00FFFF) == 0x5400077A && + (read32( (u32)ptr + i + 4 ) & 0xFC00FFFF) == 0x28000000 && + read32( (u32)ptr + i + 8 ) == 0x41820008 && + (read32( (u32)ptr + i +12 ) & 0xFC00FFFF) == 0x64002000 + ) { dbgprintf("Patch:Found [__OSDispatchInterrupt]: 0x%08X 0x%08X\n", (u32)ptr + i + 0 + SectionOffset, (u32)ptr + i + 0x1A8 + SectionOffset ); - write32( (u32)ptr + i + 0, (read32( (u32)ptr + i + 0 ) & 0xFFFF0000) | 0x0463 ); + write32( (u32)ptr + i + 0, (read32( (u32)ptr + i + 0 ) & 0xFFFF0000) | 0x0463 ); write32( (u32)ptr + i + 0x1A8, (read32( (u32)ptr + i + 0x1A8 ) & 0xFFFF0000) | 0x0463 ); PatchCount |= 2; @@ -909,12 +909,73 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset ) } } + if( (PatchCount & 256) == 0 ) //DVDLowStopMotor + { + if( read32( (u32)ptr + i ) == 0x3C00E300 ) + { + u32 Offset = (u32)ptr + i; + + dbgprintf("Patch:[DVDLowStopMotor] 0x%08X\n", Offset + SectionOffset ); + + value = *(vu32*)(Offset-12); + value&= 0xFFFF0000; + value|= 0x0000C000; + *(vu32*)(Offset-12) = value; + + value = *(vu32*)(Offset-8); + value&= 0xFFFF0000; + value|= 0x00002F00; + *(vu32*)(Offset-8) = value; + + value = *(vu32*)(Offset+4); + value&= 0xFFFF0000; + value|= 0x00002F08; + *(vu32*)(Offset+4) = value; + + PatchCount |= 256; + } + } + + if( (PatchCount & 512) == 0 ) //DVDLowReadDiskID + { + if( (read32( (u32)ptr + i ) & 0xFFFF ) == 0xA800 && (read32( (u32)ptr + i + 4 ) & 0xFFFF ) == 0x40 ) + { + u32 Offset = (u32)ptr + i; + + dbgprintf("Patch:[DVDLowReadDiskID] 0x%08X\n", Offset + SectionOffset ); + + value = *(vu32*)(Offset); + value&= 0xFFFF0000; + value|= 0x0000A700; + *(vu32*)(Offset) = value; + + value = *(vu32*)(Offset+0x20); + value&= 0xFFFF0000; + value|= 0x0000C000; + *(vu32*)(Offset+0x20) = value; + + value = *(vu32*)(Offset+0x24); + value&= 0xFFFF0000; + value|= 0x00002F00; + *(vu32*)(Offset+0x24) = value; + + value = *(vu32*)(Offset+0x2C); + value&= 0xFFFF0000; + value|= 0x00002F08; + *(vu32*)(Offset+0x2C) = value; + + write32( 0x01576D4, 0x38600000 ); + + PatchCount |= 512; + } + } + if( ConfigGetConfig(DML_CFG_CHEATS) || ConfigGetConfig( DML_CFG_DEBUGGER ) ) { - if( PatchCount == 255 ) + if( PatchCount == 1023 ) break; } else { - if( PatchCount == 239 ) + if( PatchCount == 1007 ) break; } } diff --git a/dip.c b/dip.c index 498195b..10c2f01 100644 --- a/dip.c +++ b/dip.c @@ -15,6 +15,7 @@ u32 DOLSize = 0; u32 DOLOffset = 0; s32 ELFNumberOfSections = 0; u32 FSTMode = 0; +u32 DiscChangeIRQ = 0; extern DML_CFG *DMLCfg; @@ -106,6 +107,39 @@ u32 DIUpdateRegisters( void ) switch( read32(DI_SCMD_0) >> 24 ) { + case 0xE3: + { + dbgprintf("DIP:DVDLowStopMotor()\n"); + + u32 CDiscNumber = (read32(4) << 16 ) >> 24; + dbgprintf("DIP:Current disc number:%u\n", CDiscNumber + 1 ); + + if( CDiscNumber ) + { + ConfigClearConfig(DML_CFG_BOOT_DISC2); + } else { + ConfigSetConfig(DML_CFG_BOOT_DISC2); + } + + f_close( &GameFile ); + + dbgprintf("DVDSelectGame():%d\n", DVDSelectGame() ); + + DiscChangeIRQ = 1; + + while( read32(DI_SCONTROL) & 1 ) + clear32( DI_SCONTROL, 1 ); + + set32( DI_SSTATUS, 0x3A ); + + write32( 0x0d80000C, (1<<0) | (1<<4) ); + write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); + write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); + set32( 0x0d80000C, (1<<2) ); + + write32( HW_TIMER, 0 ); + + } break; case 0xA7: case 0xA9: //dbgprintf("DIP:Async!\n"); @@ -333,7 +367,7 @@ u32 DIUpdateRegisters( void ) } } - if( (u64)read32(HW_TIMER) >= 2 * 60 * 243000000LL / 128 ) + if( (u64)read32(HW_TIMER) >= 25 * 243000000LL / 128 ) { USBStorage_Read_Sectors( (read32(HW_TIMER) << 3) & 0x000FFFFF, 1, (void*)0x1000 ); diff --git a/global.h b/global.h index c12f941..decaa88 100644 --- a/global.h +++ b/global.h @@ -15,7 +15,7 @@ #define PADHOOK 1 #define CONFIG_VERSION 0x00000002 -#define DM_VERSION 0x00020005 +#define DM_VERSION 0x00020006 #define DI_SUCCESS 1 #define DI_ERROR 2 diff --git a/main.c b/main.c index 503266f..b426b15 100644 --- a/main.c +++ b/main.c @@ -21,26 +21,24 @@ Copyright (C) 2010-2012 crediar #include "dip.h" #include "Patches.h" +extern u32 DiscChangeIRQ; + char __aeabi_unwind_cpp_pr0[0]; void Syscall( u32 a, u32 b, u32 c, u32 d ) { - dbgprintf("Syscall,%d,%d,%d,%d\n", a, b, c, d); + //dbgprintf("Syscall,%d,%d,%d,%d\n", a, b, c, d); return; } void SWI( u32 a, u32 b ) { - dbgprintf("SWI:%X,%X\n", a, b ); + //dbgprintf("SWI:%X,%X\n", a, b ); return; } void PrefetchAbort( void ) { - u32 val; - __asm("mov %0,lr": "=r" (val) ); - - *(vu32*)0xD800070 |= 1; - - dbgprintf("PrefetchAbort LR:%08x\n", val-8 ); + EXIControl(1); + dbgprintf("PrefetchAbort\n"); while(1); return; } @@ -52,13 +50,13 @@ void DataAbort( u32 a, u32 b, u32 c, u32 d, u32 e, u32 f, u32 g, u32 h ) *(vu32*)0xD800070 |= 1; - dbgprintf("DataAbort: LR:%08x, %x, %x, %x, %x, %x, %x, %x\n",val-8,b,c,d,e,f,g,h); + dbgprintf("DataAbort: LR:%08x, %x, %x, %x, %x, %x, %x, %x\n",val,b,c,d,e,f,g,h); Shutdown(); } void IRQHandler( void ) { u32 IRQs = read32(HW_ARMIRQFLAG) /*& read32(HW_ARMIRQMASK)*/; - + if( IRQs & IRQ_GPIO1 ) // Starlet GPIO IRQ { if( read32(HW_GPIO_INTFLAG) & (1) ) @@ -85,18 +83,12 @@ void IRQHandler( void ) while(1); } - } else if( IRQs & IRQ_RESET ) - { - ; - } else { - - set32( HW_EXICTRL, 1 ); - - udelay(1000); - dbgprintf("IRQ:%08X %08X\n", read32(HW_ARMIRQFLAG), read32(HW_GPIO_INTFLAG) ); - set32( HW_EXICTRL, 0 ); } + //Clear IRQ Flags + write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); + write32( HW_GPIO_INTFLAG, read32(HW_GPIO_INTFLAG) ); + return; } void FIQHandler( void ) @@ -168,9 +160,7 @@ int main( int argc, char *argv[] ) #endif dbgprintf("Built: " __DATE__ " " __TIME__ "\n"); dbgprintf("This software is licensed under GPLv3, for more details visit:\nhttp://code.google.com/p/diosmios\n"); - - //dbgprintf("CPU Ver:%d.%d\n", SP[1], SP[0] ); - + //dbgprintf("MEMInitLow()...\n"); MEMInitLow(); @@ -208,6 +198,8 @@ int main( int argc, char *argv[] ) ConfigInit( (DML_CFG*)0x01200000 ); + ConfigSetConfig( DML_CFG_BOOT_DISC2 ); + if( !ConfigGetConfig(DML_CFG_BOOT_DISC) ) { if( DVDSelectGame() == DI_SUCCESS ) @@ -267,6 +259,27 @@ int main( int argc, char *argv[] ) PADLock = 0; } + if( DiscChangeIRQ ) + if( read32(HW_TIMER) * 128 / 243000000 > 2 ) + { + // dbgprintf("DIP:IRQ mon!\n"); + + //DVDGetDriveStatus + //write32( 0x01576D4, 0x38600000 ); + + while( read32(DI_SCONTROL) & 1 ) + clear32( DI_SCONTROL, 1 ); + + set32( DI_SSTATUS, 0x3A ); + + write32( 0x0d80000C, (1<<0) | (1<<4) ); + write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); + write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); + set32( 0x0d80000C, (1<<2) ); + + DiscChangeIRQ = 0; + } + if( (((read32(0x12FC) >> 16) & 0x1030) == 0x1030 ) ) { SysReset();