Compare commits

...

9 Commits
DML ... master

Author SHA1 Message Date
crediar@rypp.net
9ba08bec0f *Added the FatFS link map feature which should greatly decrease load times
git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@41 be6c1b03-d731-4111-a574-e37d80d43941
2014-07-02 08:34:53 +00:00
crediar@rypp.net
cb9fe32b8c -updated to version 2.10-
*Fixed a bug in the pattern detection code (DVDLowReadDiskID)


git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@40 be6c1b03-d731-4111-a574-e37d80d43941
2013-05-24 18:40:02 +00:00
crediar@rypp.net
bc58c3874f -updated to version 2.9-
*Changed patch code to prevent false hits (DVDLowReadDiskID)
*Added C_MTXLightPerspective patching (Fixes heat effects when using wide screen hack in Zelda:WW)




git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@38 be6c1b03-d731-4111-a574-e37d80d43941
2013-04-05 16:41:58 +00:00
crediar@rypp.net
7fa64ca726 -updated to version 2.8-
*Fixed a bug in GCLoader that broke the progressive patch
*Moved progressive patch back 16 bytes, this fixes PADHOOK and progressive patching not working at the same time

Thanks to FIX94 who sacrificed his school carer for testing this release!



git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@36 be6c1b03-d731-4111-a574-e37d80d43941
2013-02-24 19:16:28 +00:00
crediar@rypp.net
8e3d855eac -updated to version 2.7-
*Fixed a bug that caused a black screen when using PADHook and Progressive mode patching at the same time


git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@35 be6c1b03-d731-4111-a574-e37d80d43941
2013-02-20 13:51:24 +00:00
crediar@rypp.net
b6e6f8ca44 -updated to version 2.6-
*Reduced HDD read time out to 25 seconds
*Added two disc feature (Extracted format is unsupported)
 Use the latest DMToolBox (0.3 or higher) to install your two disc games

This will be the last version for some time, since I'm moving my focus to other things.

Always remember; Impossible is nothing!



git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@34 be6c1b03-d731-4111-a574-e37d80d43941
2012-11-30 21:46:19 +00:00
crediar@rypp.net
f808bbc8e0 Again another donation another feature. Thanks for donating!
-updated to version 2.5-

*Fixed a bug in DM that could cause a fatal read error when using devices with under 8GB size
*Added a PADHOOK pattern for Batman:Vengeance
*Added a screenshot feature
 This feature can be enabled/disabled via the DM(L) config
 Press R+Z on the fourth controller to take a screenshot any time!
 Screenshots will be saved to device:/screenshots in the YPbPr format, you can use my tool to convert them.


git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@33 be6c1b03-d731-4111-a574-e37d80d43941
2012-11-09 20:30:55 +00:00
crediar@rypp.net
894f641639 -updated to version 2.4-
*Fixed NMM for Mario Kart Double Dash. Saving ghost data works now as well
*Fixed a bug that would sometimes break cheating/debugging unless both were enabled
*Moved the VIConfigure patch to the ARM side which should fix a number of broken titles
*Changed the HDD time out to read a random sector
*Optimised the EHCI reset code
*Optimised the CARD code


git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@31 be6c1b03-d731-4111-a574-e37d80d43941
2012-10-21 21:36:35 +00:00
0xD15EA5E@gmail.com
8cebe92a4d -updated to version 2.3-
*Fixed creating NMM save file folders in FST mode
*Fixed CardFindEntryByName which incorrectly compared file names
*Added a hack for Phantasy Star Online 1&2 version 1.0
*GCLoader improvements that include warning the user if an incorrect CONFIG_VERSION is used
*Hardcoded the only worthy DVDGetDriveStatus patching, so once again the NODISC cfg doesn't do anything
*Removed unused code
*Removed unused files

git-svn-id: svn://localhost/Users/andi/Downloads/code/trunk@29 be6c1b03-d731-4111-a574-e37d80d43941
2012-09-24 14:03:20 +00:00
19 changed files with 638 additions and 345 deletions

191
Card.c
View File

@ -1,12 +1,16 @@
#include "Card.h" #include "Card.h"
FIL CardStat; FIL CardStat;
extern u32 FSTMode;
extern FIL GameFile;
void CardInit( void ) void CardInit( void )
{ {
FILINFO f; FILINFO f;
u32 i,wrote; u32 i,wrote;
CARDStat CStat; CARDStat CStat;
char GameID[0x20];
memset32( (void*)CARD_BASE, 0xdeadbeef, 0x20 ); memset32( (void*)CARD_BASE, 0xdeadbeef, 0x20 );
memset32( (void*)CARD_SHADOW, 0, 0x20 ); memset32( (void*)CARD_SHADOW, 0, 0x20 );
@ -18,10 +22,20 @@ void CardInit( void )
f_chdir("/saves"); f_chdir("/saves");
} }
if( f_chdir((const TCHAR*)0) != FR_OK ) if( FSTMode )
{ {
f_mkdir((const TCHAR*)0); FSTRead( (char*)GameID, 0x20, 0 );
f_chdir((const TCHAR*)0);
} else {
f_lseek( &GameFile, 0 );
f_read( &GameFile, (char*)GameID, 0x20, &wrote );
}
if( f_chdir(GameID) != FR_OK )
{
f_mkdir(GameID);
f_chdir(GameID);
} }
switch( f_stat( "stats.bin", &f ) ) switch( f_stat( "stats.bin", &f ) )
@ -57,6 +71,31 @@ void CardInit( void )
write32( 0x2FA0, 0 ); write32( 0x2FA0, 0 );
} }
void LFNfy( char *str )
{
u32 len = strlen(str);
u32 i;
for( i=0; i < len; ++i )
{
switch( str[i] )
{
case '\\':
case '/':
case '*':
case '|':
case '?':
case '<':
case '>':
case '\"':
case ':':
str[i] = ' ';
break;
default:
break;
}
}
}
s32 CardFindFreeEntry( void ) s32 CardFindFreeEntry( void )
{ {
CARDStat CStat; CARDStat CStat;
@ -89,7 +128,7 @@ s32 CardFindEntryByName( char *Filename )
f_lseek( &CardStat, sizeof(CARDStat) * i ); f_lseek( &CardStat, sizeof(CARDStat) * i );
f_read( &CardStat, &CStat, sizeof(CARDStat), &read ); f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
if( memcmp( Filename, CStat.fileName, strlen(Filename) ) == 0 ) if( strcmp( Filename, CStat.fileName ) == 0 )
{ {
//dbgprintf("CardFindEntryByName(%d,%s,%s)\n", i, Filename, CStat.fileName ); //dbgprintf("CardFindEntryByName(%d,%s,%s)\n", i, Filename, CStat.fileName );
return i; return i;
@ -112,6 +151,7 @@ s32 CardOpenFile( char *Filename, CARDFileInfo *CFInfo )
return -4; return -4;
} }
LFNfy( Filename );
fres = f_open( &savefile, Filename, FA_READ|FA_WRITE|FA_OPEN_EXISTING ) ; fres = f_open( &savefile, Filename, FA_READ|FA_WRITE|FA_OPEN_EXISTING ) ;
switch( fres ) switch( fres )
{ {
@ -144,7 +184,7 @@ s32 CardFastOpenFile( u32 FileNo, CARDFileInfo *CFInfo )
{ {
CARDStat CStat; CARDStat CStat;
FIL savefile; FIL savefile;
s32 fres; s32 Slot,fres;
u32 read; u32 read;
if( FileNo >= CARD_MAX_FILES ) if( FileNo >= CARD_MAX_FILES )
@ -162,6 +202,7 @@ s32 CardFastOpenFile( u32 FileNo, CARDFileInfo *CFInfo )
return 0; return 0;
} }
LFNfy( CStat.fileName );
fres = f_open( &savefile, CStat.fileName, FA_READ|FA_WRITE|FA_OPEN_EXISTING ) ; fres = f_open( &savefile, CStat.fileName, FA_READ|FA_WRITE|FA_OPEN_EXISTING ) ;
switch( fres ) switch( fres )
{ {
@ -317,7 +358,11 @@ void CardCreateFile( char *Filename, u32 Size, CARDFileInfo *CFInfo )
if( Slot < 0 ) if( Slot < 0 )
return; return;
fres = f_open( &savefile, Filename, FA_READ|FA_WRITE|FA_CREATE_NEW ); char FName[32];
memcpy( FName, Filename, 32 );
LFNfy( FName );
fres = f_open( &savefile, FName, FA_READ|FA_WRITE|FA_CREATE_NEW );
switch( fres ) switch( fres )
{ {
case FR_EXIST: case FR_EXIST:
@ -392,6 +437,7 @@ void CardReadFile( u32 FileNo, u8 *Buffer, u32 Length, u32 Offset )
f_lseek( &CardStat, sizeof(CARDStat) * FileNo ); f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
f_read( &CardStat, &CStat, sizeof(CARDStat), &read ); f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
LFNfy( CStat.fileName );
if( f_open( &savefile, CStat.fileName, FA_OPEN_EXISTING | FA_READ ) == FR_OK ) if( f_open( &savefile, CStat.fileName, FA_OPEN_EXISTING | FA_READ ) == FR_OK )
{ {
f_lseek( &savefile, Offset ); f_lseek( &savefile, Offset );
@ -409,6 +455,7 @@ void CardWriteFile( u32 FileNo, u8 *Buffer, u32 Length, u32 Offset )
f_lseek( &CardStat, sizeof(CARDStat) * FileNo ); f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
f_read( &CardStat, &CStat, sizeof(CARDStat), &read ); f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
LFNfy( CStat.fileName );
switch( f_open( &savefile, CStat.fileName, FA_OPEN_EXISTING | FA_WRITE ) ) switch( f_open( &savefile, CStat.fileName, FA_OPEN_EXISTING | FA_WRITE ) )
{ {
case FR_OK: case FR_OK:
@ -505,10 +552,10 @@ void CardUpdateStats( CARDStat *CStat )
CStat->offsetData = Offset; CStat->offsetData = Offset;
} }
u32 Device = 0;
void CARDUpdateRegisters( void ) void CARDUpdateRegisters( void )
{ {
u32 read; u32 read,i;
u32 CARDOK=0;
if( read32(CARD_CONTROL) != 0xdeadbeef ) if( read32(CARD_CONTROL) != 0xdeadbeef )
{ {
@ -524,19 +571,16 @@ void CARDUpdateRegisters( void )
write32( CARD_CONTROL, 0xdeadbeef ); write32( CARD_CONTROL, 0xdeadbeef );
#ifdef ACTIVITYLED if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) )
set32( HW_GPIO_OUT, 1<<5 ); set32( HW_GPIO_OUT, 1<<5 );
#endif
while( read32(CARD_CMD) == 0xdeadbeef ); while( read32(CARD_CMD) == 0xdeadbeef );
write32( CARD_SCMD, read32(CARD_CMD) ); write32( CARD_SCMD, read32(CARD_CMD) );
write32( CARD_CMD, 0xdeadbeef ); write32( CARD_CMD, 0xdeadbeef );
if( read32(CARD_CMD_1) != 0xdeadbeef ) while( read32(CARD_CMD_1) == 0xdeadbeef );
{
write32( CARD_SCMD_1, read32(CARD_CMD_1) ); write32( CARD_SCMD_1, read32(CARD_CMD_1) );
write32( CARD_CMD_1, 0xdeadbeef ); write32( CARD_CMD_1, 0xdeadbeef );
}
if( read32(CARD_CMD_2) != 0xdeadbeef ) if( read32(CARD_CMD_2) != 0xdeadbeef )
{ {
@ -565,12 +609,9 @@ void CARDUpdateRegisters( void )
default: default:
{ {
//EXIControl(1); //EXIControl(1);
dbgprintf("CARD:Unknown CMD:%08X %08X %08X %08X %08X %08X\n", read32(CARD_SCMD), read32(CARD_SCMD_1), read32(CARD_SCMD_2), read32(CARD_SCMD_3), read32(CARD_SCMD_4), read32(CARD_SCONTROL) ); dbgprintf("CARD:Unknown CMD:%08X %08X %08X %08X %08X %08X\n", read32(CARD_SCMD), read32(CARD_SCMD_1), read32(CARD_SCMD_2), read32(CARD_SCMD_3), read32(CARD_SCMD_4), read32(CARD_SCONTROL) );
Shutdown(); Shutdown();
} break; } break;
/* CARDOpen( char *FileName ) */ /* CARDOpen( char *FileName ) */
case 0xC0: case 0xC0:
{ {
@ -583,18 +624,9 @@ void CARDUpdateRegisters( void )
#ifdef CARDDEBUG #ifdef CARDDEBUG
dbgprintf("MC:CARDOpen( \"%s\", 0x%08x )", FileName, FInfo ); dbgprintf("MC:CARDOpen( \"%s\", 0x%08x )", FileName, FInfo );
#endif #endif
CardOpenFile( (char*)FileName, (CARDFileInfo*)FInfo ); CardOpenFile( (char*)FileName, (CARDFileInfo*)FInfo );
while( read32(CARD_CONTROL) & 1 ) CARDOK = 1;
clear32( CARD_CONTROL, 1 );
while( (read32(CARD_SSTATUS) & 0x10) != 0x10 )
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
} break; } break;
case 0xC1: case 0xC1:
{ {
@ -608,13 +640,7 @@ void CARDUpdateRegisters( void )
else else
write32( CARD_SRETURN, 0 ); write32( CARD_SRETURN, 0 );
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32(CARD_SRETURN) );
#endif
} break; } break;
case 0xC2: case 0xC2:
{ {
@ -627,25 +653,18 @@ void CARDUpdateRegisters( void )
#ifdef CARDDEBUG #ifdef CARDDEBUG
dbgprintf("MC:CARDCreate( \"%s\", 0x%04x, 0x%08x )", FileName, Size, FInfo ); dbgprintf("MC:CARDCreate( \"%s\", 0x%04x, 0x%08x )", FileName, Size, FInfo );
#endif #endif
CardCreateFile( (char*)FileName, Size, (CARDFileInfo*)FInfo ); CardCreateFile( (char*)FileName, Size, (CARDFileInfo*)FInfo );
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_CREATE ); write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_CREATE );
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
} break; } break;
case 0xC3: case 0xC3:
{ {
CARDStat CS; CARDStat CS;
#ifdef CARDDEBUG #ifdef CARDDEBUG
// dbgprintf("MC:CARDGetState( %d, 0x%08x, ", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)) ); dbgprintf("MC:CARDGetState( %d, 0x%08x, ", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)) );
#endif #endif
if( read32(CARD_SCMD_1) >= CARD_MAX_FILES ) if( read32(CARD_SCMD_1) >= CARD_MAX_FILES )
@ -666,11 +685,6 @@ void CARDUpdateRegisters( void )
write32( CARD_SRETURN, CARD_NO_FILE ); write32( CARD_SRETURN, CARD_NO_FILE );
} else { } else {
#ifdef CARDDEBUG
// dbgprintf("\"%s\")", CS.fileName );
dbgprintf("MC:CARDGetState( %d, 0x%08x, \"%s\"):0", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)), CS.fileName );
#endif
CardUpdateStats( &CS ); CardUpdateStats( &CS );
memcpy( (void*)0x1780, &CS, sizeof(CARDStat) ); memcpy( (void*)0x1780, &CS, sizeof(CARDStat) );
@ -703,14 +717,7 @@ void CARDUpdateRegisters( void )
write32( CARD_SRETURN, CARD_SUCCESS ); write32( CARD_SRETURN, CARD_SUCCESS );
} }
CARDOK = 1;
while( read32(CARD_SCONTROL) & 1 )
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
// dbgprintf("MC:CARDGetState( %d, 0x%08x, ):%d\n", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)), read32( CARD_SRETURN) );
#endif
} break; } break;
case 0xC4: case 0xC4:
{ {
@ -719,7 +726,6 @@ void CARDUpdateRegisters( void )
#ifdef CARDDEBUG #ifdef CARDDEBUG
dbgprintf("MC:CARDSetState( %d, 0x%08x )", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)) ); dbgprintf("MC:CARDSetState( %d, 0x%08x )", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)) );
#endif #endif
if( read32(CARD_SCMD_1) >= CARD_MAX_FILES ) if( read32(CARD_SCMD_1) >= CARD_MAX_FILES )
{ {
EXIControl(1); EXIControl(1);
@ -784,13 +790,7 @@ void CARDUpdateRegisters( void )
write32( CARD_SRETURN, CARD_SUCCESS ); write32( CARD_SRETURN, CARD_SUCCESS );
} }
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":1\n");
#endif
} break; } break;
/* CARDFastOpen( u32 FileNO, CARDFileInfo *CFInfo ) */ /* CARDFastOpen( u32 FileNO, CARDFileInfo *CFInfo ) */
case 0xC5: case 0xC5:
@ -801,19 +801,9 @@ void CARDUpdateRegisters( void )
#ifdef CARDDEBUG #ifdef CARDDEBUG
dbgprintf("MC:CARDFastOpen( %d, 0x%08X )", FileNo, FInfo ); dbgprintf("MC:CARDFastOpen( %d, 0x%08X )", FileNo, FInfo );
#endif #endif
CardFastOpenFile( FileNo, (CARDFileInfo*)FInfo ); CardFastOpenFile( FileNo, (CARDFileInfo*)FInfo );
while( read32(CARD_CONTROL) & 1 ) CARDOK = 1;
clear32( CARD_CONTROL, 1 );
while( (read32(CARD_SSTATUS) & 0x10) != 0x10 )
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
} break; } break;
case 0xC6: case 0xC6:
{ {
@ -828,13 +818,7 @@ void CARDUpdateRegisters( void )
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_DELETE ); write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_DELETE );
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
} break; } break;
case 0xC8: case 0xC8:
{ {
@ -846,7 +830,6 @@ void CARDUpdateRegisters( void )
#ifdef CARDDEBUG #ifdef CARDDEBUG
dbgprintf("MC:CARDWrite( %d, 0x%08x, 0x%04x, 0x%04x )", FileNo, Buffer, Offset, Length ); dbgprintf("MC:CARDWrite( %d, 0x%08x, 0x%04x, 0x%04x )", FileNo, Buffer, Offset, Length );
#endif #endif
if( FileNo >= CARD_MAX_FILES ) if( FileNo >= CARD_MAX_FILES )
{ {
EXIControl(1); EXIControl(1);
@ -860,14 +843,7 @@ void CARDUpdateRegisters( void )
write32( CARD_SRETURN, 0 ); write32( CARD_SRETURN, 0 );
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%u\n", read32(CARD_SRETURN) );
#endif
} break; } break;
case 0xC9: case 0xC9:
{ {
@ -879,7 +855,6 @@ void CARDUpdateRegisters( void )
#ifdef CARDDEBUG #ifdef CARDDEBUG
dbgprintf("MC:CARDRead( %d, 0x%08x, 0x%04x, 0x%04x )", FileNo, Buffer, Offset, Length ); dbgprintf("MC:CARDRead( %d, 0x%08x, 0x%04x, 0x%04x )", FileNo, Buffer, Offset, Length );
#endif #endif
if( FileNo >= CARD_MAX_FILES ) if( FileNo >= CARD_MAX_FILES )
{ {
EXIControl(1); EXIControl(1);
@ -893,14 +868,7 @@ void CARDUpdateRegisters( void )
write32( CARD_SRETURN, 0 ); write32( CARD_SRETURN, 0 );
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%u\n", read32(CARD_SRETURN) );
#endif
} break; } break;
case 0xCA: case 0xCA:
{ {
@ -912,13 +880,7 @@ void CARDUpdateRegisters( void )
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_DELETE ); write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_DELETE );
while( read32(CARD_SCONTROL) & 1 ) CARDOK = 1;
clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
} break; } break;
case 0xCB: case 0xCB:
{ {
@ -933,17 +895,22 @@ void CARDUpdateRegisters( void )
#endif #endif
CardRename( NameSrc, NameDst ); CardRename( NameSrc, NameDst );
CARDOK = 1;
} break;
}
if(CARDOK)
{
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
while( read32(CARD_SCONTROL) & 1 ) while( read32(CARD_SCONTROL) & 1 )
clear32( CARD_SCONTROL, 1 ); clear32( CARD_SCONTROL, 1 );
set32( CARD_SSTATUS, 0x10 ); set32( CARD_SSTATUS, 0x10 );
#ifdef CARDDEBUG
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
#endif
} break;
} }
#ifdef ACTIVITYLED
if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) )
clear32( HW_GPIO_OUT, 1<<5 ); clear32( HW_GPIO_OUT, 1<<5 );
#endif
} }
} }

5
Card.h
View File

@ -8,9 +8,7 @@
#include "vsprintf.h" #include "vsprintf.h"
#include "HW.h" #include "HW.h"
#include "vsprintf.h" #include "vsprintf.h"
#ifdef TRIFORCE
#include "JVSIOMessage.h"
#endif
#define CARD_MAX_FILES 128 #define CARD_MAX_FILES 128
#define CARD_BASE 0x00002F60 #define CARD_BASE 0x00002F60
@ -45,7 +43,6 @@
#define CARD_XFER_SETATTRIBUTES (1 * 8 * 1024) // CARDSetAttributes[Async] #define CARD_XFER_SETATTRIBUTES (1 * 8 * 1024) // CARDSetAttributes[Async]
#define CARD_XFER_WRITE (1 * 8 * 1024) // CARDWrite[Async] #define CARD_XFER_WRITE (1 * 8 * 1024) // CARDWrite[Async]
#define CARD_FILENAME_MAX 32 #define CARD_FILENAME_MAX 32
#define CARD_ICON_MAX 8 #define CARD_ICON_MAX 8

View File

@ -9,15 +9,15 @@ void ConfigInit( DML_CFG *Cfg )
memset32( DMLCfg, 0, sizeof(DML_CFG) ); memset32( DMLCfg, 0, sizeof(DML_CFG) );
//If a loader supplied any options we use them otherwise use the code defines //If a loader supplied any options we use them otherwise use the code defines
if( Cfg->Magicbytes == 0xD1050CF6 && Cfg->Version == CONFIG_VERSION ) if( Cfg->Magicbytes == 0xD1050CF6 )
{ {
memcpy( DMLCfg, Cfg, sizeof( DML_CFG ) ); memcpy( DMLCfg, Cfg, sizeof( DML_CFG ) );
} else { } else {
dbgprintf("No config found in RAM\n"); dbgprintf("No valid config found in RAM\n");
dbgprintf("Version:%08X\n", DMLCfg->Version ); dbgprintf("Version:%08X\n", DMLCfg->Version );
dbgprintf("Config:%08X\n", DMLCfg->Config ); dbgprintf("Config :%08X\n", DMLCfg->Config );
DMLCfg->Config = 0; DMLCfg->Config = 0;
#ifdef CHEATHOOK #ifdef CHEATHOOK
@ -41,9 +41,9 @@ void ConfigInit( DML_CFG *Cfg )
#ifdef PADHOOK #ifdef PADHOOK
DMLCfg->Config |= DML_CFG_PADHOOK; DMLCfg->Config |= DML_CFG_PADHOOK;
#endif #endif
DMLCfg->VideoMode = DML_VID_DML_AUTO;
DMLCfg->Version = CONFIG_VERSION;
DMLCfg->Magicbytes = 0xD1050CF6; DMLCfg->Magicbytes = 0xD1050CF6;
DMLCfg->Version = CONFIG_VERSION;
DMLCfg->VideoMode = DML_VID_DML_AUTO;
} }
//Check if a memcard is inserted in Slot A //Check if a memcard is inserted in Slot A
@ -59,6 +59,14 @@ inline u32 ConfigGetConfig( u32 Config )
{ {
return !!(DMLCfg->Config & Config); return !!(DMLCfg->Config & Config);
} }
inline void ConfigSetConfig( u32 Config )
{
DMLCfg->Config |= Config;
}
inline void ConfigClearConfig( u32 Config )
{
DMLCfg->Config &= ~Config;
}
u32 ConfigGetVideMode( void ) u32 ConfigGetVideMode( void )
{ {
return DMLCfg->VideoMode; return DMLCfg->VideoMode;

View File

@ -3,7 +3,6 @@
#include "string.h" #include "string.h"
#include "global.h" #include "global.h"
#include "ipc.h"
#include "alloc.h" #include "alloc.h"
#include "vsprintf.h" #include "vsprintf.h"
#include "HW.h" #include "HW.h"
@ -66,6 +65,7 @@ enum dmlconfig
DML_CFG_BOOT_DISC = (1<<10), DML_CFG_BOOT_DISC = (1<<10),
DML_CFG_BOOT_DISC2 = (1<<11), DML_CFG_BOOT_DISC2 = (1<<11),
DML_CFG_NODISC = (1<<12), DML_CFG_NODISC = (1<<12),
DML_CFG_SCREENSHOT = (1<<13),
}; };
enum dmlvideomode enum dmlvideomode
@ -90,6 +90,8 @@ enum VideoModes
void ConfigInit( DML_CFG *Cfg ); void ConfigInit( DML_CFG *Cfg );
u32 ConfigGetConfig( u32 Config ); u32 ConfigGetConfig( u32 Config );
void ConfigSetConfig( u32 Config );
void ConfigClearConfig( u32 Config );
u32 ConfigGetVideMode( void ); u32 ConfigGetVideMode( void );
char *ConfigGetGamePath( void ); char *ConfigGetGamePath( void );

61
DVD.c
View File

@ -13,15 +13,28 @@ u8 HardDriveConnected;
FATFS fatfs; FATFS fatfs;
static u8 *FSTable ALIGNED(32); static u8 *FSTable ALIGNED(32);
u32 ApploaderSize=0;
u32 dolOffset=0; u32 ApploaderSize = 0;
u32 FSTableSize=0; u32 dolOffset = 0;
u32 FSTableOffset=0; u32 FSTableSize = 0;
u32 FSTableOffset = 0;
u32 FCEntry=0; u32 FCEntry=0;
FileCache FC[FILECACHE_MAX]; FileCache FC[FILECACHE_MAX];
u32 FCState[FILECACHE_MAX]; u32 FCState[FILECACHE_MAX];
DWORD LTable[0x1D0];
static void DVDCreateLinkMap( FIL *File )
{
GameFile.cltbl = LTable;
GameFile.cltbl[0] = sizeof(LTable);
s32 fres = f_lseek( &GameFile, CREATE_LINKMAP );
if( fres == FR_NOT_ENOUGH_CORE )
{
GameFile.cltbl = NULL;
}
}
void DVDInit( void ) void DVDInit( void )
{ {
int i=0; int i=0;
@ -65,7 +78,7 @@ void DVDInit( void )
default: default:
case FR_DISK_ERR: case FR_DISK_ERR:
{ {
dbgprintf( "DIP: Disk error\n", fres ); dbgprintf( "DIP:Disk error\n", fres );
while(1); while(1);
} break; } break;
} }
@ -73,7 +86,7 @@ void DVDInit( void )
if( fres != FR_OK ) if( fres != FR_OK )
{ {
dbgprintf( "Could not find any USB device!"); dbgprintf( "DIP:Could not find any USB device!");
} }
return; return;
@ -81,13 +94,14 @@ void DVDInit( void )
s32 DVDSelectGame( void ) s32 DVDSelectGame( void )
{ {
char *str = (char*)malloca( 256, 32 ); char *str = (char*)malloca( 256, 32 );
u32 i=0;
if( ConfigGetConfig(DML_CFG_GAME_PATH) ) if( ConfigGetConfig(DML_CFG_GAME_PATH) )
{ {
sprintf( str, "%s", ConfigGetGamePath() ); sprintf( str, "%s", ConfigGetGamePath() );
} else { } else {
dbgprintf("No game path was supplied!\n"); dbgprintf("DIP:No game path was supplied!\n");
free(str); free(str);
return -1; return -1;
} }
@ -100,13 +114,42 @@ s32 DVDSelectGame( void )
//Try to switch to FST mode //Try to switch to FST mode
if( !FSTInit() ) 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); free(str);
return -2; return -2;
} }
} else { } 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;
}
DVDCreateLinkMap(&GameFile);
f_lseek( &GameFile, 0 ); f_lseek( &GameFile, 0 );
f_read( &GameFile, (void*)0, 0x20, &read ); f_read( &GameFile, (void*)0, 0x20, &read );
@ -287,6 +330,8 @@ void FSTRead( char *Buffer, u32 Length, u32 Offset )
FC[FCEntry].Offset = fe[i].FileOffset; FC[FCEntry].Offset = fe[i].FileOffset;
FCState[FCEntry] = 0x23; FCState[FCEntry] = 0x23;
DVDCreateLinkMap(&(FC[FCEntry].File));
f_lseek( &(FC[FCEntry].File), nOffset ); f_lseek( &(FC[FCEntry].File), nOffset );
f_read( &(FC[FCEntry].File), Buffer, Length, &read ); f_read( &(FC[FCEntry].File), Buffer, Length, &read );

1
HW.h
View File

@ -4,7 +4,6 @@
#include "string.h" #include "string.h"
#include "global.h" #include "global.h"
#include "memory.h" #include "memory.h"
#include "ipc.h"
#include "alloc.h" #include "alloc.h"
#include "dip.h" #include "dip.h"

302
Patches.c
View File

@ -6,6 +6,18 @@
#include "CheatCode.c" #include "CheatCode.c"
extern u32 DOLSize; extern u32 DOLSize;
u32 FrameBuffer = 0;
u32 FBOffset = 0;
u32 FBEnable = 0;
u32 FBSize = 0;
unsigned char VISetFB[] =
{
0x38, 0x7F, 0x00, 0xF0, // mr %r3, %r7
0x38, 0x9F, 0x01, 0x24,
0x38, 0xBF, 0x01, 0x28,
0x38, 0xDF, 0x01, 0x3C,
};
unsigned char OSReportDM[] = unsigned char OSReportDM[] =
{ {
@ -132,6 +144,7 @@ FuncPattern FPatterns[] =
{ 0xCC, 3, 3, 1, 0, 3, (u8*)NULL, 0xdead000C, "C_MTXPerspective", 0, 0 }, { 0xCC, 3, 3, 1, 0, 3, (u8*)NULL, 0xdead000C, "C_MTXPerspective", 0, 0 },
{ 0xC8, 3, 3, 1, 0, 3, (u8*)NULL, 0xdead000D, "C_MTXLightPerspective", 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 },
@ -147,7 +160,7 @@ FuncPattern FPatterns[] =
{ 0x2FC, 73, 8, 23, 16, 15, (u8*)NULL, 0xdead000B, "PADRead B", 2, 0 }, { 0x2FC, 73, 8, 23, 16, 15, (u8*)NULL, 0xdead000B, "PADRead B", 2, 0 },
{ 0x3B0, 87, 13, 27, 17, 25, (u8*)NULL, 0xdead000B, "PADRead C", 2, 0 }, { 0x3B0, 87, 13, 27, 17, 25, (u8*)NULL, 0xdead000B, "PADRead C", 2, 0 },
{ 0x334, 78, 7, 20, 17, 19, (u8*)NULL, 0xdead000B, "PADRead D", 2, 0 }, { 0x334, 78, 7, 20, 17, 19, (u8*)NULL, 0xdead000B, "PADRead D", 2, 0 },
{ 0x2A8, 66, 4, 20, 17, 14, (u8*)NULL, 0xdead000B, "PADRead E", 2, 0 },
}; };
FuncPattern CPatterns[] = FuncPattern CPatterns[] =
@ -197,7 +210,97 @@ FuncPattern CPatterns[] =
u32 CardLowestOff = 0; u32 CardLowestOff = 0;
u32 FB[MAX_FB];
void SMenuAddFramebuffer( void )
{
u32 i,j,f;
if( *(vu32*)FBEnable != 1 )
return;
FrameBuffer = (*(vu32*)FBOffset) & 0x7FFFFFFF;
for( i=0; i < MAX_FB; i++)
{
if( FB[i] ) //add a new entry
continue;
//check if we already know this address
f=0;
for( j=0; j<i; ++j )
{
if( FrameBuffer == FB[j] ) // already known!
{
f=1;
return;
}
}
if( !f && FrameBuffer && FrameBuffer < 0x14000000 ) // add new entry
{
dbgprintf("ES:Added new FB[%d]:%08X\n", i, FrameBuffer );
FB[i] = FrameBuffer;
switch( *(vu32*)(FBEnable+0x20) )
{
case VI_NTSC:
FBSize = 304*480*4;
break;
case VI_PAL:
FBSize = 320*480*4;
break;
case VI_EUR60:
FBSize = 320*480*4;
break;
default:
dbgprintf("ES:SMenuFindOffsets():Invalid Video mode:%d\n", *(vu32*)(FBEnable+0x20) );
break;
}
}
}
}
void ScreenShot( void )
{
if( *(vu32*)FBEnable != 1 )
return;
set32( HW_GPIO_OUT, 1<<5 );
char *str = (char*)malloc( 64 );
u32 i=0,r,wrote;
FIL SCRFile;
sprintf( str, "/screenshots" );
f_mkdir( str );
do
{
sprintf( str, "/screenshots/scrn_%02X.raw", i++ );
r = f_open( &SCRFile, str, FA_CREATE_NEW|FA_WRITE );
if( r == FR_OK )
{
break;
} else {
if( r != FR_EXIST )
{
dbgprintf("Failed to create file:%u\n", r );
clear32( HW_GPIO_OUT, 1<<5 );
return;
}
}
} while(1);
free(str);
if( r == FR_OK )
{
f_write( &SCRFile, (void*)(FB[0]), FBSize, &wrote );
f_close( &SCRFile );
}
clear32( HW_GPIO_OUT, 1<<5 );
}
void PatchB( u32 dst, u32 src ) void PatchB( u32 dst, u32 src )
{ {
u32 newval = (dst - src); u32 newval = (dst - src);
@ -452,11 +555,16 @@ void DoCardPatches( char *ptr, u32 size, u32 SectionOffset )
if( (read32( offset + 0x04 ) & 0x0000F000 ) == 0x00008000 ) // lis if( (read32( offset + 0x04 ) & 0x0000F000 ) == 0x00008000 ) // lis
{ {
write32( offset, read32( offset + 0x0C ) & 0xFBE00000 ); write32( offset, read32( offset + 0x0C ) & 0xFBE00000 );
offset += 4;
if( CPatterns[j].Patch == CARDCheckEX )
{
write32( offset, 0x38800000 ); // lis r4,0
offset += 4;
}
//Forge a branch to the async function //Forge a branch to the async function
offset += 4;
u32 newval = ((u32)ptr + i) - offset; u32 newval = ((u32)ptr + i) - offset;
newval&= 0x03FFFFFC; newval&= 0x03FFFFFC;
newval|= 0x48000000; newval|= 0x48000000;
@ -478,18 +586,28 @@ void DoCardPatches( char *ptr, u32 size, u32 SectionOffset )
} }
} }
for( j=0; j < sizeof(CPatterns)/sizeof(FuncPattern); ++j )
{ //if( CardLowestOff )
if( CPatterns[j].Found == 0 ) //{
dbgprintf("Pattern %s not found!\n", CPatterns[j].Name ); // for( j=0; j < sizeof(CPatterns)/sizeof(FuncPattern); ++j )
} // {
// if( CPatterns[j].Found == 0 )
// dbgprintf("Pattern %s not found!\n", CPatterns[j].Name );
// }
//}
return; return;
} }
void DoPatches( char *ptr, u32 size, u32 SectionOffset ) void DoPatches( char *ptr, u32 size, u32 SectionOffset )
{ {
u32 i=0,j=0,k=0,value; u32 i=0,j=0,k=0,value;
u32 PatchCount = 0; u32 PatchCount = 0;
u32 r13 = 0;
FBOffset = 0;
FBEnable = 0;
CardLowestOff = 0;
dbgprintf("DoPatches( 0x%p, %d, 0x%X)\n", ptr, size, SectionOffset ); dbgprintf("DoPatches( 0x%p, %d, 0x%X)\n", ptr, size, SectionOffset );
@ -517,10 +635,12 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
write32(0x00003194, 0x48000028); write32(0x00003194, 0x48000028);
} }
// Reset Found // Reset Found
for( k=0; k < sizeof(FPatterns)/sizeof(FuncPattern); ++k ) for( k=0; k < sizeof(FPatterns)/sizeof(FuncPattern); ++k )
FPatterns[k].Found = 0; FPatterns[k].Found = 0;
if( ConfigGetConfig(DML_CFG_NMM) ) if( ConfigGetConfig(DML_CFG_NMM) )
DoCardPatches( ptr, size, SectionOffset ); DoCardPatches( ptr, size, SectionOffset );
@ -530,10 +650,10 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
for( i=0; i < size; i+=4 ) for( i=0; i < size; i+=4 )
{ {
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 &&
read32( (u32)ptr + i + 8 ) == 0x41820008 && read32( (u32)ptr + i + 8 ) == 0x41820008 &&
(read32( (u32)ptr + i +12 )&0xFC00FFFF) == 0x64002000 (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 ); dbgprintf("Patch:Found [__OSDispatchInterrupt]: 0x%08X 0x%08X\n", (u32)ptr + i + 0 + SectionOffset, (u32)ptr + i + 0x1A8 + SectionOffset );
@ -678,10 +798,10 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
if( f_open( &CodeFD, path, FA_OPEN_EXISTING|FA_READ ) == FR_OK ) if( f_open( &CodeFD, path, FA_OPEN_EXISTING|FA_READ ) == FR_OK )
{ {
if( CodeFD.fsize >= 0x2E80 - (0x1800+DBGSize-8) ) if( CodeFD.fsize >= 0x2E60 - (0x1800+DBGSize-8) )
{ {
dbgprintf("Patch:Cheatfile is too large, it must not be large than %d bytes!\n", dbgprintf("Patch:Cheatfile is too large, it must not be large than %d bytes!\n",
0x2E80 - (0x1800+DBGSize-8)); 0x2E60 - (0x1800+DBGSize-8));
} else { } else {
if( f_read( &CodeFD, (void*)(0x1800+DBGSize-8), CodeFD.fsize, &read ) == FR_OK ) if( f_read( &CodeFD, (void*)(0x1800+DBGSize-8), CodeFD.fsize, &read ) == FR_OK )
{ {
@ -736,12 +856,128 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
} }
} }
if( ConfigGetConfig(DML_CFG_CHEATS) ) if( (PatchCount & 64) == 0 )
{ {
if( PatchCount == 63 ) if( read32( (u32)ptr + i + 0 ) == 0x3C608000 )
{
if( ((read32( (u32)ptr + i + 4 ) & 0xFC1FFFFF ) == 0x800300CC) && ((read32( (u32)ptr + i + 8 ) >> 24) == 0x54 ) )
{
dbgprintf( "Patch:[VIConfgiure] 0x%08X\n", (u32)(ptr+i) );
write32( *(vu32*)(ptr+i+4), 0x5400F0BE | ((read32( (u32)ptr + i + 4 ) & 0x3E00000) >> 5 ) );
PatchCount |= 64;
}
}
}
if( (PatchCount & 128) == 0 )
{
if( ConfigGetConfig(DML_CFG_SCREENSHOT) )
{
if( *(u32*)(ptr+i) >> 16 == 0x3DA0 && r13 == 0 )
{
r13 = ((*(u32*)(ptr+i)) & 0xFFFF) << 16;
r13|= (*(u32*)(ptr+i+4)) & 0xFFFF;
dbgprintf("Patch:r13:%08X\n", r13 );
}
if( memcmp( ptr+i, VISetFB, sizeof(VISetFB) ) == 0 && FBEnable == 0 )
{
dbgprintf("Patch:[VISetFB]%08X\n", (u32)ptr+i );
FBEnable = ( *(u32*)(ptr+i-4) );
if( FBEnable & 0x8000 )
{
FBEnable = ((~FBEnable) & 0xFFFF) + 1;
FBEnable = (r13 - FBEnable) & 0x7FFFFFF;
} else {
FBEnable = FBEnable & 0xFFFF;
FBEnable = (r13 + FBEnable) & 0x7FFFFFF;
}
FBOffset = FBEnable - 0x08;
// dbgprintf("FBOffset:%08X\n", FBOffset );
// dbgprintf("FBEnable:%08X\n", FBEnable );
for( j=0; j < MAX_FB; ++j )
FB[j] = 0;
PatchCount |= 128;
}
} else {
PatchCount |= 128;
}
}
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 ) & 0xFC00FFFF ) == 0x3C00A800 && (read32( (u32)ptr + i + 4 ) & 0xFC00FFFF ) == 0x38000040 )
{
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 == 1023 )
break; break;
} else { } else {
if( PatchCount == 47 ) if( PatchCount == 1007 )
break; break;
} }
} }
@ -856,26 +1092,45 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
dbgprintf("Patch:[PADRead hook] %08X\n", FOffset + j ); dbgprintf("Patch:[PADRead hook] %08X\n", FOffset + j );
memcpy( (void*)0x2EE0, padipc, sizeof(padipc) ); memcpy( (void*)0x2ECC, padipc, sizeof(padipc) );
PatchB( 0x2EE0, FOffset + j ); PatchB( 0x2ECC, FOffset + j );
write32( 0x12FC, 0 ); write32( 0x12FC, 0 );
} break; } break;
case 0xdead000C: // Widescreen hack by Extrems // Widescreen hack by Extrems
case 0xdead000C: // C_MTXPerspective
{ {
if( !ConfigGetConfig(DML_CFG_FORCE_WIDE) ) if( !ConfigGetConfig(DML_CFG_FORCE_WIDE) )
break; break;
dbgprintf("Patch:[MTXPerspectiveSig] 0x%08X \n", (u32)FOffset);
*(volatile float *)0x00000050 = 0.5625f; *(volatile float *)0x00000050 = 0.5625f;
memcpy((void*)(FOffset+ 28),(void*)(FOffset+ 36),44); memcpy((void*)(FOffset+ 28),(void*)(FOffset+ 36),44);
memcpy((void*)(FOffset+188),(void*)(FOffset+192),16); memcpy((void*)(FOffset+188),(void*)(FOffset+192),16);
*(unsigned int*)(FOffset+52) = 0x48000001 | ((*(unsigned int*)(FOffset+52) & 0x3FFFFFC) + 8); *(unsigned int*)(FOffset+52) = 0x48000001 | ((*(unsigned int*)(FOffset+52) & 0x3FFFFFC) + 8);
*(unsigned int*)(FOffset+72) = 0x3C600000 | (0x80000050 >> 16); // lis 3, 0x8180 *(unsigned int*)(FOffset+72) = 0x3C600000 | (0x80000050 >> 16); // lis 3, 0x8180
*(unsigned int*)(FOffset+76) = 0xC0230000 | (0x80000050 & 0xFFFF); // lfs 1, -0x1C (3) *(unsigned int*)(FOffset+76) = 0xC0230000 | (0x80000050 & 0xFFFF); // lfs 1, -0x1C (3)
*(unsigned int*)(FOffset+80) = 0xEC240072; // fmuls 1, 4, 1 *(unsigned int*)(FOffset+80) = 0xEC240072; // fmuls 1, 4, 1
} break;
case 0xdead000D: // C_MTXLightPerspective
{
if( !ConfigGetConfig(DML_CFG_FORCE_WIDE) )
break;
*(volatile float *)0x00000050 = 0.5625f;
*(u32*)(FOffset+36) = *(u32*)(FOffset+32);
memcpy((void*)(FOffset+ 28),(void*)(FOffset+ 36),60);
memcpy((void*)(FOffset+184),(void*)(FOffset+188),16);
*(u32*)(FOffset+68) += 8;
*(u32*)(FOffset+88) = 0x3C600000 | (0x80000050 >> 16); // lis 3, 0x8180
*(u32*)(FOffset+92) = 0xC0230000 | (0x80000050 & 0xFFFF); // lfs 1, -0x90 (3)
*(u32*)(FOffset+96) = 0xEC240072; // fmuls 1, 4, 1
} break; } break;
default: default:
{ {
@ -887,8 +1142,11 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
if( FPatterns[j].Patch == (u8*)DVDGetDriveStatus ) if( FPatterns[j].Patch == (u8*)DVDGetDriveStatus )
{ {
if( !ConfigGetConfig( DML_CFG_NODISC ) ) if( (read32(0) >> 8) != 0x474754 && // Chibi-Robo!
(read32(0) >> 8) != 0x475041 ) // Pokémon Channel
break; break;
dbgprintf("Patch:DVDGetDriveStatus\n");
} }
if( (FPatterns[j].Length >> 16) == 0xdead ) if( (FPatterns[j].Length >> 16) == 0xdead )

View File

@ -3,7 +3,6 @@
#include "string.h" #include "string.h"
#include "global.h" #include "global.h"
#include "ipc.h"
#include "alloc.h" #include "alloc.h"
#include "ff.h" #include "ff.h"
#include "vsprintf.h" #include "vsprintf.h"
@ -11,6 +10,7 @@
#include "dol.h" #include "dol.h"
#include "Config.h" #include "Config.h"
#define MAX_FB 3
typedef struct PatchInfo typedef struct PatchInfo
{ {
@ -61,14 +61,22 @@ typedef struct _gx_rmodeobj {
u8 vfilter[7]; u8 vfilter[7];
} GXRModeObj; } GXRModeObj;
#define VI_NTSC 0
#define VI_PAL 1
#define VI_MPAL 2
#define VI_DEBUG 3
#define VI_DEBUG_PAL 4
#define VI_EUR60 5
#define GXPal528IntDf 0 #define GXPal528IntDf 0
#define GXEurgb60Hz480IntDf 1 #define GXEurgb60Hz480IntDf 1
#define GXMpal480IntDf 2 #define GXMpal480IntDf 2
#define GXNtsc480IntDf 3 #define GXNtsc480IntDf 3
#define GXNtsc480Int 4 #define GXNtsc480Int 4
void SMenuAddFramebuffer( void );
void PatchGCIPL( void ); void ScreenShot( void );
void DoPatches( char *ptr, u32 size, u32 SectionOffset ); void DoPatches( char *ptr, u32 size, u32 SectionOffset );
void DoCardPatches( char *ptr, u32 size, u32 SectionOffset ); void DoCardPatches( char *ptr, u32 size, u32 SectionOffset );
void DoPatchesLoader( char *ptr, u32 size ); void DoPatchesLoader( char *ptr, u32 size );

View File

@ -19,7 +19,8 @@ DoCode:
mflr %r0 mflr %r0
stw %r0, 4(%sp) stw %r0, 4(%sp)
stwu %sp, -0x10(%sp) stwu %sp, -0x28(%sp)
stmw %r27, 0x14(%sp)
#send cmd to DM #send cmd to DM
@ -81,8 +82,9 @@ skip_cb:
lwz %r3, 0x2F94(%r7) lwz %r3, 0x2F94(%r7)
mr %r4, %r3 mr %r4, %r3
lwz %r0, 0x14(%sp) lmw %r27, 0x14(%sp)
addi %sp, %sp, 0x10 lwz %r0, 0x2C(%sp)
addi %sp, %sp, 0x28
mtlr %r0 mtlr %r0
blr blr

View File

@ -7,12 +7,12 @@
# r6 offset # r6 offset
# r7 cb # r7 cb
CardWrite: CardRead:
mflr %r0 mflr %r0
stw %r0, 4(%sp) stw %r0, 4(%sp)
stwu %sp, -0x20(%sp) stwu %sp, -0x28(%sp)
stw %r31, 0x1C(%sp) stmw %r27, 0x14(%sp)
#Update fileinfo #Update fileinfo
stw %r5, 0x0C(%r3) stw %r5, 0x0C(%r3)
@ -66,17 +66,17 @@ wait_loop:
cmpwi %r12, 0 cmpwi %r12, 0
beq skip_cb beq skip_cb
mtctr %r12 mtlr %r12
li %r3, 0 li %r3, 0
li %r4, 0 li %r4, 0
bctrl blrl
skip_cb: skip_cb:
li %r3, 0 li %r3, 0
mr %r4, %r3 mr %r4, %r3
lwz %r0, 0x24(%sp) lmw %r27, 0x14(%sp)
lwz %r31, 0x1C(%sp) lwz %r0, 0x2C(%sp)
addi %sp, %sp, 0x20 addi %sp, %sp, 0x28
mtlr %r0 mtlr %r0
blr blr

View File

@ -11,7 +11,8 @@ CardWrite:
mflr %r0 mflr %r0
stw %r0, 4(%sp) stw %r0, 4(%sp)
stwu %sp, -0x10(%sp) stwu %sp, -0x28(%sp)
stmw %r27, 0x14(%sp)
#Update fileinfo #Update fileinfo
stw %r5, 0x0C(%r3) stw %r5, 0x0C(%r3)
@ -65,16 +66,17 @@ wait_loop:
cmpwi %r12, 0 cmpwi %r12, 0
beq skip_cb beq skip_cb
mtctr %r12 mtlr %r12
li %r3, 0 li %r3, 0
li %r4, 0 li %r4, 0
bctrl blrl
skip_cb: skip_cb:
li %r3, 0 li %r3, 0
mr %r4, %r3 mr %r4, %r3
lwz %r0, 0x14(%sp) lmw %r27, 0x14(%sp)
addi %sp, %sp, 0x10 lwz %r0, 0x2C(%sp)
addi %sp, %sp, 0x28
mtlr %r0 mtlr %r0
blr blr

View File

@ -4,8 +4,15 @@
PADRead: PADRead:
lis %r4, 0xCC00 lis %r4, 0xCC00
lwz %r5, 0x6428(%r4)
lwz %r0, 0x642C(%r4)
lwz %r0, 0x6404(%r4) lwz %r0, 0x6404(%r4)
lwz %r4, 0x6408(%r4) lwz %r4, 0x6408(%r4)
lis %r4, 0xC000 lis %r4, 0xC000
stw %r0, 0x12FC(%r4) stw %r0, 0x12FC(%r4)
stw %r5, 0x12F8(%r4)
blr blr

45
dip.c
View File

@ -15,6 +15,7 @@ u32 DOLSize = 0;
u32 DOLOffset = 0; u32 DOLOffset = 0;
s32 ELFNumberOfSections = 0; s32 ELFNumberOfSections = 0;
u32 FSTMode = 0; u32 FSTMode = 0;
u32 DiscChangeIRQ = 0;
extern DML_CFG *DMLCfg; extern DML_CFG *DMLCfg;
@ -37,6 +38,7 @@ char *getfilenamebyoffset(u32 offset)
return (char*)NULL; return (char*)NULL;
} }
void DIInit( void ) void DIInit( void )
{ {
memset32( (void*)DI_BASE, 0xdeadbeef, 0x30 ); memset32( (void*)DI_BASE, 0xdeadbeef, 0x30 );
@ -105,6 +107,39 @@ u32 DIUpdateRegisters( void )
switch( read32(DI_SCMD_0) >> 24 ) 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 0xA7:
case 0xA9: case 0xA9:
//dbgprintf("DIP:Async!\n"); //dbgprintf("DIP:Async!\n");
@ -156,7 +191,8 @@ u32 DIUpdateRegisters( void )
switch( Offset ) switch( Offset )
{ {
case 0x56B8E7E0: // AppSwitcher [EUR] case 0x56B8E7E0: // AppSwitcher [EUR]
case 0x56C49600: // [USA] case 0x56C49600: // [USA] v1.1
case 0x56C4C980: // [USA] v1.0
{ {
DMLCfg->Config &= ~(DML_CFG_CHEATS|DML_CFG_PADHOOK|DML_CFG_DEBUGGER|DML_CFG_DEBUGWAIT); DMLCfg->Config &= ~(DML_CFG_CHEATS|DML_CFG_PADHOOK|DML_CFG_DEBUGGER|DML_CFG_DEBUGWAIT);
@ -164,7 +200,8 @@ u32 DIUpdateRegisters( void )
} break; } break;
case 0x5668FE20: // psov3.dol [EUR] case 0x5668FE20: // psov3.dol [EUR]
case 0x56750660: // [USA] case 0x56750660: // [USA] v1.1
case 0x56753EC0: // [USA] v1.0
{ {
PSOHack = 1; PSOHack = 1;
} break; } break;
@ -330,9 +367,9 @@ u32 DIUpdateRegisters( void )
} }
} }
if( (u64)read32(HW_TIMER) >= 2 * 60 * 243000000LL / 128 ) if( (u64)read32(HW_TIMER) >= 25 * 243000000LL / 128 )
{ {
USBStorage_Read_Sectors( 23, 1, (void*)0x1000 ); USBStorage_Read_Sectors( (read32(HW_TIMER) << 3) & 0x000FFFFF, 1, (void*)0x1000 );
write32( HW_TIMER, 0 ); write32( HW_TIMER, 0 );
} }

38
ehci.c
View File

@ -656,21 +656,20 @@ s32 ehci_bulk_message(struct ehci_device *dev,u8 bEndpoint,u16 wLength,void *rpD
return ret; return ret;
} }
int ehci_reset_port(int port) int ehci_reset_port(int port)
{ {
u32 __iomem *status_reg = &ehci->regs->port_status[port]; u32 __iomem *status_reg = &ehci->regs->port_status[port];
struct ehci_device *dev = &ehci->devices[port]; struct ehci_device *dev = &ehci->devices[port];
u32 status = ehci_readl(status_reg); u32 status = ehci_readl(status_reg);
int retval = 0; int retval = 0;
dev->id = 0; dev->id = 0;
if ((PORT_OWNER&status) || !(PORT_CONNECT&status)) if( (PORT_OWNER&status) || !(PORT_CONNECT&status) )
{ {
int retries = 10; int retries = 10;
while (!(PORT_CONNECT&status) && retries > 0) while( !(PORT_CONNECT&status) && retries > 0 )
{ {
msleep(1000); // sleep 1 second msleep(1000); // sleep 1 second
status = ehci_readl(status_reg); status = ehci_readl(status_reg);
@ -680,38 +679,41 @@ int ehci_reset_port(int port)
if( retries <= 0 ) if( retries <= 0 )
{ {
ehci_writel( PORT_OWNER, status_reg); ehci_writel( PORT_OWNER, status_reg );
ehci_dbg ( "EHCI:port %d had no usb2 device connected at startup %X \n", port,ehci_readl(status_reg) ); ehci_dbg ( "EHCI:port %d had no usb2 device connected at startup %X \n", port,ehci_readl(status_reg) );
return -ENODEV;// no USB2 device connected return -ENODEV;// no USB2 device connected
} }
} }
ehci_dbg ( "EHCI:port %d has usb2 device connected! reset it...\n", port); ehci_dbg ( "EHCI:port %d has usb2 device connected! reset it...\n", port);
ehci_writel( 0x1803,status_reg);
while ((ehci_readl(status_reg) & 0x1801) != 0x1801) if( PORT_USB11(ehci_readl(status_reg)) )
{ {
ehci_dbg ( "EHCI:Waiting for port %d to settle...(%04x)\n", port, ehci_readl(status_reg)); ehci_dbg("EHCI:Device is USB1.1\n");
ehci_writel( 0x1803,status_reg);
msleep(500);
} }
ehci_writel( 0x1903,status_reg); status = ehci_readl(status_reg);
//ehci_writel( PORT_OWNER|PORT_POWER|PORT_RESET,status_reg); status|= PORT_RESET;
msleep(50);// wait 50ms for the reset sequence ehci_writel( status, status_reg );
ehci_writel( 0x1001,status_reg);
retval = handshake( status_reg, PORT_RESET, 0, 2000);
if (retval != 0) msleep(50); // wait 50ms for the reset sequence
status = ehci_readl(status_reg);
status ^= PORT_RESET;
ehci_writel( status, status_reg );
retval = handshake( status_reg, PORT_RESET, 0, 2000 );
if(retval != 0)
{ {
ehci_dbg ( "EHCI:port %d reset error %d\n", port, retval); ehci_dbg ( "EHCI:port %d reset error %d\n", port, retval);
return retval; return retval;
} }
ehci_dbg ( "EHCI:port %d reseted status:%04x...\n", port,ehci_readl(status_reg)); ehci_dbg ( "EHCI:port %d reseted status:%04x...\n", port,ehci_readl(status_reg));
msleep(50); msleep(100);
// now the device has the default device id // now the device has the default device id
retval = ehci_control_message( dev, USB_CTRLTYPE_DIR_DEVICE2HOST, USB_REQ_GETDESCRIPTOR, USB_DT_DEVICE<<8, 0, sizeof(dev->desc), &dev->desc ); retval = ehci_control_message( dev, USB_CTRLTYPE_DIR_DEVICE2HOST, USB_REQ_GETDESCRIPTOR, USB_DT_DEVICE<<8, 0, sizeof(dev->desc), &dev->desc );
if (retval < 0) if (retval < 0)
{ {
ehci_dbg("EHCI:unable to get device desc...\n"); ehci_dbg("EHCI:unable to get device desc...\n");

View File

@ -15,7 +15,7 @@
#define PADHOOK 1 #define PADHOOK 1
#define CONFIG_VERSION 0x00000002 #define CONFIG_VERSION 0x00000002
#define DM_VERSION 0x00020002 #define DM_VERSION 0x0002000B
#define DI_SUCCESS 1 #define DI_SUCCESS 1
#define DI_ERROR 2 #define DI_ERROR 2

67
ipc.h
View File

@ -1,67 +0,0 @@
#ifndef __IPC_H__
#define __IPC_H__ 1
struct ioctl_vector {
void *data;
unsigned int len;
} __attribute__((packed));
struct ipcmessage
{
unsigned int command; // 0
unsigned int result; // 4
union
{
unsigned int fd; // 8
};
union
{
struct
{
char *device; // 12
unsigned int mode; // 16
unsigned int resultfd; // 20
} open;
struct
{
void *data;
unsigned int length;
} read, write;
struct
{
int offset;
int origin;
} seek;
struct
{
unsigned int command;
unsigned int *buffer_in;
unsigned int length_in;
unsigned int *buffer_io;
unsigned int length_io;
} ioctl;
struct
{
unsigned int command; // C
unsigned int argc_in; // 10
unsigned int argc_io; // 14
struct ioctl_vector *argv; // 18
} ioctlv;
};
} __attribute__((packed)) ipcmessage;
#define IOS_OPEN 0x01
#define IOS_CLOSE 0x02
#define IOS_READ 0x03
#define IOS_WRITE 0x04
#define IOS_SEEK 0x05
#define IOS_IOCTL 0x06
#define IOS_IOCTLV 0x07
#endif

71
main.c
View File

@ -7,7 +7,6 @@ Copyright (C) 2010-2012 crediar
*/ */
#include "string.h" #include "string.h"
#include "global.h" #include "global.h"
#include "ipc.h"
#include "alloc.h" #include "alloc.h"
#include "ff.h" #include "ff.h"
#include "diskio.h" #include "diskio.h"
@ -20,27 +19,26 @@ Copyright (C) 2010-2012 crediar
#include "DVD.h" #include "DVD.h"
#include "Drive.h" #include "Drive.h"
#include "dip.h" #include "dip.h"
#include "Patches.h"
extern u32 DiscChangeIRQ;
char __aeabi_unwind_cpp_pr0[0]; char __aeabi_unwind_cpp_pr0[0];
void Syscall( u32 a, u32 b, u32 c, u32 d ) 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; return;
} }
void SWI( u32 a, u32 b ) void SWI( u32 a, u32 b )
{ {
dbgprintf("SWI:%X,%X\n", a, b ); //dbgprintf("SWI:%X,%X\n", a, b );
return; return;
} }
void PrefetchAbort( void ) void PrefetchAbort( void )
{ {
u32 val; EXIControl(1);
__asm("mov %0,lr": "=r" (val) ); dbgprintf("PrefetchAbort\n");
*(vu32*)0xD800070 |= 1;
dbgprintf("PrefetchAbort LR:%08x\n", val-8 );
while(1); while(1);
return; return;
} }
@ -52,7 +50,7 @@ void DataAbort( u32 a, u32 b, u32 c, u32 d, u32 e, u32 f, u32 g, u32 h )
*(vu32*)0xD800070 |= 1; *(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(); Shutdown();
} }
void IRQHandler( void ) void IRQHandler( void )
@ -85,18 +83,12 @@ void IRQHandler( void )
while(1); 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; return;
} }
void FIQHandler( void ) void FIQHandler( void )
@ -169,8 +161,6 @@ int main( int argc, char *argv[] )
dbgprintf("Built: " __DATE__ " " __TIME__ "\n"); dbgprintf("Built: " __DATE__ " " __TIME__ "\n");
dbgprintf("This software is licensed under GPLv3, for more details visit:\nhttp://code.google.com/p/diosmios\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"); //dbgprintf("MEMInitLow()...\n");
MEMInitLow(); MEMInitLow();
@ -208,6 +198,8 @@ int main( int argc, char *argv[] )
ConfigInit( (DML_CFG*)0x01200000 ); ConfigInit( (DML_CFG*)0x01200000 );
ConfigSetConfig( DML_CFG_BOOT_DISC2 );
if( !ConfigGetConfig(DML_CFG_BOOT_DISC) ) if( !ConfigGetConfig(DML_CFG_BOOT_DISC) )
{ {
if( DVDSelectGame() == DI_SUCCESS ) if( DVDSelectGame() == DI_SUCCESS )
@ -250,10 +242,44 @@ int main( int argc, char *argv[] )
ahb_flush_to( AHB_PPC ); ahb_flush_to( AHB_PPC );
u32 PADLock = 0;
while (1) while (1)
{ {
ahb_flush_from( AHB_STARLET ); //flush to arm ahb_flush_from( AHB_STARLET ); //flush to arm
if( (((read32(0x12F8) >> 16) & 0x30) == 0x30 ) )
{
if( !PADLock )
{
ScreenShot();
PADLock = 1;
}
} else {
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 ) ) if( (((read32(0x12FC) >> 16) & 0x1030) == 0x1030 ) )
{ {
SysReset(); SysReset();
@ -287,6 +313,7 @@ int main( int argc, char *argv[] )
// write32(0x1860, 0xdeadbeef); // write32(0x1860, 0xdeadbeef);
//} //}
SMenuAddFramebuffer();
DIUpdateRegisters(); DIUpdateRegisters();

View File

@ -3,7 +3,6 @@
#include "string.h" #include "string.h"
#include "global.h" #include "global.h"
#include "ipc.h"
#include "utils.h" #include "utils.h"
#include "hollywood.h" #include "hollywood.h"
#include "vsprintf.h" #include "vsprintf.h"

View File

@ -34,7 +34,7 @@ void BUG(void)
void msleep(int msec) void msleep(int msec)
{ {
udelay(2048*msec); udelay(msec*1000);
} }
extern u32 __exe_start_virt__; extern u32 __exe_start_virt__;
extern u32 __ram_start_virt__; extern u32 __ram_start_virt__;