We are still looking for competent contributors (JPN and 480p results especially) for our
compatibility list ( http://crediar.no-ip.com/gc ) Please come to #DM on efnet if you want to help! IMPORTANT: The config version has been updated to 2! updated DM to version 2.1 *Improved patch code and made it more versatile *Improved .elf patching code (fixes Nightfire) *Improved No Disc patching *Added a hack for PSO I&II EUR/USA *Added the wide screen hack by Extrems *The NODISC config setting has been removed since it's been unused since 1.0 *Removed USBGecko debug output git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@18 be6c1b03-d731-4111-a574-e37d80d43941
This commit is contained in:
parent
0dabbeeb80
commit
07f92c2489
6
Config.h
6
Config.h
|
@ -44,7 +44,7 @@ typedef struct GC_SRAM
|
||||||
typedef struct DML_CFG
|
typedef struct DML_CFG
|
||||||
{
|
{
|
||||||
u32 Magicbytes; // 0xD1050CF6
|
u32 Magicbytes; // 0xD1050CF6
|
||||||
u32 Version; // 0x00000001
|
u32 Version; // 0x00000002
|
||||||
u32 VideoMode;
|
u32 VideoMode;
|
||||||
u32 Config;
|
u32 Config;
|
||||||
char GamePath[255];
|
char GamePath[255];
|
||||||
|
@ -62,9 +62,9 @@ enum dmlconfig
|
||||||
DML_CFG_CHEAT_PATH = (1<<6),
|
DML_CFG_CHEAT_PATH = (1<<6),
|
||||||
DML_CFG_ACTIVITY_LED= (1<<7),
|
DML_CFG_ACTIVITY_LED= (1<<7),
|
||||||
DML_CFG_PADHOOK = (1<<8),
|
DML_CFG_PADHOOK = (1<<8),
|
||||||
DML_CFG_NODISC = (1<<9),
|
DML_CFG_FORCE_WIDE = (1<<9),
|
||||||
DML_CFG_BOOT_DISC = (1<<10),
|
DML_CFG_BOOT_DISC = (1<<10),
|
||||||
DML_CFG_BOOT_DOL = (1<<11),
|
DML_CFG_BOOT_DISC2 = (1<<11),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dmlvideomode
|
enum dmlvideomode
|
||||||
|
|
234
Patches.c
234
Patches.c
|
@ -114,12 +114,23 @@ u8 GXMObjects[][0x3C] =
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u32 DVDGetDriveStatus[] = {
|
||||||
|
0x38600000, // li r3, 0
|
||||||
|
0x4E800020
|
||||||
|
};
|
||||||
|
|
||||||
FuncPattern FPatterns[] =
|
FuncPattern FPatterns[] =
|
||||||
{
|
{
|
||||||
{ 0xCC, 17, 10, 5, 3, 2, DVDInquiryAsync, sizeof(DVDInquiryAsync), "DVDInquiryAsync", 0, 0 },
|
{ 0xCC, 17, 10, 5, 3, 2, DVDInquiryAsync, sizeof(DVDInquiryAsync), "DVDInquiryAsync", 0, 0 },
|
||||||
{ 0xC8, 16, 9, 5, 3, 3, DVDSeekAbsAsyncPrio, sizeof(DVDSeekAbsAsyncPrio), "DVDSeekAbsAsyncPrio", 0, 0 },
|
{ 0xC8, 16, 9, 5, 3, 3, DVDSeekAbsAsyncPrio, sizeof(DVDSeekAbsAsyncPrio), "DVDSeekAbsAsyncPrio", 0, 0 },
|
||||||
|
{ 0xA8, 10, 4, 4, 6, 3, (u8*)DVDGetDriveStatus, sizeof(DVDGetDriveStatus), "DVDGetDriveStatus", 0, 0 },
|
||||||
{ 0xD4, 13, 8, 11, 2, 7, (u8*)NULL, 0xdead0004, "AIResetStreamSampleCount", 0, 0 },
|
{ 0xD4, 13, 8, 11, 2, 7, (u8*)NULL, 0xdead0004, "AIResetStreamSampleCount", 0, 0 },
|
||||||
|
|
||||||
|
{ 0x10C, 30, 18, 5, 2, 3, (u8*)NULL, 0xdead0002, "DVDLowRead A", 0, 0 },
|
||||||
|
{ 0xDC, 23, 18, 3, 2, 4, (u8*)NULL, 0xdead0002, "DVDLowRead B", 0, 0 },
|
||||||
|
|
||||||
|
{ 0xCC, 3, 3, 1, 0, 3, (u8*)NULL, 0xdead000C, "C_MTXPerspective", 0, 0 },
|
||||||
|
|
||||||
{ 0x94, 18, 10, 2, 0, 2, (u8*)__dvdLowReadAudioNULL, sizeof(__dvdLowReadAudioNULL), "DVDLowReadAudio", 0, 0 },
|
{ 0x94, 18, 10, 2, 0, 2, (u8*)__dvdLowReadAudioNULL, sizeof(__dvdLowReadAudioNULL), "DVDLowReadAudio", 0, 0 },
|
||||||
{ 0x88, 18, 8, 2, 0, 2, (u8*)__dvdLowAudioStatusNULL, sizeof(__dvdLowAudioStatusNULL), "DVDLowAudioStatus", 0, 0 },
|
{ 0x88, 18, 8, 2, 0, 2, (u8*)__dvdLowAudioStatusNULL, sizeof(__dvdLowAudioStatusNULL), "DVDLowAudioStatus", 0, 0 },
|
||||||
{ 0x98, 19, 8, 2, 1, 3, (u8*)__dvdLowAudioConfigNULL, sizeof(__dvdLowAudioConfigNULL), "DVDLowAudioConfig", 0, 0 },
|
{ 0x98, 19, 8, 2, 1, 3, (u8*)__dvdLowAudioConfigNULL, sizeof(__dvdLowAudioConfigNULL), "DVDLowAudioConfig", 0, 0 },
|
||||||
|
@ -199,6 +210,65 @@ void PatchBL( u32 dst, u32 src )
|
||||||
newval|= 0x48000001;
|
newval|= 0x48000001;
|
||||||
write32( src, newval );
|
write32( src, newval );
|
||||||
}
|
}
|
||||||
|
void PatchFunc( char *ptr )
|
||||||
|
{
|
||||||
|
u32 i = 0;
|
||||||
|
u32 reg=-1;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
u32 op = read32( (u32)ptr + i );
|
||||||
|
|
||||||
|
if( op == 0x4E800020 ) // blr
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( (op & 0xFC00FFFF) == 0x3C00CC00 ) // lis rX, 0xCC00
|
||||||
|
{
|
||||||
|
reg = (op & 0x3E00000) >> 21;
|
||||||
|
|
||||||
|
write32( (u32)ptr + i, (reg<<21) | 0x3C00C000 ); // Patch to: lis rX, 0xC000
|
||||||
|
dbgprintf("[%08X] %08X: lis r%u, 0xC000\n", (u32)ptr+i, read32( (u32)ptr+i), reg );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (op & 0xFC00FFFF) == 0x3C00A800 ) // lis rX, 0xA800
|
||||||
|
{
|
||||||
|
write32( (u32)ptr + i, (op & 0x3E00000) | 0x3C00A700 ); // Patch to: lis rX, 0xA700
|
||||||
|
dbgprintf("[%08X] %08X: lis rX, 0xA700\n", (u32)ptr+i, read32( (u32)ptr+i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (op & 0xFC00FFFF) == 0x38006000 ) // addi rX, rY, 0x6000
|
||||||
|
{
|
||||||
|
u32 src = (op >> 16) & 0x1F;
|
||||||
|
u32 dst = (op >> 21) & 0x1F;
|
||||||
|
|
||||||
|
if( src == reg )
|
||||||
|
{
|
||||||
|
write32( (u32)ptr + i, (dst<<21) | (src<<16) | 0x38002F00 ); // Patch to: addi rX, rY, 0x2F00
|
||||||
|
dbgprintf("[%08X] %08X: addi r%u, r%u, 0x2F00\n", (u32)ptr+i, read32( (u32)ptr+i), dst, src );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (op & 0xFC000000 ) == 0x90000000 )
|
||||||
|
{
|
||||||
|
u32 src = (op >> 16) & 0x1F;
|
||||||
|
u32 dst = (op >> 21) & 0x1F;
|
||||||
|
u32 val = op & 0xFFFF;
|
||||||
|
|
||||||
|
if( src == reg )
|
||||||
|
{
|
||||||
|
if( (val & 0xFF00) == 0x6000 ) // case with 0x60XY(rZ)
|
||||||
|
{
|
||||||
|
write32( (u32)ptr + i, (dst<<21) | (src<<16) | 0x2F00 | (val&0xFF) | 0x90000000 ); // Patch to: stw rX, 0x2FXY(rZ)
|
||||||
|
dbgprintf("[%08X] %08X: stw r%u, 0x%04X(r%u)\n", (u32)ptr+i, read32( (u32)ptr+i), dst, 0x2F00 | (val&0xFF), src );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
void MPattern( u8 *Data, u32 Length, FuncPattern *FunctionPattern )
|
void MPattern( u8 *Data, u32 Length, FuncPattern *FunctionPattern )
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
@ -453,126 +523,10 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
||||||
DoCardPatches( ptr, size, SectionOffset );
|
DoCardPatches( ptr, size, SectionOffset );
|
||||||
|
|
||||||
//Note: ORing the values prevents an early break out when a single patterns has multiple hits
|
//Note: ORing the values prevents an early break out when a single patterns has multiple hits
|
||||||
PatchCount=0;
|
PatchCount=1;
|
||||||
|
|
||||||
for( i=0; i < size; i+=4 )
|
for( i=0; i < size; i+=4 )
|
||||||
{
|
{
|
||||||
if( (PatchCount & 1) == 0 )
|
|
||||||
{
|
|
||||||
if( read32( (u32)ptr + i ) == 0x3C00A800 ) // Loader
|
|
||||||
{
|
|
||||||
int j=0;
|
|
||||||
while( read32( (u32)ptr + i - j ) != 0x7C0802A6 ) // Seek to start of function
|
|
||||||
j+=4;
|
|
||||||
|
|
||||||
//Check if there is a lis %rX, 0xCC00 in this function
|
|
||||||
//At least Sunshine has one false hit on lis r3,0xA800
|
|
||||||
int k=0;
|
|
||||||
while( 1 )
|
|
||||||
{
|
|
||||||
if( read32( (u32)ptr + i + k - j ) == 0x4E800020 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( (read32( (u32)ptr + i + k - j ) & 0xF81FFFFF) == 0x3800CC00 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
k += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( read32( (u32)ptr + i + k - j ) == 0x4E800020 )
|
|
||||||
{
|
|
||||||
//dbgprintf("Patch:No 0xCC00 found around:%08X\n", (u32)ptr+i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
u32 val = read32( (u32)ptr + i + k );
|
|
||||||
|
|
||||||
if( (val & 0xFFFF ) == 0xCC00 )
|
|
||||||
{
|
|
||||||
write32( (u32)ptr + i + k, (val&0xFFFF0000) | 0xC000 );
|
|
||||||
//dbgprintf("Patch:lis 0x%08X\n", (u32)ptr + i + k + SectionOffset );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (val & 0xFC00FF00) == 0x90006000 )
|
|
||||||
{
|
|
||||||
write32( (u32)ptr + i + k, (val&0xFFFF00FF) | 0x2F00 );
|
|
||||||
//dbgprintf("Patch:stw 0x%08X\n", (u32)ptr + i + k + SectionOffset );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( read32( (u32)ptr + i + k ) == 0x4E800020 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
k+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
write32( (u32)ptr + i, 0x3C00A700 );
|
|
||||||
|
|
||||||
dbgprintf("Patch:Found [DVDLowRead]: 0x%08X\n", (u32)ptr + i + SectionOffset );
|
|
||||||
|
|
||||||
PatchCount |= 1;
|
|
||||||
|
|
||||||
} else if( read32( (u32)ptr + i ) == 0x3C60A800 ) // Games
|
|
||||||
{
|
|
||||||
int j=0;
|
|
||||||
while( read32( (u32)ptr + i - j ) != 0x7C0802A6 ) // Seek to start of function
|
|
||||||
j+=4;
|
|
||||||
|
|
||||||
//Check if there is a lis %rX, 0xCC00 in this function
|
|
||||||
//At least Sunshine has one false hit on lis r3,0xA800
|
|
||||||
int k=0;
|
|
||||||
while( 1 )
|
|
||||||
{
|
|
||||||
if( read32( (u32)ptr + i + k - j ) == 0x4E800020 )
|
|
||||||
break;
|
|
||||||
if( (read32( (u32)ptr + i + k - j ) & 0xF81FFFFF) == 0x3800CC00 )
|
|
||||||
{
|
|
||||||
write32( (u32)ptr + i + k - j, (read32((u32)ptr + i + k - j) & 0xFFFF0000) | 0xC000 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
k += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( read32( (u32)ptr + i + k - j ) == 0x4E800020 )
|
|
||||||
{
|
|
||||||
//dbgprintf("Patch:No 0xCC00 found around:%08X\n", (u32)ptr+i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Search addi 0x6000
|
|
||||||
while( 1 )
|
|
||||||
{
|
|
||||||
if( read32( (u32)ptr + i + k - j ) == 0x4E800020 )
|
|
||||||
break;
|
|
||||||
if( (read32( (u32)ptr + i + k - j ) & 0xFFFF) == 0x6000 )
|
|
||||||
{
|
|
||||||
write32( (u32)ptr + i + k - j, (read32((u32)ptr + i + k - j) & 0xFFFF0000) | 0x2F00 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
k += 4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if( read32( (u32)ptr + i + k - j ) == 0x4E800020 )
|
|
||||||
{
|
|
||||||
//dbgprintf("Patch:No 0xCC00 found around:%08X\n", (u32)ptr+i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
write32( (u32)ptr + i, 0x3C60A700 );
|
|
||||||
|
|
||||||
dbgprintf("Patch:Found [DVDLowRead]: 0x%08X\n", (u32)ptr + i + SectionOffset );
|
|
||||||
|
|
||||||
PatchCount |= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (PatchCount & 2) == 0 )
|
if( (PatchCount & 2) == 0 )
|
||||||
if( (read32( (u32)ptr + i )&0xFC00FFFF) == 0x5400077A &&
|
if( (read32( (u32)ptr + i )&0xFC00FFFF) == 0x5400077A &&
|
||||||
(read32( (u32)ptr + i + 4 )&0xFC00FFFF) == 0x28000000 &&
|
(read32( (u32)ptr + i + 4 )&0xFC00FFFF) == 0x28000000 &&
|
||||||
|
@ -847,19 +801,6 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
||||||
|
|
||||||
switch( FPatterns[j].PatchLength )
|
switch( FPatterns[j].PatchLength )
|
||||||
{
|
{
|
||||||
case 0xdead0004: // Audiostreaming hack
|
|
||||||
{
|
|
||||||
switch( read32(0) >> 8 )
|
|
||||||
{
|
|
||||||
case 0x474544: // Eternal Darkness
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
write32( FOffset + 0xB4, 0x60000000 );
|
|
||||||
write32( FOffset + 0xC0, 0x60000000 );
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case 0xdead0001: // Patch for __GXSetVAT, fixes the dungeon map freeze in Wind Waker
|
case 0xdead0001: // Patch for __GXSetVAT, fixes the dungeon map freeze in Wind Waker
|
||||||
{
|
{
|
||||||
switch( read32(0) >> 8 )
|
switch( read32(0) >> 8 )
|
||||||
|
@ -879,6 +820,23 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case 0xdead0002: // DVDLowRead
|
||||||
|
{
|
||||||
|
PatchFunc( (char*)FOffset );
|
||||||
|
} break;
|
||||||
|
case 0xdead0004: // Audiostreaming hack
|
||||||
|
{
|
||||||
|
switch( read32(0) >> 8 )
|
||||||
|
{
|
||||||
|
case 0x474544: // Eternal Darkness
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
write32( FOffset + 0xB4, 0x60000000 );
|
||||||
|
write32( FOffset + 0xC0, 0x60000000 );
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case 0xdead000B: // PADRead hook
|
case 0xdead000B: // PADRead hook
|
||||||
{
|
{
|
||||||
//Find blr
|
//Find blr
|
||||||
|
@ -897,6 +855,22 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
||||||
PatchB( 0x2EE0, FOffset + j );
|
PatchB( 0x2EE0, FOffset + j );
|
||||||
write32( 0x12FC, 0 );
|
write32( 0x12FC, 0 );
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case 0xdead000C: // Widescreen hack by Extrems
|
||||||
|
{
|
||||||
|
if( !ConfigGetConfig(DML_CFG_FORCE_WIDE) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
dbgprintf("Patch:[MTXPerspectiveSig] 0x%08X \n", (u32)FOffset);
|
||||||
|
|
||||||
|
*(volatile float *)0x00000050 = 0.5625f;
|
||||||
|
memcpy((void*)(FOffset+ 28),(void*)(FOffset+ 36),44);
|
||||||
|
memcpy((void*)(FOffset+188),(void*)(FOffset+192),16);
|
||||||
|
*(unsigned int*)(FOffset+52) = 0x48000001 | ((*(unsigned int*)(FOffset+52) & 0x3FFFFFC) + 8);
|
||||||
|
*(unsigned int*)(FOffset+72) = 0x3C600000 | (0x80000050 >> 16); // lis 3, 0x8180
|
||||||
|
*(unsigned int*)(FOffset+76) = 0xC0230000 | (0x80000050 & 0xFFFF); // lfs 1, -0x1C (3)
|
||||||
|
*(unsigned int*)(FOffset+80) = 0xEC240072; // fmuls 1, 4, 1
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|
149
dip.c
149
dip.c
|
@ -16,6 +16,8 @@ u32 DOLOffset = 0;
|
||||||
s32 ELFNumberOfSections = 0;
|
s32 ELFNumberOfSections = 0;
|
||||||
u32 FSTMode = 0;
|
u32 FSTMode = 0;
|
||||||
|
|
||||||
|
extern DML_CFG *DMLCfg;
|
||||||
|
|
||||||
FIL GameFile;
|
FIL GameFile;
|
||||||
u32 read;
|
u32 read;
|
||||||
u32 DiscRead=0;
|
u32 DiscRead=0;
|
||||||
|
@ -46,8 +48,9 @@ void DIInit( void )
|
||||||
u32 DIUpdateRegisters( void )
|
u32 DIUpdateRegisters( void )
|
||||||
{
|
{
|
||||||
u32 read,i,j;
|
u32 read,i,j;
|
||||||
static u32 PatchState = 0;
|
static u32 PatchState = 0;
|
||||||
static u32 DOLReadSize= 0;
|
static u32 DOLReadSize = 0;
|
||||||
|
static u32 PSOHack = 0;
|
||||||
|
|
||||||
if( read32(DI_CONTROL) != 0xdeadbeef )
|
if( read32(DI_CONTROL) != 0xdeadbeef )
|
||||||
{
|
{
|
||||||
|
@ -145,9 +148,30 @@ u32 DIUpdateRegisters( void )
|
||||||
DoPatches( (char*)(0x01300000), Length, 0x80000000 );
|
DoPatches( (char*)(0x01300000), Length, 0x80000000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PSO 1&2
|
||||||
|
if( (read32(0) >> 8) == 0x47504F )
|
||||||
|
{
|
||||||
|
switch( Offset )
|
||||||
|
{
|
||||||
|
case 0x56B8E7E0: // AppSwitcher [EUR]
|
||||||
|
case 0x56C49600: // [USA]
|
||||||
|
{
|
||||||
|
DMLCfg->Config &= ~(DML_CFG_CHEATS|DML_CFG_PADHOOK|DML_CFG_DEBUGGER|DML_CFG_DEBUGWAIT);
|
||||||
|
|
||||||
|
DoPatches( (char*)Buffer, Length, 0x80000000 );
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case 0x5668FE20: // psov3.dol [EUR]
|
||||||
|
case 0x56750660: // [USA]
|
||||||
|
{
|
||||||
|
PSOHack = 1;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( PatchState == 0 )
|
if( PatchState == 0 )
|
||||||
{
|
{
|
||||||
if( Length == 0x100 )
|
if( Length == 0x100 || PSOHack )
|
||||||
{
|
{
|
||||||
if( read32( (u32)Buffer ) == 0x100 )
|
if( read32( (u32)Buffer ) == 0x100 )
|
||||||
{
|
{
|
||||||
|
@ -160,7 +184,7 @@ u32 DIUpdateRegisters( void )
|
||||||
for( i=0; i < 11; ++i )
|
for( i=0; i < 11; ++i )
|
||||||
DOLSize += dol->sizeData[i];
|
DOLSize += dol->sizeData[i];
|
||||||
|
|
||||||
DOLReadSize = sizeof(dolhdr);
|
DOLReadSize = Length;
|
||||||
|
|
||||||
DOLMinOff=0x81800000;
|
DOLMinOff=0x81800000;
|
||||||
DOLMaxOff=0;
|
DOLMaxOff=0;
|
||||||
|
@ -190,82 +214,83 @@ u32 DIUpdateRegisters( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
DOLMinOff -= 0x80000000;
|
DOLMinOff -= 0x80000000;
|
||||||
DOLMaxOff -= 0x80000000;
|
DOLMaxOff -= 0x80000000;
|
||||||
|
|
||||||
|
if( PSOHack )
|
||||||
|
{
|
||||||
|
DOLMinOff = Buffer;
|
||||||
|
DOLMaxOff = Buffer + DOLSize;
|
||||||
|
}
|
||||||
|
|
||||||
dbgprintf("DIP:DOLSize:%d DOLMinOff:0x%08X DOLMaxOff:0x%08X\n", DOLSize, DOLMinOff, DOLMaxOff );
|
dbgprintf("DIP:DOLSize:%d DOLMinOff:0x%08X DOLMaxOff:0x%08X\n", DOLSize, DOLMinOff, DOLMaxOff );
|
||||||
|
|
||||||
PatchState = 1;
|
PatchState = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PSOHack = 0;
|
||||||
|
|
||||||
} else if( read32(Buffer) == 0x7F454C46 )
|
} else if( read32(Buffer) == 0x7F454C46 )
|
||||||
{
|
{
|
||||||
if (getfilenamebyoffset(Offset) != NULL)
|
dbgprintf("DIP:Game is loading an ELF 0x%08x\n", Offset );
|
||||||
{
|
|
||||||
dbgprintf("DIP:The Game is loading %s\n", getfilenamebyoffset(Offset));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
dbgprintf("DIP:The Game is loading some .elf that is not in the fst...\n");
|
|
||||||
}
|
|
||||||
for (i = ((*(u32 *)0x00000038) & ~0x80000000) + 16; i < 0x01800000; i+=12) // Search the fst for the dvd offset of the .elf file
|
|
||||||
{
|
|
||||||
if (*(u32 *)i == Offset)
|
|
||||||
{
|
|
||||||
DOLSize = *(u32 *)(i+4);
|
|
||||||
DOLReadSize = Length;
|
|
||||||
|
|
||||||
if( DOLReadSize == DOLSize ) // The .elf is read completely already
|
DOLOffset = Offset;
|
||||||
{
|
DOLSize = 0;
|
||||||
dbgprintf("DIP:The .elf is read completely, file size: %u bytes\n", DOLSize);
|
|
||||||
DoPatches( (char*)(Buffer), Length, 0x80000000 );
|
if( Length > 0x1000 )
|
||||||
} else // a part of the .elf is read
|
{
|
||||||
{
|
DOLReadSize = Length;
|
||||||
PatchState = 2;
|
DoPatches( (char*)(Buffer), Length, 0x80000000 );
|
||||||
DOLMinOff=Buffer;
|
} else
|
||||||
DOLMaxOff=Buffer+Length;
|
DOLReadSize = 0;
|
||||||
if (Length <= 4096) // The .elf header is read
|
|
||||||
{
|
Elf32_Ehdr *ehdr = (Elf32_Ehdr*)Buffer;
|
||||||
ELFNumberOfSections = read16(Buffer+0x2c) -2; // Assume that 2 sections are .bss and .sbss which are not read
|
dbgprintf("DIP:ELF Programheader Entries:%u\n", ehdr->e_phnum );
|
||||||
dbgprintf("DIP:The .elf header is read(%u bytes), .elf file size: %u bytes, number of sections to load: %u\n", Length, DOLSize, ELFNumberOfSections);
|
|
||||||
} else // The .elf is read into a buffer
|
for( i=0; i < ehdr->e_phnum; ++i )
|
||||||
{
|
{
|
||||||
ELFNumberOfSections = -1; // Make sure that ELFNumberOfSections == 0 does not become true
|
Elf32_Phdr phdr;
|
||||||
dbgprintf("DIP:The .elf is read into a buffer, read progress: %u/%u bytes\n", Length, DOLSize);
|
|
||||||
}
|
if( FSTMode )
|
||||||
}
|
{
|
||||||
break;
|
FSTRead( (char*)&phdr, sizeof(Elf32_Phdr), DOLOffset + ehdr->e_phoff + i * sizeof(Elf32_Phdr) );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
f_lseek( &GameFile, DOLOffset + ehdr->e_phoff + i * sizeof(Elf32_Phdr) );
|
||||||
|
f_read( &GameFile, &phdr, sizeof(Elf32_Phdr), &read );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOLSize += (phdr.p_filesz+31) & (~31); // align by 32byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbgprintf("DIP:ELF size:%u\n", DOLSize );
|
||||||
|
|
||||||
|
PatchState = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ( PatchState != 0 )
|
} else if ( PatchState == 1 )
|
||||||
{
|
{
|
||||||
DOLReadSize += Length;
|
DOLReadSize += Length;
|
||||||
|
//dbgprintf("DIP:DOL ize:%d DOL read:%d\n", DOLSize, DOLReadSize );
|
||||||
if (PatchState == 2)
|
if( DOLReadSize >= DOLSize )
|
||||||
{
|
|
||||||
ELFNumberOfSections--;
|
|
||||||
|
|
||||||
// DOLMinOff and DOLMaxOff are optimised when loading .dol files
|
|
||||||
if (DOLMinOff > Buffer)
|
|
||||||
DOLMinOff = Buffer;
|
|
||||||
|
|
||||||
if (DOLMaxOff < Buffer+Length)
|
|
||||||
DOLMaxOff = Buffer+Length;
|
|
||||||
|
|
||||||
if (ELFNumberOfSections < 0)
|
|
||||||
{
|
|
||||||
dbgprintf("DIP:.elf read progress: %u/%u bytes\n", DOLReadSize, DOLSize);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
dbgprintf("DIP:.elf read progress: %u/%u bytes, sections left: %u\n", DOLReadSize, DOLSize, ELFNumberOfSections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//dbgprintf("DIP:DOLSize:%d DOLReadSize:%d\n", DOLSize, DOLReadSize );
|
|
||||||
if( DOLReadSize >= DOLSize || (PatchState == 2 && ELFNumberOfSections == 0))
|
|
||||||
{
|
{
|
||||||
DoPatches( (char*)(DOLMinOff), DOLMaxOff-DOLMinOff, 0x80000000 );
|
DoPatches( (char*)(DOLMinOff), DOLMaxOff-DOLMinOff, 0x80000000 );
|
||||||
PatchState = 0;
|
PatchState = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if ( PatchState == 2 )
|
||||||
|
{
|
||||||
|
DoPatches( (char*)(Buffer), Length, 0x80000000 );
|
||||||
|
|
||||||
|
if( Buffer > DOLMaxOff )
|
||||||
|
DOLMaxOff = Buffer;
|
||||||
|
|
||||||
|
DOLReadSize += Length;
|
||||||
|
//dbgprintf("DIP:ELF size:%d ELF read:%d\n", DOLSize, DOLReadSize );
|
||||||
|
if( DOLReadSize >= DOLSize )
|
||||||
|
{
|
||||||
|
PatchState = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write32( DI_SDMA_LEN, 0 );
|
write32( DI_SDMA_LEN, 0 );
|
||||||
|
|
1
dip.h
1
dip.h
|
@ -12,6 +12,7 @@
|
||||||
#include "vsprintf.h"
|
#include "vsprintf.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "DVD.h"
|
#include "DVD.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
enum opcodes
|
enum opcodes
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
preloader 0.30 - A tool which allows to change the default boot up sequence on the Wii console
|
||||||
|
|
||||||
|
Copyright (C) 2008-2009 crediar
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation version 2.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
unsigned short e_type;
|
||||||
|
unsigned short e_machine;
|
||||||
|
unsigned int e_version;
|
||||||
|
unsigned int e_entry;
|
||||||
|
unsigned int e_phoff;
|
||||||
|
unsigned int e_shoff;
|
||||||
|
unsigned int e_flags;
|
||||||
|
unsigned short e_ehsize;
|
||||||
|
unsigned short e_phentsize;
|
||||||
|
unsigned short e_phnum;
|
||||||
|
unsigned short e_shentsize;
|
||||||
|
unsigned short e_shnum;
|
||||||
|
unsigned short e_shstrndx;
|
||||||
|
} __attribute__((packed)) Elf32_Ehdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int sh_name;
|
||||||
|
unsigned int sh_type;
|
||||||
|
unsigned int sh_flags;
|
||||||
|
unsigned int sh_addr;
|
||||||
|
unsigned int sh_offset;
|
||||||
|
unsigned int sh_size;
|
||||||
|
unsigned int sh_link;
|
||||||
|
unsigned int sh_info;
|
||||||
|
unsigned int sh_addralign;
|
||||||
|
unsigned int sh_entsize;
|
||||||
|
} __attribute__((packed)) Elf32_Shdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int p_type;
|
||||||
|
unsigned int p_offset;
|
||||||
|
unsigned int p_vaddr;
|
||||||
|
unsigned int p_paddr;
|
||||||
|
unsigned int p_filesz;
|
||||||
|
unsigned int p_memsz;
|
||||||
|
unsigned int p_flags;
|
||||||
|
unsigned int p_align;
|
||||||
|
} __attribute__((packed)) Elf32_Phdr;
|
||||||
|
|
||||||
|
#define EI_MAG0 0
|
||||||
|
#define EI_MAG1 1
|
||||||
|
#define EI_MAG2 2
|
||||||
|
#define EI_MAG3 3
|
||||||
|
#define EI_CLASS 4
|
||||||
|
#define EI_DATA 5
|
||||||
|
#define EI_VERSION 6
|
||||||
|
#define EI_PAD 7
|
||||||
|
#define EI_NIDENT 16 //size of ident
|
2
global.h
2
global.h
|
@ -15,7 +15,7 @@
|
||||||
#define PADHOOK 1
|
#define PADHOOK 1
|
||||||
|
|
||||||
#define CONFIG_VERSION 0x00000001
|
#define CONFIG_VERSION 0x00000001
|
||||||
#define DM_VERSION 0x00020000
|
#define DM_VERSION 0x00020001
|
||||||
|
|
||||||
#define DI_SUCCESS 1
|
#define DI_SUCCESS 1
|
||||||
#define DI_ERROR 2
|
#define DI_ERROR 2
|
||||||
|
|
1
main.c
1
main.c
|
@ -122,7 +122,6 @@ void SysShutdown( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 fail;
|
u32 fail;
|
||||||
FIL Log;
|
|
||||||
|
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
|
|
31
vsprintf.c
31
vsprintf.c
|
@ -362,39 +362,8 @@ void GeckoSendBuffer( char *buffer )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern FIL Log;
|
|
||||||
|
|
||||||
static char buffer[128] ALIGNED(32);
|
|
||||||
int dbgprintf( const char *fmt, ...)
|
int dbgprintf( const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
vsprintf(buffer, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
//u32 cokie = read32( 0x0D800070 );
|
|
||||||
//set32(0x0D800070,1);
|
|
||||||
|
|
||||||
if( read32( 0x0D800070 ) & 1 )
|
|
||||||
{
|
|
||||||
GeckoSendBuffer( buffer );
|
|
||||||
}/* else {
|
|
||||||
u32 read;
|
|
||||||
u32 fres = f_open( &Log, "/dm.log", FA_READ|FA_WRITE|FA_OPEN_ALWAYS );
|
|
||||||
if( fres != FR_OK )
|
|
||||||
{
|
|
||||||
write32( 0x0D800070, 1 );
|
|
||||||
dbgprintf("f_open():%d\n", fres );
|
|
||||||
}
|
|
||||||
|
|
||||||
f_lseek( &Log, Log.fsize );
|
|
||||||
f_write( &Log, buffer, strlen(buffer), &read );
|
|
||||||
f_close( &Log );
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//write32( 0x0D800070, cokie );
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue