Compare commits
No commits in common. "wiki" and "master" have entirely different histories.
916
Card.c
Normal file
916
Card.c
Normal file
@ -0,0 +1,916 @@
|
||||
#include "Card.h"
|
||||
|
||||
FIL CardStat;
|
||||
extern u32 FSTMode;
|
||||
extern FIL GameFile;
|
||||
|
||||
void CardInit( void )
|
||||
{
|
||||
FILINFO f;
|
||||
u32 i,wrote;
|
||||
CARDStat CStat;
|
||||
char GameID[0x20];
|
||||
|
||||
|
||||
memset32( (void*)CARD_BASE, 0xdeadbeef, 0x20 );
|
||||
memset32( (void*)CARD_SHADOW, 0, 0x20 );
|
||||
|
||||
//Create savefile dirs for the current game
|
||||
if( f_chdir("/saves") != FR_OK )
|
||||
{
|
||||
f_mkdir("/saves");
|
||||
f_chdir("/saves");
|
||||
}
|
||||
|
||||
if( FSTMode )
|
||||
{
|
||||
FSTRead( (char*)GameID, 0x20, 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 ) )
|
||||
{
|
||||
case FR_NO_FILE:
|
||||
{
|
||||
if( f_open( &CardStat, "stats.bin", FA_CREATE_ALWAYS | FA_READ | FA_WRITE ) != FR_OK )
|
||||
{
|
||||
//dbgprintf("MC:Could not create stats file!\n");
|
||||
|
||||
} else {
|
||||
|
||||
memset32( &CStat, 0, sizeof( CARDStat ) );
|
||||
for( i=0; i < CARD_MAX_FILES; ++i )
|
||||
{
|
||||
f_write( &CardStat, &CStat, sizeof( CARDStat ), &wrote );
|
||||
}
|
||||
f_sync( &CardStat );
|
||||
}
|
||||
} break;
|
||||
case FR_OK:
|
||||
{
|
||||
if( f_open( &CardStat, "stats.bin", FA_OPEN_EXISTING | FA_READ | FA_WRITE ) != FR_OK )
|
||||
{
|
||||
;//dbgprintf("MC:Could not create stats file!\n");
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
;//dbgprintf("MC:CardInit fuck up\n");
|
||||
} break;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
CARDStat CStat;
|
||||
u32 i;
|
||||
u32 read;
|
||||
|
||||
for( i=0; i < CARD_MAX_FILES; ++i )
|
||||
{
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * i );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
if( CStat.length == 0 )
|
||||
{
|
||||
//dbgprintf("CardFindFreeEntry(%d)\n", i );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 CardFindEntryByName( char *Filename )
|
||||
{
|
||||
CARDStat CStat;
|
||||
u32 i;
|
||||
u32 read;
|
||||
|
||||
for( i=0; i < CARD_MAX_FILES; ++i )
|
||||
{
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * i );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
if( strcmp( Filename, CStat.fileName ) == 0 )
|
||||
{
|
||||
//dbgprintf("CardFindEntryByName(%d,%s,%s)\n", i, Filename, CStat.fileName );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
s32 CardOpenFile( char *Filename, CARDFileInfo *CFInfo )
|
||||
{
|
||||
FIL savefile;
|
||||
s32 Slot,fres;
|
||||
|
||||
Slot = CardFindEntryByName(Filename);
|
||||
if( Slot < 0 )
|
||||
{
|
||||
write32( CARD_SCMD_4, -1 );
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
return -4;
|
||||
}
|
||||
|
||||
LFNfy( Filename );
|
||||
fres = f_open( &savefile, Filename, FA_READ|FA_WRITE|FA_OPEN_EXISTING ) ;
|
||||
switch( fres )
|
||||
{
|
||||
case FR_NO_PATH:
|
||||
case FR_NO_FILE:
|
||||
{
|
||||
;//dbgprintf("MC:Failed to open:\"%s\":%d\n", Filename, fres );
|
||||
|
||||
write32( CARD_SCMD_4, -1 );
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
EXIControl(1);
|
||||
;//dbgprintf("MC:Failed to open:\"%s\":%d\n", Filename, fres );
|
||||
Shutdown();
|
||||
} break;
|
||||
case FR_OK:
|
||||
{
|
||||
f_close( &savefile );
|
||||
|
||||
write32( CARD_SCMD_4, Slot );
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
} break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
s32 CardFastOpenFile( u32 FileNo, CARDFileInfo *CFInfo )
|
||||
{
|
||||
CARDStat CStat;
|
||||
FIL savefile;
|
||||
s32 Slot,fres;
|
||||
u32 read;
|
||||
|
||||
if( FileNo >= CARD_MAX_FILES )
|
||||
{
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
return 0;
|
||||
}
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
if( CStat.length == 0 )
|
||||
{
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
return 0;
|
||||
}
|
||||
|
||||
LFNfy( CStat.fileName );
|
||||
fres = f_open( &savefile, CStat.fileName, FA_READ|FA_WRITE|FA_OPEN_EXISTING ) ;
|
||||
switch( fres )
|
||||
{
|
||||
case FR_NO_PATH:
|
||||
case FR_NO_FILE:
|
||||
{
|
||||
;//dbgprintf("MC:Failed to open:\"%s\":%d\n", CStat.fileName, fres );
|
||||
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
EXIControl(1);
|
||||
;//dbgprintf("MC:Failed to open:\"%s\":%d\n", CStat.fileName, fres );
|
||||
Shutdown();
|
||||
} break;
|
||||
case FR_OK:
|
||||
{
|
||||
write32( CARD_SCMD_4, savefile.fsize );
|
||||
|
||||
f_close( &savefile );
|
||||
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
} break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
void CardDeleteFile( char *Filename )
|
||||
{
|
||||
CARDStat CStat;
|
||||
u32 wrote;
|
||||
s32 Slot;
|
||||
|
||||
Slot = CardFindEntryByName( Filename );
|
||||
if( Slot < 0 )
|
||||
{
|
||||
dbgprintf("MC:\"%s\" doesn't exists\n", Filename );
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
memset32( &CStat, 0, sizeof(CARDStat) );
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_write( &CardStat, &CStat, sizeof(CARDStat), &wrote );
|
||||
f_sync( &CardStat );
|
||||
|
||||
f_unlink( Filename );
|
||||
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
}
|
||||
void CardFastDelete( u32 FileNo )
|
||||
{
|
||||
CARDStat CStat;
|
||||
u32 read;
|
||||
|
||||
if( FileNo >= CARD_MAX_FILES )
|
||||
{
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
if( f_unlink( CStat.fileName ) == FR_OK )
|
||||
{
|
||||
memset32( &CStat, 0, sizeof(CARDStat) );
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
|
||||
f_write( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
f_sync( &CardStat );
|
||||
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
|
||||
} else {
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
void CardRename( char *NameSrc, char *NameDst )
|
||||
{
|
||||
CARDStat CStat;
|
||||
u32 wrote;
|
||||
s32 Slot;
|
||||
|
||||
Slot = CardFindEntryByName( NameDst );
|
||||
if( Slot != -1 )
|
||||
{
|
||||
f_unlink( NameDst );
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &wrote );
|
||||
|
||||
memset32( &CStat, 0, sizeof(CARDStat) );
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_write( &CardStat, &CStat, sizeof(CARDStat), &wrote );
|
||||
f_sync( &CardStat );
|
||||
}
|
||||
|
||||
Slot = CardFindEntryByName( NameSrc );
|
||||
if( Slot == -1 )
|
||||
{
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
switch( f_rename( NameSrc, NameDst ) )
|
||||
{
|
||||
case FR_OK:
|
||||
{
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &wrote );
|
||||
|
||||
memcpy( CStat.fileName, NameDst, 32 );
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_write( &CardStat, &CStat, sizeof(CARDStat), &wrote );
|
||||
f_sync( &CardStat );
|
||||
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
|
||||
} break;
|
||||
//case FR_EXIST:
|
||||
//{
|
||||
// write32( CARD_SRETURN, CARD_FILE_EXISTS );
|
||||
//} break;
|
||||
default:
|
||||
{
|
||||
write32( CARD_SRETURN, CARD_FATAL_ERROR );
|
||||
} break;
|
||||
}
|
||||
}
|
||||
void CardCreateFile( char *Filename, u32 Size, CARDFileInfo *CFInfo )
|
||||
{
|
||||
CARDStat CStat;
|
||||
u32 i,fres,read;
|
||||
s32 Slot;
|
||||
FIL savefile;
|
||||
|
||||
Slot = CardFindEntryByName( Filename );
|
||||
if( Slot >= 0 )
|
||||
{
|
||||
;//dbgprintf("MC:\"%s\" already exists\n", Filename );
|
||||
write32( CARD_SRETURN, CARD_FILE_EXISTS );
|
||||
return;
|
||||
}
|
||||
|
||||
Slot = CardFindFreeEntry();
|
||||
if( Slot < 0 )
|
||||
return;
|
||||
|
||||
char FName[32];
|
||||
memcpy( FName, Filename, 32 );
|
||||
|
||||
LFNfy( FName );
|
||||
fres = f_open( &savefile, FName, FA_READ|FA_WRITE|FA_CREATE_NEW );
|
||||
switch( fres )
|
||||
{
|
||||
case FR_EXIST:
|
||||
{
|
||||
write32( CARD_SCMD_4, 0 );
|
||||
write32( CARD_SRETURN, CARD_FILE_EXISTS );
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
EXIControl(1);
|
||||
;//dbgprintf("MC:Failed to create:\"%s\":%d\n", Filename, fres );
|
||||
Shutdown();
|
||||
} break;
|
||||
case FR_OK:
|
||||
{
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
memcpy( CStat.fileName, Filename, strlen(Filename) );
|
||||
|
||||
CStat.length = Size;
|
||||
CStat.time = 0x15745a1a;
|
||||
memcpy( CStat.gameName, (void*)0, 4 );
|
||||
memcpy( CStat.company, (void*)4, 2 );
|
||||
|
||||
CStat.bannerFormat = 0;
|
||||
CStat.iconAddr = -1;
|
||||
CStat.iconFormat = 0;
|
||||
CStat.iconSpeed = 0;
|
||||
CStat.commentAddr = -1;
|
||||
|
||||
CStat.offsetBanner = -1;
|
||||
CStat.offsetBannerTlut = -1;
|
||||
for( i=0; i < 8; ++i )
|
||||
CStat.offsetIcon[i] = -1;
|
||||
CStat.offsetIconTlut = -1;
|
||||
CStat.offsetData = 0;
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * Slot );
|
||||
f_write( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
f_sync( &CardStat );
|
||||
|
||||
CFInfo->chan = 0;
|
||||
CFInfo->fileNo = Slot;
|
||||
CFInfo->iBlock = 0;
|
||||
CFInfo->length = Size;
|
||||
CFInfo->offset = 0;
|
||||
|
||||
char *buf = (char*)malloc(512);
|
||||
memset32( buf, 0, 512 );
|
||||
|
||||
//Create full file
|
||||
for( i=0; i < Size; i+=512 )
|
||||
{
|
||||
f_write( &savefile, buf, 512, &read);
|
||||
}
|
||||
|
||||
f_close( &savefile );
|
||||
|
||||
write32( CARD_SCMD_4, Slot );
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
} break;
|
||||
}
|
||||
}
|
||||
void CardReadFile( u32 FileNo, u8 *Buffer, u32 Length, u32 Offset )
|
||||
{
|
||||
u32 read;
|
||||
CARDStat CStat;
|
||||
|
||||
FIL savefile;
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
LFNfy( CStat.fileName );
|
||||
if( f_open( &savefile, CStat.fileName, FA_OPEN_EXISTING | FA_READ ) == FR_OK )
|
||||
{
|
||||
f_lseek( &savefile, Offset );
|
||||
f_read( &savefile, (void*)Buffer, Length, &read );
|
||||
f_close( &savefile );
|
||||
}
|
||||
}
|
||||
void CardWriteFile( u32 FileNo, u8 *Buffer, u32 Length, u32 Offset )
|
||||
{
|
||||
u32 read;
|
||||
CARDStat CStat;
|
||||
|
||||
FIL savefile;
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * FileNo );
|
||||
f_read( &CardStat, &CStat, sizeof(CARDStat), &read );
|
||||
|
||||
LFNfy( CStat.fileName );
|
||||
switch( f_open( &savefile, CStat.fileName, FA_OPEN_EXISTING | FA_WRITE ) )
|
||||
{
|
||||
case FR_OK:
|
||||
{
|
||||
#ifdef CARD_DEBUG
|
||||
if( f_lseek( &savefile, Offset ) != FR_OK )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("Failed to seek to %08x\n", Offset );
|
||||
Shutdown();
|
||||
} else {
|
||||
if( f_write( &savefile, (void*)Buffer, Length, &read ) != FR_OK )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("Failed to write %d bytes to %p\n", Length, Buffer );
|
||||
Shutdown();
|
||||
}
|
||||
if( read != Length )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("Short write; %d of %d bytes written!\n", read, Length );
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
#else
|
||||
f_lseek( &savefile, Offset );
|
||||
f_write( &savefile, (void*)Buffer, Length, &read );
|
||||
#endif
|
||||
f_close( &savefile );
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("Failed to open:\"%s\"\n", CStat.fileName );
|
||||
Shutdown();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
void CardUpdateStats( CARDStat *CStat )
|
||||
{
|
||||
u32 IconSize,BannerSize,Format,Offset,i,TLut=0;
|
||||
|
||||
BannerSize = CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT;
|
||||
IconSize = CARD_ICON_WIDTH * CARD_ICON_HEIGHT;
|
||||
Offset = CStat->iconAddr;
|
||||
|
||||
if( CStat->bannerFormat & CARD_STAT_BANNER_C8 )
|
||||
{
|
||||
CStat->offsetBanner = Offset;
|
||||
CStat->offsetBannerTlut = Offset + BannerSize;
|
||||
|
||||
Offset += BannerSize + 512;
|
||||
|
||||
} else if( CStat->bannerFormat & CARD_STAT_BANNER_RGB5A3 ) {
|
||||
|
||||
CStat->offsetBanner = Offset;
|
||||
CStat->offsetBannerTlut = -1;
|
||||
|
||||
Offset += BannerSize * 2;
|
||||
|
||||
} else {
|
||||
|
||||
CStat->offsetBanner = -1;
|
||||
CStat->offsetBannerTlut = -1;
|
||||
}
|
||||
|
||||
for( i=0; i < CARD_ICON_MAX; ++i )
|
||||
{
|
||||
Format = CStat->iconFormat >> ( i * 2 );
|
||||
|
||||
if( Format & CARD_STAT_ICON_C8 )
|
||||
{
|
||||
CStat->offsetIcon[i] = Offset;
|
||||
Offset += IconSize;
|
||||
TLut = 1;
|
||||
|
||||
} else if ( Format & CARD_STAT_ICON_RGB5A3 ) {
|
||||
|
||||
CStat->offsetIcon[i] = Offset;
|
||||
Offset += IconSize * 2;
|
||||
|
||||
} else {
|
||||
CStat->offsetIcon[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( TLut )
|
||||
{
|
||||
CStat->offsetIconTlut = Offset;
|
||||
Offset += 512;
|
||||
} else {
|
||||
CStat->offsetIconTlut = -1;
|
||||
}
|
||||
|
||||
CStat->offsetData = Offset;
|
||||
}
|
||||
void CARDUpdateRegisters( void )
|
||||
{
|
||||
u32 read,i;
|
||||
u32 CARDOK=0;
|
||||
|
||||
if( read32(CARD_CONTROL) != 0xdeadbeef )
|
||||
{
|
||||
if( read32( CARD_CONTROL ) & (~3) )
|
||||
{
|
||||
write32( CARD_CONTROL, 0xdeadbeef );
|
||||
return;
|
||||
}
|
||||
|
||||
write32( CARD_SCONTROL, read32(CARD_CONTROL) & 3 );
|
||||
|
||||
clear32( CARD_SSTATUS, 0x14 );
|
||||
|
||||
write32( CARD_CONTROL, 0xdeadbeef );
|
||||
|
||||
if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) )
|
||||
set32( HW_GPIO_OUT, 1<<5 );
|
||||
|
||||
while( read32(CARD_CMD) == 0xdeadbeef );
|
||||
write32( CARD_SCMD, read32(CARD_CMD) );
|
||||
write32( CARD_CMD, 0xdeadbeef );
|
||||
|
||||
while( read32(CARD_CMD_1) == 0xdeadbeef );
|
||||
write32( CARD_SCMD_1, read32(CARD_CMD_1) );
|
||||
write32( CARD_CMD_1, 0xdeadbeef );
|
||||
|
||||
if( read32(CARD_CMD_2) != 0xdeadbeef )
|
||||
{
|
||||
write32( CARD_SCMD_2, read32(CARD_CMD_2) );
|
||||
write32( CARD_CMD_2, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(CARD_CMD_3) != 0xdeadbeef )
|
||||
{
|
||||
write32( CARD_SCMD_3, read32(CARD_CMD_3) );
|
||||
write32( CARD_CMD_3, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(CARD_CMD_4) != 0xdeadbeef )
|
||||
{
|
||||
write32( CARD_SCMD_4, read32(CARD_CMD_4) );
|
||||
write32( CARD_CMD_4, 0xdeadbeef );
|
||||
}
|
||||
|
||||
switch( read32(CARD_SCMD) >> 24 )
|
||||
{
|
||||
case 0x00:
|
||||
{
|
||||
;//dbgprintf("CARD:Warning unknown command!\n");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
//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) );
|
||||
Shutdown();
|
||||
} break;
|
||||
/* CARDOpen( char *FileName ) */
|
||||
case 0xC0:
|
||||
{
|
||||
char FileName[32];
|
||||
|
||||
u32 FInfo = P2C(read32(CARD_SCMD_2));
|
||||
|
||||
memcpy( FileName, (void*)0x17E0, 32 );
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDOpen( \"%s\", 0x%08x )", FileName, FInfo );
|
||||
#endif
|
||||
CardOpenFile( (char*)FileName, (CARDFileInfo*)FInfo );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC1:
|
||||
{
|
||||
u32 FileNo = read32(CARD_SCMD_1);
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDClose( %d )", FileNo );
|
||||
#endif
|
||||
if( FileNo < 0 )
|
||||
write32( CARD_SRETURN, -128 );
|
||||
else
|
||||
write32( CARD_SRETURN, 0 );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC2:
|
||||
{
|
||||
char FileName[32];
|
||||
u32 Size = read32(CARD_SCMD_2);
|
||||
u32 FInfo = P2C(read32(CARD_SCMD_3));
|
||||
|
||||
memcpy( FileName, (void*)0x17E0, 32 );
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDCreate( \"%s\", 0x%04x, 0x%08x )", FileName, Size, FInfo );
|
||||
#endif
|
||||
CardCreateFile( (char*)FileName, Size, (CARDFileInfo*)FInfo );
|
||||
|
||||
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_CREATE );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC3:
|
||||
{
|
||||
CARDStat CS;
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDGetState( %d, 0x%08x, ", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)) );
|
||||
#endif
|
||||
|
||||
if( read32(CARD_SCMD_1) >= CARD_MAX_FILES )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("MC: Invalid file slot!:%d\n", read32(CARD_SCMD_1) );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * read32(CARD_SCMD_1) );
|
||||
f_read( &CardStat, &CS, sizeof(CARDStat), &read );
|
||||
|
||||
if( CS.length == 0 )
|
||||
{
|
||||
#ifdef CARDDEBUG
|
||||
// dbgprintf(")");
|
||||
#endif
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
} else {
|
||||
|
||||
CardUpdateStats( &CS );
|
||||
|
||||
memcpy( (void*)0x1780, &CS, sizeof(CARDStat) );
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
CARDStat *CSTAT = (CARDStat*)0x1780;
|
||||
|
||||
dbgprintf("\nMC:Card Status:\n");
|
||||
dbgprintf("\tFilename:%.32s\n", CSTAT->fileName );
|
||||
dbgprintf("\tGameName:%.4s\n", CSTAT->gameName );
|
||||
dbgprintf("\tCompany :%.2s\n", CSTAT->company );
|
||||
dbgprintf("\tLength :%d\n", CSTAT->length );
|
||||
dbgprintf("\tTime :%d\n\n", CSTAT->time );
|
||||
|
||||
dbgprintf("\tBannerFormat:%d\n", CSTAT->bannerFormat );
|
||||
dbgprintf("\tIconAddress :0x%04X\n", CSTAT->iconAddr );
|
||||
dbgprintf("\tIconFormat :0x%02X\n", CSTAT->iconFormat );
|
||||
dbgprintf("\tIconSpeed :0x%02X\n", CSTAT->iconSpeed );
|
||||
dbgprintf("\tComntAddress:0x%04X\n\n", CSTAT->commentAddr );
|
||||
|
||||
dbgprintf("\tOffsetBanner :0x%04X\n", CSTAT->offsetBanner );
|
||||
dbgprintf("\tOffsetBnrTlt :0x%04X\n", CSTAT->offsetBannerTlut );
|
||||
|
||||
for( i=0; i < CARD_ICON_MAX; ++i)
|
||||
dbgprintf("\tOffsetIcon[%d]:0x%04X\n", i, CSTAT->offsetIcon[i] );
|
||||
|
||||
dbgprintf("\tOffsetIconTlt:0x%04X\n", CSTAT->offsetIconTlut );
|
||||
dbgprintf("\tOffsetData :0x%04X\n", CSTAT->offsetData );
|
||||
#endif
|
||||
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
}
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC4:
|
||||
{
|
||||
CARDStat CS;
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDSetState( %d, 0x%08x )", read32(CARD_SCMD_1), P2C(read32(CARD_SCMD_2)) );
|
||||
#endif
|
||||
if( read32(CARD_SCMD_1) >= CARD_MAX_FILES )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("\nMC: Invalid file slot!\n");
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
CARDStat *CStat = (CARDStat *) P2C(read32(CARD_SCMD_2));
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * read32(CARD_SCMD_1) );
|
||||
f_read( &CardStat, &CS, sizeof(CARDStat), &read );
|
||||
|
||||
if( CS.length == 0 )
|
||||
{
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf(")");
|
||||
#endif
|
||||
write32( CARD_SRETURN, CARD_NO_FILE );
|
||||
|
||||
} else {
|
||||
|
||||
CS.bannerFormat = CStat->bannerFormat;
|
||||
CS.iconAddr = CStat->iconAddr;
|
||||
CS.iconFormat = CStat->iconFormat;
|
||||
CS.iconSpeed = CStat->iconSpeed;
|
||||
CS.commentAddr = CStat->commentAddr;
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("\nMC:Card Status:\n");
|
||||
dbgprintf("\tFilename:%.32s\n", CS.fileName );
|
||||
dbgprintf("\tGameName:%.4s\n", CS.gameName );
|
||||
dbgprintf("\tCompany :%.2s\n", CS.company );
|
||||
dbgprintf("\tLength :%d\n", CS.length );
|
||||
dbgprintf("\tTime :%d\n\n", CS.time );
|
||||
|
||||
dbgprintf("\tBannerFormat:%d\n", CS.bannerFormat );
|
||||
dbgprintf("\tIconAddress :0x%04X\n", CS.iconAddr );
|
||||
dbgprintf("\tIconFormat :0x%02X\n", CS.iconFormat );
|
||||
dbgprintf("\tIconSpeed :0x%02X\n", CS.iconSpeed );
|
||||
dbgprintf("\tComntAddress:0x%04X\n\n", CS.commentAddr );
|
||||
#endif
|
||||
|
||||
CardUpdateStats( &CS );
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("\tOffsetBanner :0x%04X\n", CS.offsetBanner );
|
||||
dbgprintf("\tOffsetBnrTlt :0x%04X\n", CS.offsetBannerTlut );
|
||||
|
||||
for( i=0; i < CARD_ICON_MAX; ++i)
|
||||
dbgprintf("\tOffsetIcon[%d]:0x%04X\n", i, CS.offsetIcon[i] );
|
||||
|
||||
dbgprintf("\tOffsetIconTlt:0x%04X\n", CS.offsetIconTlut );
|
||||
dbgprintf("\tOffsetData :0x%04X\n", CS.offsetData );
|
||||
#endif
|
||||
|
||||
f_lseek( &CardStat, sizeof(CARDStat) * read32(CARD_SCMD_1) );
|
||||
f_write( &CardStat, &CS, sizeof(CARDStat), &read );
|
||||
f_sync( &CardStat );
|
||||
|
||||
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_SETSTATUS );
|
||||
|
||||
write32( CARD_SRETURN, CARD_SUCCESS );
|
||||
}
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
/* CARDFastOpen( u32 FileNO, CARDFileInfo *CFInfo ) */
|
||||
case 0xC5:
|
||||
{
|
||||
u32 FileNo = read32(CARD_SCMD_1);
|
||||
u32 FInfo = P2C(read32(CARD_SCMD_2));
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDFastOpen( %d, 0x%08X )", FileNo, FInfo );
|
||||
#endif
|
||||
CardFastOpenFile( FileNo, (CARDFileInfo*)FInfo );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC6:
|
||||
{
|
||||
char FileName[32];
|
||||
|
||||
memcpy( FileName, (void*)0x17E0, 32 );
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDDelete( \"%s\" )", FileName );
|
||||
#endif
|
||||
|
||||
CardDeleteFile( (char*)FileName );
|
||||
|
||||
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_DELETE );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC8:
|
||||
{
|
||||
u32 Buffer = P2C(read32(CARD_SCMD_1));
|
||||
u32 Length = read32(CARD_SCMD_2);
|
||||
u32 Offset = read32(CARD_SCMD_3);
|
||||
u32 FileNo = read32(CARD_SCMD_4);
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDWrite( %d, 0x%08x, 0x%04x, 0x%04x )", FileNo, Buffer, Offset, Length );
|
||||
#endif
|
||||
if( FileNo >= CARD_MAX_FILES )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("\nMC: Invalid file slot!:%d\n", FileNo );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
CardWriteFile( FileNo, (u8*)Buffer, Length, Offset );
|
||||
|
||||
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_WRITE + Length );
|
||||
|
||||
write32( CARD_SRETURN, 0 );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xC9:
|
||||
{
|
||||
u32 Buffer = P2C(read32(CARD_SCMD_1));
|
||||
u32 Length = read32(CARD_SCMD_2);
|
||||
u32 Offset = read32(CARD_SCMD_3);
|
||||
u32 FileNo = read32(CARD_SCMD_4);
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDRead( %d, 0x%08x, 0x%04x, 0x%04x )", FileNo, Buffer, Offset, Length );
|
||||
#endif
|
||||
if( FileNo >= CARD_MAX_FILES )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("\nMC: Invalid file slot!:%d\n", FileNo );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
CardReadFile( FileNo, (u8*)Buffer, Length, Offset );
|
||||
|
||||
write32( 0x2FA0, read32(0x2FA0) + Length );
|
||||
|
||||
write32( CARD_SRETURN, 0 );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xCA:
|
||||
{
|
||||
u32 FileNo = read32( CARD_SCMD_1 );
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDFastDelete( %u )", FileNo );
|
||||
#endif
|
||||
CardFastDelete( FileNo );
|
||||
|
||||
write32( 0x2FA0, read32(0x2FA0) + CARD_XFER_DELETE );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
case 0xCB:
|
||||
{
|
||||
char NameSrc[32];
|
||||
char NameDst[32];
|
||||
|
||||
memcpy( NameSrc, (void*)0x17C0, 32 );
|
||||
memcpy( NameDst, (void*)0x17E0, 32 );
|
||||
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf("MC:CARDRename( \"%s\", \"%s\" )", NameSrc, NameDst );
|
||||
#endif
|
||||
CardRename( NameSrc, NameDst );
|
||||
|
||||
CARDOK = 1;
|
||||
} break;
|
||||
}
|
||||
|
||||
if(CARDOK)
|
||||
{
|
||||
#ifdef CARDDEBUG
|
||||
dbgprintf(":%d\n", read32( CARD_SRETURN ) );
|
||||
#endif
|
||||
while( read32(CARD_SCONTROL) & 1 )
|
||||
clear32( CARD_SCONTROL, 1 );
|
||||
|
||||
set32( CARD_SSTATUS, 0x10 );
|
||||
}
|
||||
|
||||
if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) )
|
||||
clear32( HW_GPIO_OUT, 1<<5 );
|
||||
}
|
||||
}
|
111
Card.h
Normal file
111
Card.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef _CARD_
|
||||
#define _CARD_
|
||||
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
#include "alloc.h"
|
||||
#include "ff.h"
|
||||
#include "vsprintf.h"
|
||||
#include "HW.h"
|
||||
#include "vsprintf.h"
|
||||
|
||||
#define CARD_MAX_FILES 128
|
||||
|
||||
#define CARD_BASE 0x00002F60
|
||||
|
||||
#define CARD_CMD (CARD_BASE+0x00)
|
||||
#define CARD_CMD_1 (CARD_BASE+0x04)
|
||||
#define CARD_CMD_2 (CARD_BASE+0x08)
|
||||
#define CARD_CMD_3 (CARD_BASE+0x0C)
|
||||
#define CARD_CMD_4 (CARD_BASE+0x10)
|
||||
#define CARD_RETURN (CARD_BASE+0x14)
|
||||
#define CARD_CONTROL (CARD_BASE+0x18)
|
||||
#define CARD_STATUS (CARD_BASE+0x1C)
|
||||
|
||||
#define CARD_SHADOW (CARD_BASE + 0x20)
|
||||
|
||||
#define CARD_SCMD (CARD_SHADOW+0x00)
|
||||
#define CARD_SCMD_1 (CARD_SHADOW+0x04)
|
||||
#define CARD_SCMD_2 (CARD_SHADOW+0x08)
|
||||
#define CARD_SCMD_3 (CARD_SHADOW+0x0C)
|
||||
#define CARD_SCMD_4 (CARD_SHADOW+0x10)
|
||||
#define CARD_SRETURN (CARD_SHADOW+0x14)
|
||||
#define CARD_SCONTROL (CARD_SHADOW+0x18)
|
||||
#define CARD_SSTATUS (CARD_SHADOW+0x1C)
|
||||
|
||||
// internal API command xfer bytes
|
||||
#define CARD_XFER_CREATE (2 * 8 * 1024) // CARDCreate[Async]
|
||||
#define CARD_XFER_DELETE (2 * 8 * 1024) // CARD[Fast]Delete[Async]
|
||||
#define CARD_XFER_MOUNT (5 * 8 * 1024) // CARDMount[Async]
|
||||
#define CARD_XFER_FORMAT (5 * 8 * 1024) // CARDFormat[Async]
|
||||
#define CARD_XFER_RENAME (1 * 8 * 1024) // CARDRename[Async]
|
||||
#define CARD_XFER_SETSTATUS (1 * 8 * 1024) // CARDSetStatus[Async]
|
||||
#define CARD_XFER_SETATTRIBUTES (1 * 8 * 1024) // CARDSetAttributes[Async]
|
||||
#define CARD_XFER_WRITE (1 * 8 * 1024) // CARDWrite[Async]
|
||||
|
||||
#define CARD_FILENAME_MAX 32
|
||||
|
||||
#define CARD_ICON_MAX 8
|
||||
#define CARD_ICON_WIDTH 32
|
||||
#define CARD_ICON_HEIGHT 32
|
||||
#define CARD_BANNER_WIDTH 96
|
||||
#define CARD_BANNER_HEIGHT 32
|
||||
|
||||
#define CARD_STAT_ICON_NONE 0
|
||||
#define CARD_STAT_ICON_C8 1
|
||||
#define CARD_STAT_ICON_RGB5A3 2
|
||||
|
||||
#define CARD_STAT_BANNER_NONE 0
|
||||
#define CARD_STAT_BANNER_C8 1
|
||||
#define CARD_STAT_BANNER_RGB5A3 2
|
||||
|
||||
enum CardStatus
|
||||
{
|
||||
CARD_SUCCESS = 0,
|
||||
CARD_NO_FILE = -4,
|
||||
CARD_FILE_EXISTS = -7,
|
||||
CARD_FATAL_ERROR =-128,
|
||||
};
|
||||
|
||||
typedef struct CARDFileInfo
|
||||
{
|
||||
/* 0x00 */ s32 chan;
|
||||
/* 0x04 */ s32 fileNo;
|
||||
|
||||
/* 0x08 */ s32 offset;
|
||||
/* 0x0C */ s32 length;
|
||||
/* 0x10 */ u16 iBlock;
|
||||
} CARDFileInfo;
|
||||
|
||||
typedef struct CARDStat
|
||||
{
|
||||
// read-only (Set by CARDGetStatus)
|
||||
/* 0x00 */ char fileName[32];
|
||||
/* 0x20 */ u32 length;
|
||||
/* 0x24 */ u32 time; // seconds since 01/01/2000 midnight
|
||||
/* 0x28 */ u8 gameName[4];
|
||||
/* 0x2C */ u8 company[2];
|
||||
|
||||
// read/write (Set by CARDGetStatus/CARDSetStatus)
|
||||
/* 0x2E */ u8 bannerFormat;
|
||||
/* 0x30 */ u32 iconAddr; // offset to the banner, bannerTlut, icon, iconTlut data set.
|
||||
/* 0x34 */ u16 iconFormat;
|
||||
/* 0x36 */ u16 iconSpeed;
|
||||
/* 0x38 */ u32 commentAddr; // offset to the pair of 32 byte character strings.
|
||||
|
||||
// read-only (Set by CARDGetStatus)
|
||||
/* 0x3C */ u32 offsetBanner;
|
||||
/* 0x40 */ u32 offsetBannerTlut;
|
||||
/* 0x44 */ u32 offsetIcon[8];
|
||||
/* 0x64 */ u32 offsetIconTlut;
|
||||
/* 0x68 */ u32 offsetData;
|
||||
} CARDStat;
|
||||
|
||||
|
||||
void CardInit( void );
|
||||
void CARDUpdateRegisters( void );
|
||||
s32 CardFindFreeEntry( void );
|
||||
s32 CardOpenFile( char *Filename, CARDFileInfo *CFInfo );
|
||||
void CardCreateFile( char *Filename, u32 Size, CARDFileInfo *CFInfo );
|
||||
|
||||
#endif
|
30
CardPatches.c
Normal file
30
CardPatches.c
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef __CARDPATCHES__
|
||||
#define __CARDPATCHES__
|
||||
|
||||
#include "asm\__CARDSync.h"
|
||||
#include "asm\CARDCheck.h"
|
||||
#include "asm\CARDCheckAsync.h"
|
||||
#include "asm\CARDCheckEX.h"
|
||||
#include "asm\CARDClose.h"
|
||||
#include "asm\CARDCreate.h"
|
||||
#include "asm\CARDDelete.h"
|
||||
#include "asm\CARDFastOpen.h"
|
||||
#include "asm\CARDFreeBlocks.h"
|
||||
#include "asm\CARDGetEncoding.h"
|
||||
#include "asm\CARDGetMemSize.h"
|
||||
#include "asm\CARDGetSerialNo.h"
|
||||
#include "asm\CARDGetStats.h"
|
||||
#include "asm\CARDMount.h"
|
||||
#include "asm\CARDMountAsync.h"
|
||||
#include "asm\CARDOpen.h"
|
||||
#include "asm\CARDProbe.h"
|
||||
#include "asm\CARDProbeEX.h"
|
||||
#include "asm\CARDRead.h"
|
||||
#include "asm\CARDSetStats.h"
|
||||
#include "asm\CARDWrite.h"
|
||||
#include "asm\CARDGetResultCode.h"
|
||||
#include "asm\CARDGetXferredBytes.h"
|
||||
#include "asm\CARDFastDelete.h"
|
||||
#include "asm\CARDRename.h"
|
||||
|
||||
#endif
|
448
CheatCode.c
Normal file
448
CheatCode.c
Normal file
@ -0,0 +1,448 @@
|
||||
#include "global.h"
|
||||
|
||||
unsigned char kenobigcDBG[4288] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x27, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x21, 0xff, 0x58, 0x90, 0x01, 0x00, 0x08,
|
||||
0x7c, 0x08, 0x02, 0xa6, 0x90, 0x01, 0x00, 0xac, 0x7c, 0x00, 0x00, 0x26, 0x90, 0x01, 0x00, 0x0c,
|
||||
0x7c, 0x09, 0x02, 0xa6, 0x90, 0x01, 0x00, 0x10, 0x7c, 0x01, 0x02, 0xa6, 0x90, 0x01, 0x00, 0x14,
|
||||
0xbc, 0x61, 0x00, 0x18, 0x7f, 0x20, 0x00, 0xa6, 0x63, 0x3a, 0x20, 0x00, 0x73, 0x5a, 0xf9, 0xff,
|
||||
0x7f, 0x40, 0x01, 0x24, 0xd8, 0x41, 0x00, 0x98, 0xd8, 0x61, 0x00, 0xa0, 0x3f, 0xe0, 0x80, 0x00,
|
||||
0x3e, 0x80, 0xcc, 0x00, 0xa3, 0x94, 0x40, 0x10, 0x63, 0x95, 0x00, 0xff, 0xb2, 0xb4, 0x40, 0x10,
|
||||
0x48, 0x00, 0x06, 0x55, 0x3a, 0xa0, 0x00, 0x00, 0x3a, 0xc0, 0x00, 0x19, 0x3a, 0xe0, 0x00, 0xd0,
|
||||
0x3f, 0x00, 0xcc, 0x00, 0x63, 0xf2, 0x27, 0x74, 0x80, 0x01, 0x00, 0xac, 0x90, 0x12, 0x00, 0x04,
|
||||
0x92, 0xb8, 0x64, 0x3c, 0x48, 0x00, 0x04, 0x2d, 0x41, 0x82, 0x05, 0xa4, 0x2c, 0x1d, 0x00, 0x04,
|
||||
0x40, 0x80, 0x00, 0x10, 0x2c, 0x1d, 0x00, 0x01, 0x41, 0x80, 0x05, 0x94, 0x48, 0x00, 0x03, 0x4c,
|
||||
0x41, 0x82, 0x04, 0xf0, 0x2c, 0x1d, 0x00, 0x06, 0x41, 0x82, 0x00, 0x8c, 0x2c, 0x1d, 0x00, 0x07,
|
||||
0x41, 0x82, 0x03, 0x30, 0x2c, 0x1d, 0x00, 0x08, 0x41, 0x82, 0x05, 0x80, 0x2c, 0x1d, 0x00, 0x09,
|
||||
0x41, 0x82, 0x00, 0xa0, 0x2c, 0x1d, 0x00, 0x10, 0x41, 0x82, 0x00, 0x98, 0x2c, 0x1d, 0x00, 0x2f,
|
||||
0x41, 0x82, 0x00, 0x70, 0x2c, 0x1d, 0x00, 0x30, 0x41, 0x82, 0x00, 0x78, 0x2c, 0x1d, 0x00, 0x38,
|
||||
0x41, 0x82, 0x05, 0x28, 0x2c, 0x1d, 0x00, 0x40, 0x41, 0x82, 0x03, 0x40, 0x2c, 0x1d, 0x00, 0x41,
|
||||
0x41, 0x82, 0x03, 0x58, 0x2c, 0x1d, 0x00, 0x44, 0x41, 0x82, 0x00, 0x68, 0x2c, 0x1d, 0x00, 0x50,
|
||||
0x41, 0x82, 0x00, 0x20, 0x2c, 0x1d, 0x00, 0x60, 0x41, 0x82, 0x00, 0x24, 0x2c, 0x1d, 0x00, 0x89,
|
||||
0x41, 0x82, 0x00, 0x50, 0x2c, 0x1d, 0x00, 0x99, 0x41, 0x82, 0x05, 0x0c, 0x48, 0x00, 0x05, 0x10,
|
||||
0x80, 0x72, 0x00, 0x00, 0x48, 0x00, 0x04, 0x29, 0x48, 0x00, 0x05, 0x04, 0x48, 0x00, 0x05, 0x89,
|
||||
0x48, 0x00, 0x04, 0xfc, 0x38, 0x80, 0x00, 0x01, 0x90, 0x92, 0x00, 0x00, 0x48, 0x00, 0x04, 0xf0,
|
||||
0x48, 0x00, 0x04, 0x09, 0x3a, 0x00, 0x00, 0xa0, 0x63, 0xec, 0x27, 0x98, 0x48, 0x00, 0x03, 0x14,
|
||||
0x38, 0x60, 0x01, 0x20, 0x63, 0xec, 0x27, 0x98, 0x48, 0x00, 0x03, 0xc9, 0x48, 0x00, 0x04, 0xd0,
|
||||
0x2f, 0x1d, 0x00, 0x10, 0x2e, 0x9d, 0x00, 0x44, 0x63, 0xe4, 0x1a, 0xb4, 0x3c, 0x60, 0x80, 0x00,
|
||||
0x60, 0x63, 0x03, 0x00, 0x48, 0x00, 0x05, 0x09, 0x38, 0x63, 0x0a, 0x00, 0x48, 0x00, 0x05, 0x01,
|
||||
0x38, 0x63, 0x06, 0x00, 0x48, 0x00, 0x04, 0xf9, 0x63, 0xec, 0x27, 0x88, 0x92, 0xac, 0x00, 0x00,
|
||||
0x92, 0xac, 0x00, 0x04, 0x92, 0xac, 0x00, 0x08, 0x63, 0xe4, 0x27, 0x98, 0x81, 0x24, 0x00, 0x18,
|
||||
0x80, 0x72, 0x00, 0x00, 0x2c, 0x03, 0x00, 0x02, 0x40, 0x82, 0x00, 0x0c, 0x41, 0x96, 0x00, 0x0c,
|
||||
0x48, 0x00, 0x00, 0x20, 0x38, 0x60, 0x00, 0x00, 0x90, 0x6c, 0x00, 0x0c, 0x40, 0x82, 0x00, 0x14,
|
||||
0x40, 0x96, 0x00, 0x10, 0x61, 0x29, 0x04, 0x00, 0x91, 0x24, 0x00, 0x18, 0x48, 0x00, 0x02, 0x14,
|
||||
0x55, 0x29, 0x05, 0xa8, 0x91, 0x24, 0x00, 0x18, 0x41, 0x96, 0x04, 0x54, 0x41, 0x9a, 0x00, 0x08,
|
||||
0x39, 0x8c, 0x00, 0x04, 0x38, 0x60, 0x00, 0x04, 0x48, 0x00, 0x03, 0x09, 0x40, 0x99, 0x00, 0x10,
|
||||
0x39, 0x8c, 0x00, 0x04, 0x38, 0x60, 0x00, 0x04, 0x48, 0x00, 0x02, 0xf9, 0x63, 0xe4, 0x27, 0x88,
|
||||
0x80, 0x64, 0x00, 0x00, 0x80, 0x84, 0x00, 0x04, 0x7c, 0x72, 0xfb, 0xa6, 0x7c, 0x95, 0xfb, 0xa6,
|
||||
0x48, 0x00, 0x04, 0x1c, 0x7c, 0x32, 0x43, 0xa6, 0x7c, 0x3a, 0x02, 0xa6, 0x7c, 0x73, 0x43, 0xa6,
|
||||
0x7c, 0x7b, 0x02, 0xa6, 0x54, 0x63, 0x05, 0xa8, 0x90, 0x60, 0x27, 0xb0, 0x54, 0x63, 0x06, 0x1e,
|
||||
0x60, 0x63, 0x20, 0x00, 0x7c, 0x7b, 0x03, 0xa6, 0x3c, 0x60, 0x80, 0x00, 0x60, 0x63, 0x1a, 0xe8,
|
||||
0x7c, 0x7a, 0x03, 0xa6, 0x4c, 0x00, 0x00, 0x64, 0x3c, 0x60, 0x80, 0x00, 0x60, 0x63, 0x27, 0x98,
|
||||
0x90, 0x23, 0x00, 0x14, 0x7c, 0x61, 0x1b, 0x78, 0x7c, 0x73, 0x42, 0xa6, 0xbc, 0x41, 0x00, 0x24,
|
||||
0x7c, 0x24, 0x0b, 0x78, 0x7c, 0x32, 0x42, 0xa6, 0x90, 0x04, 0x00, 0x1c, 0x90, 0x24, 0x00, 0x20,
|
||||
0x7c, 0x68, 0x02, 0xa6, 0x90, 0x64, 0x00, 0x9c, 0x7c, 0x60, 0x00, 0x26, 0x90, 0x64, 0x00, 0x00,
|
||||
0x7c, 0x61, 0x02, 0xa6, 0x90, 0x64, 0x00, 0x04, 0x7c, 0x69, 0x02, 0xa6, 0x90, 0x64, 0x00, 0x08,
|
||||
0x7c, 0x72, 0x02, 0xa6, 0x90, 0x64, 0x00, 0x0c, 0x7c, 0x73, 0x02, 0xa6, 0x90, 0x64, 0x00, 0x10,
|
||||
0x39, 0x20, 0x00, 0x00, 0x7d, 0x32, 0xfb, 0xa6, 0x7d, 0x35, 0xfb, 0xa6, 0x3c, 0xa0, 0x80, 0x00,
|
||||
0x60, 0xa5, 0x1b, 0x70, 0x3f, 0xe0, 0xd0, 0x04, 0x63, 0xff, 0x00, 0xa0, 0x93, 0xe5, 0x00, 0x00,
|
||||
0x7c, 0x00, 0x28, 0x6c, 0x7c, 0x00, 0x04, 0xac, 0x7c, 0x00, 0x2f, 0xac, 0x4c, 0x00, 0x01, 0x2c,
|
||||
0xd0, 0x04, 0x00, 0xa0, 0x3b, 0xff, 0x00, 0x04, 0x3f, 0xff, 0x00, 0x20, 0x57, 0xf0, 0x01, 0x4b,
|
||||
0x41, 0x82, 0xff, 0xdc, 0x3f, 0xe0, 0x80, 0x00, 0x63, 0xe5, 0x27, 0x88, 0x82, 0x05, 0x00, 0x00,
|
||||
0x82, 0x25, 0x00, 0x04, 0x82, 0x65, 0x00, 0x0c, 0x2c, 0x13, 0x00, 0x00, 0x41, 0x82, 0x00, 0x74,
|
||||
0x2c, 0x13, 0x00, 0x02, 0x40, 0x82, 0x00, 0x18, 0x81, 0x24, 0x00, 0x14, 0x39, 0x33, 0x00, 0x03,
|
||||
0x91, 0x25, 0x00, 0x00, 0x91, 0x25, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x6c, 0x7c, 0x10, 0x98, 0x00,
|
||||
0x41, 0x82, 0x00, 0x38, 0x7c, 0x11, 0x98, 0x00, 0x41, 0x82, 0x00, 0x30, 0x7d, 0x30, 0x8a, 0x14,
|
||||
0x91, 0x25, 0x00, 0x0c, 0x82, 0x05, 0x00, 0x08, 0x2c, 0x10, 0x00, 0x00, 0x41, 0x82, 0x00, 0x48,
|
||||
0x80, 0x64, 0x00, 0x10, 0x7c, 0x10, 0x18, 0x00, 0x40, 0x82, 0x00, 0x10, 0x3a, 0x00, 0x00, 0x00,
|
||||
0x92, 0x05, 0x00, 0x08, 0x48, 0x00, 0x00, 0x30, 0x3a, 0x20, 0x00, 0x00, 0x92, 0x25, 0x00, 0x0c,
|
||||
0x81, 0x24, 0x00, 0x18, 0x61, 0x29, 0x04, 0x00, 0x91, 0x24, 0x00, 0x18, 0x48, 0x00, 0x00, 0x30,
|
||||
0x7e, 0x12, 0xfb, 0xa6, 0x7e, 0x35, 0xfb, 0xa6, 0x39, 0x20, 0x00, 0x01, 0x91, 0x25, 0x00, 0x0c,
|
||||
0x48, 0x00, 0x00, 0x1c, 0x38, 0xa0, 0x00, 0x02, 0x63, 0xe4, 0x27, 0x74, 0x90, 0xa4, 0x00, 0x00,
|
||||
0x38, 0x60, 0x00, 0x11, 0x48, 0x00, 0x01, 0xb9, 0x4b, 0xff, 0xfc, 0x71, 0x7c, 0x20, 0x00, 0xa6,
|
||||
0x54, 0x21, 0x07, 0xfa, 0x54, 0x21, 0x04, 0x5e, 0x7c, 0x20, 0x01, 0x24, 0x63, 0xe1, 0x27, 0x98,
|
||||
0x80, 0x61, 0x00, 0x00, 0x7c, 0x6f, 0xf1, 0x20, 0x80, 0x61, 0x00, 0x14, 0x7c, 0x7a, 0x03, 0xa6,
|
||||
0x80, 0x61, 0x00, 0x18, 0x7c, 0x7b, 0x03, 0xa6, 0x80, 0x61, 0x00, 0x9c, 0x7c, 0x68, 0x03, 0xa6,
|
||||
0xb8, 0x41, 0x00, 0x24, 0x80, 0x01, 0x00, 0x1c, 0x80, 0x21, 0x00, 0x20, 0x4c, 0x00, 0x00, 0x64,
|
||||
0x92, 0xb2, 0x00, 0x00, 0x48, 0x00, 0x02, 0x54, 0x2e, 0x9d, 0x00, 0x02, 0x38, 0x60, 0x00, 0x08,
|
||||
0x63, 0xec, 0x27, 0x7c, 0x48, 0x00, 0x00, 0xfd, 0x80, 0xac, 0x00, 0x00, 0x80, 0x6c, 0x00, 0x04,
|
||||
0x98, 0x65, 0x00, 0x00, 0x41, 0x94, 0x00, 0x10, 0xb0, 0x65, 0x00, 0x00, 0x41, 0x96, 0x00, 0x08,
|
||||
0x90, 0x65, 0x00, 0x00, 0x7c, 0x00, 0x28, 0xac, 0x7c, 0x00, 0x04, 0xac, 0x7c, 0x00, 0x2f, 0xac,
|
||||
0x4c, 0x00, 0x01, 0x2c, 0x48, 0x00, 0x02, 0x08, 0x48, 0x00, 0x01, 0x21, 0x38, 0x60, 0x00, 0x04,
|
||||
0x63, 0xec, 0x27, 0x7c, 0x48, 0x00, 0x00, 0xbd, 0x82, 0x0c, 0x00, 0x00, 0x3d, 0x80, 0x80, 0x00,
|
||||
0x61, 0x8c, 0x28, 0xb8, 0x48, 0x00, 0x00, 0x1c, 0x48, 0x00, 0x01, 0x01, 0x38, 0x60, 0x00, 0x08,
|
||||
0x63, 0xec, 0x27, 0x7c, 0x48, 0x00, 0x00, 0x9d, 0x82, 0x0c, 0x00, 0x04, 0x81, 0x8c, 0x00, 0x00,
|
||||
0x63, 0xfb, 0x27, 0x84, 0x3a, 0x20, 0x0f, 0x80, 0x48, 0x00, 0x02, 0x39, 0x41, 0x82, 0x00, 0x20,
|
||||
0x7e, 0x23, 0x8b, 0x78, 0x48, 0x00, 0x00, 0x7d, 0x48, 0x00, 0x00, 0xd1, 0x41, 0x82, 0xff, 0xfc,
|
||||
0x7d, 0x8c, 0x72, 0x14, 0x35, 0x6b, 0xff, 0xff, 0x41, 0x81, 0xff, 0xe8, 0x80, 0x7b, 0x00, 0x00,
|
||||
0x2c, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0x08, 0x48, 0x00, 0x00, 0x59, 0x7c, 0x00, 0x60, 0xac,
|
||||
0x7c, 0x00, 0x04, 0xac, 0x7c, 0x00, 0x67, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x48, 0x00, 0x01, 0x80,
|
||||
0x7f, 0xc8, 0x02, 0xa6, 0x3c, 0x60, 0xa0, 0x00, 0x48, 0x00, 0x00, 0x15, 0x76, 0x03, 0x08, 0x00,
|
||||
0x56, 0x1d, 0x86, 0x3e, 0x7f, 0xc8, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20, 0x92, 0xf8, 0x68, 0x14,
|
||||
0x90, 0x78, 0x68, 0x24, 0x92, 0xd8, 0x68, 0x20, 0x80, 0xb8, 0x68, 0x20, 0x70, 0xa5, 0x00, 0x01,
|
||||
0x40, 0x82, 0xff, 0xf8, 0x82, 0x18, 0x68, 0x24, 0x90, 0xb8, 0x68, 0x14, 0x4e, 0x80, 0x00, 0x20,
|
||||
0x7d, 0x48, 0x02, 0xa6, 0x7c, 0x69, 0x03, 0xa6, 0x39, 0xc0, 0x00, 0x00, 0x48, 0x00, 0x00, 0x79,
|
||||
0x48, 0x00, 0x00, 0x75, 0x4b, 0xff, 0xff, 0xad, 0x41, 0x82, 0xff, 0xf4, 0x7f, 0xae, 0x61, 0xae,
|
||||
0x39, 0xce, 0x00, 0x01, 0x42, 0x00, 0xff, 0xe8, 0x7d, 0x48, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20,
|
||||
0x7d, 0x48, 0x02, 0xa6, 0x7c, 0x69, 0x03, 0xa6, 0x39, 0xc0, 0x00, 0x00, 0x7c, 0x6c, 0x70, 0xae,
|
||||
0x48, 0x00, 0x00, 0x1d, 0x41, 0x82, 0xff, 0xf8, 0x39, 0xce, 0x00, 0x01, 0x42, 0x00, 0xff, 0xf0,
|
||||
0x7d, 0x48, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20, 0x38, 0x60, 0x00, 0xaa, 0x7f, 0xc8, 0x02, 0xa6,
|
||||
0x54, 0x63, 0xa0, 0x16, 0x64, 0x63, 0xb0, 0x00, 0x3a, 0xc0, 0x00, 0x19, 0x3a, 0xe0, 0x00, 0xd0,
|
||||
0x3f, 0x00, 0xcc, 0x00, 0x4b, 0xff, 0xff, 0x69, 0x56, 0x03, 0x37, 0xff, 0x7f, 0xc8, 0x03, 0xa6,
|
||||
0x4e, 0x80, 0x00, 0x20, 0x7f, 0xc8, 0x02, 0xa6, 0x3c, 0x60, 0xd0, 0x00, 0x4b, 0xff, 0xff, 0x51,
|
||||
0x56, 0x03, 0x37, 0xff, 0x41, 0x82, 0xff, 0xf4, 0x7f, 0xc8, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20,
|
||||
0x4b, 0xff, 0xff, 0xb9, 0x38, 0x60, 0x00, 0x08, 0x63, 0xec, 0x27, 0x7c, 0x4b, 0xff, 0xff, 0x55,
|
||||
0x80, 0xac, 0x00, 0x04, 0x81, 0x8c, 0x00, 0x00, 0x63, 0xfb, 0x27, 0x84, 0x62, 0xb1, 0xf8, 0x00,
|
||||
0x7e, 0x0c, 0x28, 0x50, 0x48, 0x00, 0x00, 0xed, 0x41, 0x81, 0x00, 0x10, 0x82, 0x3b, 0x00, 0x00,
|
||||
0x2c, 0x11, 0x00, 0x00, 0x41, 0x82, 0x00, 0x68, 0x7e, 0x23, 0x8b, 0x78, 0x4b, 0xff, 0xff, 0x55,
|
||||
0x4b, 0xff, 0xff, 0xa5, 0x4b, 0xff, 0xff, 0xa1, 0x4b, 0xff, 0xfe, 0xd9, 0x41, 0x82, 0xff, 0xf4,
|
||||
0x2c, 0x1d, 0x00, 0xcc, 0x41, 0x82, 0x00, 0x48, 0x2c, 0x1d, 0x00, 0xbb, 0x41, 0x82, 0xff, 0xdc,
|
||||
0x2c, 0x1d, 0x00, 0xaa, 0x40, 0x82, 0xff, 0xdc, 0x7d, 0x8c, 0x72, 0x14, 0x35, 0x6b, 0xff, 0xff,
|
||||
0x41, 0x80, 0x00, 0x2c, 0x4b, 0xff, 0xff, 0xb4, 0x7e, 0xb5, 0xfb, 0xa6, 0x7e, 0xb2, 0xfb, 0xa6,
|
||||
0x63, 0xe4, 0x27, 0x98, 0x81, 0x24, 0x00, 0x18, 0x55, 0x29, 0x05, 0xa8, 0x91, 0x24, 0x00, 0x18,
|
||||
0x48, 0x00, 0x00, 0x0c, 0x38, 0x60, 0x00, 0x80, 0x4b, 0xff, 0xff, 0x25, 0x80, 0x92, 0x00, 0x00,
|
||||
0x2c, 0x04, 0x00, 0x00, 0x40, 0x82, 0xfa, 0x50, 0xb3, 0x94, 0x40, 0x10, 0xc8, 0x41, 0x00, 0x98,
|
||||
0xc8, 0x61, 0x00, 0xa0, 0x7f, 0x20, 0x00, 0xa6, 0x80, 0x01, 0x00, 0xac, 0x7c, 0x08, 0x03, 0xa6,
|
||||
0x80, 0x01, 0x00, 0x0c, 0x7c, 0x0f, 0xf1, 0x20, 0x80, 0x01, 0x00, 0x10, 0x7c, 0x09, 0x03, 0xa6,
|
||||
0x80, 0x01, 0x00, 0x14, 0x7c, 0x01, 0x03, 0xa6, 0xb8, 0x61, 0x00, 0x18, 0x80, 0x01, 0x00, 0x08,
|
||||
0x38, 0x21, 0x00, 0xa8, 0x4c, 0x00, 0x01, 0x2c, 0x4e, 0x80, 0x00, 0x20, 0x7e, 0x23, 0x20, 0x50,
|
||||
0x3c, 0xa0, 0x48, 0x00, 0x52, 0x25, 0x01, 0xba, 0x90, 0xa3, 0x00, 0x00, 0x7c, 0x00, 0x18, 0xac,
|
||||
0x7c, 0x00, 0x04, 0xac, 0x7c, 0x00, 0x1f, 0xac, 0x4c, 0x00, 0x01, 0x2c, 0x4e, 0x80, 0x00, 0x20,
|
||||
0x7d, 0x70, 0x8b, 0xd7, 0x7d, 0x4b, 0x89, 0xd6, 0x7d, 0x4a, 0x80, 0x50, 0x91, 0x5b, 0x00, 0x00,
|
||||
0x4e, 0x80, 0x00, 0x20, 0x7f, 0xa8, 0x02, 0xa6, 0x3d, 0xe0, 0x80, 0x00, 0x61, 0xef, 0x28, 0xb8,
|
||||
0x63, 0xe7, 0x18, 0x08, 0x3c, 0xc0, 0x80, 0x00, 0x7c, 0xd0, 0x33, 0x78, 0x39, 0x00, 0x00, 0x00,
|
||||
0x3c, 0x60, 0x00, 0xd0, 0x60, 0x63, 0xc0, 0xde, 0x80, 0x8f, 0x00, 0x00, 0x7c, 0x03, 0x20, 0x00,
|
||||
0x40, 0x82, 0x00, 0x18, 0x80, 0x8f, 0x00, 0x04, 0x7c, 0x03, 0x20, 0x00, 0x40, 0x82, 0x00, 0x0c,
|
||||
0x39, 0xef, 0x00, 0x08, 0x48, 0x00, 0x00, 0x0c, 0x7f, 0xa8, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20,
|
||||
0x80, 0x6f, 0x00, 0x00, 0x80, 0x8f, 0x00, 0x04, 0x39, 0xef, 0x00, 0x08, 0x71, 0x09, 0x00, 0x01,
|
||||
0x2f, 0x89, 0x00, 0x00, 0x39, 0x20, 0x00, 0x00, 0x54, 0x6a, 0x1f, 0x7e, 0x54, 0x65, 0x3f, 0x7e,
|
||||
0x74, 0x6b, 0x10, 0x00, 0x54, 0x63, 0x01, 0xfe, 0x40, 0x82, 0x00, 0x0c, 0x54, 0xcc, 0x00, 0x0c,
|
||||
0x48, 0x00, 0x00, 0x08, 0x7e, 0x0c, 0x83, 0x78, 0x2e, 0x05, 0x00, 0x00, 0x2c, 0x0a, 0x00, 0x01,
|
||||
0x41, 0xa0, 0x00, 0x2c, 0x41, 0xa2, 0x00, 0xe4, 0x2c, 0x0a, 0x00, 0x03, 0x41, 0xa0, 0x01, 0xac,
|
||||
0x41, 0x82, 0x02, 0x50, 0x2c, 0x0a, 0x00, 0x05, 0x41, 0x80, 0x02, 0xd4, 0x41, 0xa2, 0x04, 0xe0,
|
||||
0x2c, 0x0a, 0x00, 0x07, 0x41, 0xa0, 0x05, 0x0c, 0x48, 0x00, 0x05, 0xf0, 0x7d, 0x8c, 0x1a, 0x14,
|
||||
0x2c, 0x05, 0x00, 0x03, 0x41, 0x82, 0x00, 0x48, 0x41, 0x81, 0x00, 0x60, 0x40, 0xbe, 0xff, 0x84,
|
||||
0x2e, 0x05, 0x00, 0x01, 0x41, 0x91, 0x00, 0x2c, 0x54, 0x8a, 0x84, 0x3e, 0x41, 0x92, 0x00, 0x10,
|
||||
0x7c, 0x89, 0x61, 0xae, 0x39, 0x29, 0x00, 0x01, 0x48, 0x00, 0x00, 0x0c, 0x7c, 0x89, 0x63, 0x2e,
|
||||
0x39, 0x29, 0x00, 0x02, 0x35, 0x4a, 0xff, 0xff, 0x40, 0xa0, 0xff, 0xe4, 0x4b, 0xff, 0xff, 0x54,
|
||||
0x55, 0x8c, 0x00, 0x3a, 0x90, 0x8c, 0x00, 0x00, 0x4b, 0xff, 0xff, 0x48, 0x7c, 0x89, 0x23, 0x78,
|
||||
0x40, 0x9e, 0x04, 0xc8, 0x35, 0x29, 0xff, 0xff, 0x41, 0x80, 0x04, 0xc0, 0x7c, 0xa9, 0x78, 0xae,
|
||||
0x7c, 0xa9, 0x61, 0xae, 0x4b, 0xff, 0xff, 0xf0, 0x39, 0xef, 0x00, 0x08, 0x40, 0xbe, 0xff, 0x24,
|
||||
0x80, 0xaf, 0xff, 0xf8, 0x81, 0x6f, 0xff, 0xfc, 0x54, 0xb1, 0x04, 0x3e, 0x54, 0xaa, 0x85, 0x3e,
|
||||
0x54, 0xa5, 0x27, 0x3e, 0x2e, 0x85, 0x00, 0x01, 0x41, 0x96, 0x00, 0x10, 0x41, 0xb5, 0x00, 0x14,
|
||||
0x7c, 0x89, 0x61, 0xae, 0x48, 0x00, 0x00, 0x10, 0x7c, 0x89, 0x63, 0x2e, 0x48, 0x00, 0x00, 0x08,
|
||||
0x7c, 0x89, 0x61, 0x2e, 0x7c, 0x84, 0x5a, 0x14, 0x7d, 0x29, 0x8a, 0x14, 0x35, 0x4a, 0xff, 0xff,
|
||||
0x40, 0x80, 0xff, 0xd4, 0x4b, 0xff, 0xfe, 0xdc, 0x54, 0x69, 0x07, 0xff, 0x41, 0x82, 0x00, 0x10,
|
||||
0x55, 0x08, 0xf8, 0x7e, 0x71, 0x09, 0x00, 0x01, 0x2f, 0x89, 0x00, 0x00, 0x2e, 0x85, 0x00, 0x04,
|
||||
0x2d, 0x8a, 0x00, 0x05, 0x51, 0x08, 0x08, 0x3c, 0x40, 0x9e, 0x00, 0x78, 0x41, 0x8d, 0x04, 0xb8,
|
||||
0x7d, 0x8c, 0x1a, 0x14, 0x41, 0x8c, 0x00, 0x0c, 0x41, 0x94, 0x00, 0x30, 0x48, 0x00, 0x00, 0x1c,
|
||||
0x40, 0x94, 0x00, 0x10, 0x55, 0x8c, 0x00, 0x3a, 0x81, 0x6c, 0x00, 0x00, 0x48, 0x00, 0x00, 0x1c,
|
||||
0x55, 0x8c, 0x00, 0x3c, 0xa1, 0x6c, 0x00, 0x00, 0x7c, 0x89, 0x20, 0xf8, 0x55, 0x29, 0x84, 0x3e,
|
||||
0x7d, 0x6b, 0x48, 0x38, 0x54, 0x84, 0x04, 0x3e, 0x7f, 0x0b, 0x20, 0x40, 0x70, 0xa9, 0x00, 0x03,
|
||||
0x41, 0x82, 0x00, 0x18, 0x2c, 0x09, 0x00, 0x02, 0x41, 0x82, 0x00, 0x18, 0x41, 0x81, 0x00, 0x1c,
|
||||
0x40, 0x9a, 0x00, 0x20, 0x48, 0x00, 0x00, 0x18, 0x41, 0x9a, 0x00, 0x18, 0x48, 0x00, 0x00, 0x10,
|
||||
0x41, 0x99, 0x00, 0x10, 0x48, 0x00, 0x00, 0x08, 0x41, 0x98, 0x00, 0x08, 0x61, 0x08, 0x00, 0x01,
|
||||
0x40, 0x8e, 0xfe, 0x40, 0x41, 0x94, 0xfe, 0x3c, 0x81, 0x6f, 0xff, 0xf8, 0x40, 0x9e, 0x00, 0x20,
|
||||
0x70, 0x6c, 0x00, 0x08, 0x41, 0x82, 0x00, 0x0c, 0x71, 0x0c, 0x00, 0x01, 0x41, 0x82, 0x00, 0x10,
|
||||
0x39, 0x8b, 0x00, 0x10, 0x51, 0x8b, 0x03, 0x36, 0x48, 0x00, 0x00, 0x08, 0x55, 0x6b, 0x07, 0x16,
|
||||
0x91, 0x6f, 0xff, 0xf8, 0x4b, 0xff, 0xfe, 0x0c, 0x40, 0xbe, 0xfe, 0x08, 0x54, 0x69, 0x16, 0xba,
|
||||
0x54, 0x6e, 0x87, 0xfe, 0x2d, 0x8e, 0x00, 0x00, 0x2e, 0x05, 0x00, 0x04, 0x70, 0xae, 0x00, 0x03,
|
||||
0x2e, 0x8e, 0x00, 0x02, 0x41, 0x94, 0x00, 0x14, 0x41, 0x96, 0x00, 0x50, 0x7c, 0x64, 0x07, 0x34,
|
||||
0x7c, 0x84, 0x7a, 0x14, 0x48, 0x00, 0x00, 0x68, 0x54, 0x65, 0xa7, 0xff, 0x41, 0x82, 0x00, 0x0c,
|
||||
0x7d, 0x27, 0x48, 0x2e, 0x7c, 0x84, 0x4a, 0x14, 0x41, 0x8e, 0x00, 0x08, 0x7c, 0x8c, 0x22, 0x14,
|
||||
0x2e, 0x8e, 0x00, 0x01, 0x41, 0x96, 0x00, 0x08, 0x80, 0x84, 0x00, 0x00, 0x54, 0x63, 0x67, 0xff,
|
||||
0x41, 0x82, 0x00, 0x3c, 0x40, 0x90, 0x00, 0x0c, 0x7c, 0x84, 0x32, 0x14, 0x48, 0x00, 0x00, 0x30,
|
||||
0x7c, 0x84, 0x82, 0x14, 0x48, 0x00, 0x00, 0x28, 0x54, 0x65, 0xa7, 0xff, 0x41, 0x82, 0x00, 0x0c,
|
||||
0x7d, 0x27, 0x48, 0x2e, 0x7c, 0x84, 0x4a, 0x14, 0x40, 0x90, 0x00, 0x0c, 0x7c, 0xcc, 0x21, 0x2e,
|
||||
0x4b, 0xff, 0xfd, 0x80, 0x7e, 0x0c, 0x21, 0x2e, 0x4b, 0xff, 0xfd, 0x78, 0x40, 0x90, 0x00, 0x0c,
|
||||
0x7c, 0x86, 0x23, 0x78, 0x4b, 0xff, 0xfd, 0x6c, 0x7c, 0x90, 0x23, 0x78, 0x4b, 0xff, 0xfd, 0x64,
|
||||
0x54, 0x89, 0x1e, 0x78, 0x39, 0x29, 0x00, 0x40, 0x2c, 0x05, 0x00, 0x02, 0x41, 0x80, 0x00, 0x48,
|
||||
0x54, 0x6b, 0x50, 0x03, 0x41, 0x82, 0x00, 0x14, 0x41, 0x81, 0x00, 0x08, 0x48, 0x00, 0x00, 0x10,
|
||||
0x41, 0xbe, 0xfd, 0x40, 0x48, 0x00, 0x00, 0x08, 0x40, 0xbe, 0xfd, 0x38, 0x2c, 0x05, 0x00, 0x03,
|
||||
0x41, 0x81, 0x00, 0x10, 0x41, 0xa2, 0x00, 0x10, 0x7d, 0xe7, 0x48, 0x2e, 0x4b, 0xff, 0xfd, 0x24,
|
||||
0x7d, 0xe7, 0x49, 0x2e, 0x7c, 0x64, 0x07, 0x34, 0x54, 0x84, 0x1a, 0x78, 0x7d, 0xef, 0x22, 0x14,
|
||||
0x4b, 0xff, 0xfd, 0x10, 0x40, 0xbe, 0xfd, 0x0c, 0x7c, 0xa7, 0x4a, 0x14, 0x40, 0x92, 0x00, 0x14,
|
||||
0x54, 0x64, 0x04, 0x3e, 0x91, 0xe5, 0x00, 0x00, 0x90, 0x85, 0x00, 0x04, 0x4b, 0xff, 0xfc, 0xf4,
|
||||
0x81, 0x25, 0x00, 0x04, 0x2c, 0x09, 0x00, 0x00, 0x41, 0xa2, 0xfc, 0xe8, 0x39, 0x29, 0xff, 0xff,
|
||||
0x91, 0x25, 0x00, 0x04, 0x81, 0xe5, 0x00, 0x00, 0x4b, 0xff, 0xfc, 0xd8, 0x40, 0xbe, 0xfc, 0xd4,
|
||||
0x54, 0x6b, 0x16, 0xba, 0x7f, 0x47, 0x5a, 0x14, 0x81, 0x3a, 0x00, 0x00, 0x54, 0x6e, 0x67, 0xbe,
|
||||
0x41, 0x92, 0x00, 0x84, 0x2e, 0x05, 0x00, 0x05, 0x40, 0x90, 0x01, 0x74, 0x2e, 0x05, 0x00, 0x03,
|
||||
0x40, 0x90, 0x00, 0x90, 0x2e, 0x05, 0x00, 0x01, 0x54, 0x65, 0x87, 0xff, 0x41, 0x82, 0x00, 0x08,
|
||||
0x7c, 0x8c, 0x22, 0x14, 0x2f, 0x0e, 0x00, 0x01, 0x40, 0x92, 0x00, 0x24, 0x41, 0xb9, 0x00, 0x18,
|
||||
0x41, 0x9a, 0x00, 0x0c, 0x88, 0x84, 0x00, 0x00, 0x48, 0x00, 0x00, 0xf8, 0xa0, 0x84, 0x00, 0x00,
|
||||
0x48, 0x00, 0x00, 0xf0, 0x80, 0x84, 0x00, 0x00, 0x48, 0x00, 0x00, 0xe8, 0x54, 0x73, 0xe5, 0x3e,
|
||||
0x41, 0xb9, 0x00, 0x20, 0x41, 0x9a, 0x00, 0x10, 0x99, 0x24, 0x00, 0x00, 0x38, 0x84, 0x00, 0x01,
|
||||
0x48, 0x00, 0x00, 0x18, 0xb1, 0x24, 0x00, 0x00, 0x38, 0x84, 0x00, 0x02, 0x48, 0x00, 0x00, 0x0c,
|
||||
0x91, 0x24, 0x00, 0x00, 0x38, 0x84, 0x00, 0x04, 0x36, 0x73, 0xff, 0xff, 0x40, 0x80, 0xff, 0xd4,
|
||||
0x4b, 0xff, 0xfc, 0x40, 0x54, 0x65, 0x87, 0xff, 0x41, 0x82, 0x00, 0x08, 0x7c, 0x84, 0x62, 0x14,
|
||||
0x71, 0xc5, 0x00, 0x01, 0x41, 0x82, 0x00, 0x9c, 0x7c, 0x84, 0x4a, 0x14, 0x48, 0x00, 0x00, 0x94,
|
||||
0x54, 0x6a, 0x87, 0xbe, 0x54, 0x8e, 0x16, 0xba, 0x7e, 0x67, 0x72, 0x14, 0x40, 0x92, 0x00, 0x08,
|
||||
0x3a, 0x6f, 0xff, 0xfc, 0x80, 0x9a, 0x00, 0x00, 0x81, 0x33, 0x00, 0x00, 0x71, 0x4b, 0x00, 0x01,
|
||||
0x41, 0x82, 0x00, 0x08, 0x7c, 0x9a, 0x23, 0x78, 0x71, 0x4b, 0x00, 0x02, 0x41, 0x82, 0x00, 0x10,
|
||||
0x7d, 0x33, 0x4b, 0x78, 0x40, 0xb2, 0x00, 0x08, 0x7e, 0x6c, 0x9a, 0x14, 0x54, 0x65, 0x67, 0x3f,
|
||||
0x2c, 0x05, 0x00, 0x09, 0x40, 0x80, 0x00, 0x54, 0x48, 0x00, 0x00, 0x79, 0x7c, 0x89, 0x22, 0x14,
|
||||
0x48, 0x00, 0x00, 0x40, 0x7c, 0x89, 0x21, 0xd6, 0x48, 0x00, 0x00, 0x38, 0x7d, 0x24, 0x23, 0x78,
|
||||
0x48, 0x00, 0x00, 0x30, 0x7d, 0x24, 0x20, 0x38, 0x48, 0x00, 0x00, 0x28, 0x7d, 0x24, 0x22, 0x78,
|
||||
0x48, 0x00, 0x00, 0x20, 0x7d, 0x24, 0x20, 0x30, 0x48, 0x00, 0x00, 0x18, 0x7d, 0x24, 0x24, 0x30,
|
||||
0x48, 0x00, 0x00, 0x10, 0x5d, 0x24, 0x20, 0x3e, 0x48, 0x00, 0x00, 0x08, 0x7d, 0x24, 0x26, 0x30,
|
||||
0x90, 0x9a, 0x00, 0x00, 0x4b, 0xff, 0xfb, 0x8c, 0x2c, 0x05, 0x00, 0x0a, 0x41, 0x81, 0xfb, 0x84,
|
||||
0xc0, 0x5a, 0x00, 0x00, 0xc0, 0x73, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0c, 0xec, 0x43, 0x10, 0x2a,
|
||||
0x48, 0x00, 0x00, 0x08, 0xec, 0x43, 0x00, 0xb2, 0xd0, 0x5a, 0x00, 0x00, 0x4b, 0xff, 0xfb, 0x64,
|
||||
0x7d, 0x48, 0x02, 0xa6, 0x54, 0xa5, 0x1e, 0x78, 0x7d, 0x4a, 0x2a, 0x14, 0x80, 0x9a, 0x00, 0x00,
|
||||
0x81, 0x33, 0x00, 0x00, 0x7d, 0x48, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20, 0x40, 0xbe, 0xfb, 0x44,
|
||||
0x54, 0x69, 0xc0, 0x3e, 0x7d, 0x8e, 0x63, 0x78, 0x48, 0x00, 0x00, 0x35, 0x41, 0x92, 0x00, 0x0c,
|
||||
0x7e, 0x31, 0x22, 0x14, 0x48, 0x00, 0x00, 0x08, 0x7d, 0x29, 0x22, 0x14, 0x54, 0x64, 0xc4, 0x3f,
|
||||
0x38, 0xa0, 0x00, 0x00, 0x41, 0x82, 0xfb, 0x1c, 0x7d, 0x45, 0x88, 0xae, 0x7d, 0x45, 0x49, 0xae,
|
||||
0x38, 0xa5, 0x00, 0x01, 0x7c, 0x05, 0x20, 0x00, 0x4b, 0xff, 0xff, 0xec, 0x2e, 0x8a, 0x00, 0x04,
|
||||
0x55, 0x31, 0x36, 0xba, 0x2c, 0x11, 0x00, 0x3c, 0x7e, 0x27, 0x88, 0x2e, 0x40, 0x82, 0x00, 0x08,
|
||||
0x7d, 0xd1, 0x73, 0x78, 0x41, 0x96, 0x00, 0x08, 0xa2, 0x31, 0x00, 0x00, 0x55, 0x29, 0x56, 0xba,
|
||||
0x2c, 0x09, 0x00, 0x3c, 0x7d, 0x27, 0x48, 0x2e, 0x40, 0x82, 0x00, 0x08, 0x7d, 0xc9, 0x73, 0x78,
|
||||
0x41, 0x96, 0x00, 0x08, 0xa1, 0x29, 0x00, 0x00, 0x4e, 0x80, 0x00, 0x20, 0x2c, 0x05, 0x00, 0x04,
|
||||
0x40, 0x80, 0x00, 0x28, 0x7c, 0x89, 0x23, 0x78, 0x7d, 0xc3, 0x62, 0x14, 0x55, 0xce, 0x00, 0x3c,
|
||||
0x4b, 0xff, 0xff, 0xad, 0x7c, 0x84, 0x20, 0xf8, 0x54, 0x84, 0x04, 0x3e, 0x7d, 0x2b, 0x20, 0x38,
|
||||
0x7e, 0x24, 0x20, 0x38, 0x4b, 0xff, 0xfb, 0xc4, 0x54, 0x6b, 0xe4, 0x3e, 0x4b, 0xff, 0xfb, 0xbc,
|
||||
0x7c, 0x9a, 0x23, 0x78, 0x54, 0x84, 0x18, 0x38, 0x40, 0x92, 0x00, 0x20, 0x40, 0x9e, 0x00, 0x0c,
|
||||
0x7d, 0xe8, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x21, 0x7d, 0xe4, 0x7a, 0x14, 0x39, 0xef, 0x00, 0x07,
|
||||
0x55, 0xef, 0x00, 0x38, 0x4b, 0xff, 0xfa, 0x6c, 0x2e, 0x05, 0x00, 0x03, 0x41, 0x91, 0x00, 0x5c,
|
||||
0x3c, 0xa0, 0x48, 0x00, 0x7d, 0x83, 0x62, 0x14, 0x55, 0x8c, 0x00, 0x3a, 0x40, 0x92, 0x00, 0x20,
|
||||
0x40, 0xbe, 0xfa, 0x50, 0x57, 0x44, 0x00, 0x3a, 0x7c, 0x8c, 0x20, 0x50, 0x50, 0x85, 0x01, 0xba,
|
||||
0x50, 0x65, 0x07, 0xfe, 0x90, 0xac, 0x00, 0x00, 0x4b, 0xff, 0xfa, 0x38, 0x40, 0xbe, 0xff, 0xbc,
|
||||
0x7d, 0x2c, 0x78, 0x50, 0x51, 0x25, 0x01, 0xba, 0x90, 0xac, 0x00, 0x00, 0x39, 0x8c, 0x00, 0x04,
|
||||
0x7d, 0x6f, 0x22, 0x14, 0x39, 0x6b, 0xff, 0xfc, 0x7d, 0x2b, 0x60, 0x50, 0x51, 0x25, 0x01, 0xba,
|
||||
0x90, 0xab, 0x00, 0x00, 0x4b, 0xff, 0xff, 0x94, 0x2e, 0x05, 0x00, 0x06, 0x41, 0x92, 0x00, 0x28,
|
||||
0x4b, 0xff, 0xfb, 0x28, 0x55, 0x8c, 0x84, 0x3e, 0x57, 0x44, 0x84, 0x3e, 0x57, 0x5a, 0x04, 0x3e,
|
||||
0x7c, 0x0c, 0x20, 0x00, 0x41, 0x80, 0xfb, 0xa8, 0x7c, 0x0c, 0xd0, 0x00, 0x40, 0x80, 0xfb, 0xa0,
|
||||
0x4b, 0xff, 0xf9, 0xe0, 0x57, 0x45, 0xff, 0xfe, 0x68, 0xa5, 0x00, 0x01, 0x71, 0x03, 0x00, 0x01,
|
||||
0x7c, 0x05, 0x18, 0x00, 0x41, 0x82, 0x00, 0x1c, 0x51, 0x1a, 0x0f, 0xbc, 0x6b, 0x5a, 0x00, 0x02,
|
||||
0x57, 0x45, 0xff, 0xff, 0x41, 0x82, 0x00, 0x08, 0x6b, 0x5a, 0x00, 0x01, 0x93, 0x4f, 0xff, 0xfc,
|
||||
0x53, 0x48, 0x07, 0xfe, 0x4b, 0xff, 0xf9, 0xac, 0x2c, 0x0b, 0x00, 0x00, 0x41, 0x82, 0x01, 0x38,
|
||||
0x2c, 0x05, 0x00, 0x01, 0x41, 0x82, 0x00, 0x18, 0x2c, 0x05, 0x00, 0x02, 0x41, 0x82, 0x00, 0x14,
|
||||
0x2c, 0x05, 0x00, 0x03, 0x41, 0x82, 0x00, 0x70, 0x4b, 0xff, 0xf9, 0x80, 0x54, 0xcc, 0x00, 0x0c,
|
||||
0x54, 0x97, 0x46, 0x3e, 0x54, 0x98, 0xc4, 0x3e, 0x54, 0x84, 0x06, 0x3e, 0x40, 0x9e, 0x00, 0xfc,
|
||||
0x56, 0xf9, 0x06, 0x31, 0x7d, 0x9a, 0x63, 0x78, 0x7f, 0x43, 0xd2, 0x14, 0x57, 0x5a, 0x00, 0x3a,
|
||||
0x41, 0x82, 0x00, 0x18, 0x7e, 0xf7, 0x07, 0x74, 0x7e, 0xf7, 0x00, 0xd0, 0x1f, 0x37, 0x00, 0x02,
|
||||
0x3b, 0x39, 0x00, 0x04, 0x7f, 0x59, 0xd0, 0x50, 0x2c, 0x17, 0x00, 0x00, 0x41, 0x82, 0x00, 0x1c,
|
||||
0x3b, 0x20, 0x00, 0x00, 0x7e, 0xe9, 0x03, 0xa6, 0xa3, 0x7a, 0x00, 0x04, 0x7f, 0x79, 0xca, 0x78,
|
||||
0x3b, 0x5a, 0x00, 0x02, 0x42, 0x00, 0xff, 0xf4, 0x7c, 0x18, 0xc8, 0x00, 0x40, 0x82, 0x00, 0xac,
|
||||
0x4b, 0xff, 0xfe, 0x90, 0x51, 0x08, 0x08, 0x3c, 0x40, 0x9e, 0x00, 0x9c, 0x54, 0x77, 0xb0, 0x03,
|
||||
0x41, 0x81, 0x00, 0x88, 0x41, 0x80, 0x00, 0x8c, 0x54, 0x7e, 0x06, 0x3e, 0x1f, 0xde, 0x00, 0x02,
|
||||
0x54, 0x97, 0x00, 0x1e, 0x6e, 0xf8, 0x80, 0x00, 0x2c, 0x18, 0x00, 0x00, 0x40, 0x82, 0x00, 0x08,
|
||||
0x62, 0xf7, 0x30, 0x00, 0x54, 0x98, 0x80, 0x1e, 0x1f, 0x3e, 0x00, 0x04, 0x7f, 0x19, 0xc0, 0x50,
|
||||
0x3b, 0x20, 0x00, 0x00, 0x1f, 0x59, 0x00, 0x04, 0x7f, 0x6f, 0xd0, 0x2e, 0x7f, 0x57, 0xd0, 0x2e,
|
||||
0x3b, 0x39, 0x00, 0x01, 0x7c, 0x17, 0xc0, 0x40, 0x41, 0x81, 0x00, 0x34, 0x7c, 0x19, 0xf0, 0x00,
|
||||
0x41, 0x81, 0x00, 0x14, 0x7c, 0x1a, 0xd8, 0x00, 0x41, 0x82, 0xff, 0xdc, 0x3a, 0xf7, 0x00, 0x04,
|
||||
0x4b, 0xff, 0xff, 0xd0, 0x80, 0x6f, 0xff, 0xf8, 0x60, 0x63, 0x03, 0x00, 0x90, 0x6f, 0xff, 0xf8,
|
||||
0x92, 0xef, 0xff, 0xfc, 0x7e, 0xf0, 0xbb, 0x78, 0x48, 0x00, 0x00, 0x1c, 0x80, 0x6f, 0xff, 0xf8,
|
||||
0x60, 0x63, 0x01, 0x00, 0x90, 0x6f, 0xff, 0xf8, 0x61, 0x08, 0x00, 0x01, 0x48, 0x00, 0x00, 0x08,
|
||||
0x7c, 0x90, 0x23, 0x78, 0x54, 0x64, 0x06, 0x3e, 0x1c, 0x84, 0x00, 0x08, 0x7d, 0xe4, 0x7a, 0x14,
|
||||
0x4b, 0xff, 0xf8, 0x70, 0x40, 0x92, 0x00, 0x0c, 0x39, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x14,
|
||||
0x54, 0x69, 0x06, 0xff, 0x54, 0x65, 0x67, 0xfe, 0x7d, 0x08, 0x4c, 0x30, 0x55, 0x17, 0xff, 0xff,
|
||||
0x40, 0x82, 0x00, 0x08, 0x7d, 0x08, 0x2a, 0x78, 0x54, 0x85, 0x00, 0x1f, 0x41, 0x82, 0x00, 0x08,
|
||||
0x7c, 0xa6, 0x2b, 0x78, 0x54, 0x85, 0x80, 0x1f, 0x41, 0x82, 0x00, 0x08, 0x7c, 0xb0, 0x2b, 0x78,
|
||||
0x4b, 0xff, 0xf8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
//unsigned char kenobigc[2736] =
|
||||
//{
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x21, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x21, 0xff, 0x58, 0x90, 0x01, 0x00, 0x08,
|
||||
// 0x7c, 0x08, 0x02, 0xa6, 0x90, 0x01, 0x00, 0xac, 0x7c, 0x00, 0x00, 0x26, 0x90, 0x01, 0x00, 0x0c,
|
||||
// 0x7c, 0x09, 0x02, 0xa6, 0x90, 0x01, 0x00, 0x10, 0x7c, 0x01, 0x02, 0xa6, 0x90, 0x01, 0x00, 0x14,
|
||||
// 0xbc, 0x61, 0x00, 0x18, 0x7f, 0x20, 0x00, 0xa6, 0x63, 0x3a, 0x20, 0x00, 0x73, 0x5a, 0xf9, 0xff,
|
||||
// 0x7f, 0x40, 0x01, 0x24, 0xd8, 0x41, 0x00, 0x98, 0xd8, 0x61, 0x00, 0xa0, 0x3f, 0xe0, 0x80, 0x00,
|
||||
// 0x3e, 0x80, 0xcc, 0x00, 0xa3, 0x94, 0x40, 0x10, 0x63, 0x95, 0x00, 0xff, 0xb2, 0xb4, 0x40, 0x10,
|
||||
// 0x7f, 0xa8, 0x02, 0xa6, 0x3d, 0xe0, 0x80, 0x00, 0x61, 0xef, 0x22, 0xa8, 0x63, 0xe7, 0x18, 0x08,
|
||||
// 0x3c, 0xc0, 0x80, 0x00, 0x7c, 0xd0, 0x33, 0x78, 0x39, 0x00, 0x00, 0x00, 0x3c, 0x60, 0x00, 0xd0,
|
||||
// 0x60, 0x63, 0xc0, 0xde, 0x80, 0x8f, 0x00, 0x00, 0x7c, 0x03, 0x20, 0x00, 0x40, 0x82, 0x00, 0x18,
|
||||
// 0x80, 0x8f, 0x00, 0x04, 0x7c, 0x03, 0x20, 0x00, 0x40, 0x82, 0x00, 0x0c, 0x39, 0xef, 0x00, 0x08,
|
||||
// 0x48, 0x00, 0x00, 0x4c, 0x7f, 0xa8, 0x03, 0xa6, 0xb3, 0x94, 0x40, 0x10, 0xc8, 0x41, 0x00, 0x98,
|
||||
// 0xc8, 0x61, 0x00, 0xa0, 0x7f, 0x20, 0x00, 0xa6, 0x80, 0x01, 0x00, 0xac, 0x7c, 0x08, 0x03, 0xa6,
|
||||
// 0x80, 0x01, 0x00, 0x0c, 0x7c, 0x0f, 0xf1, 0x20, 0x80, 0x01, 0x00, 0x10, 0x7c, 0x09, 0x03, 0xa6,
|
||||
// 0x80, 0x01, 0x00, 0x14, 0x7c, 0x01, 0x03, 0xa6, 0xb8, 0x61, 0x00, 0x18, 0x80, 0x01, 0x00, 0x08,
|
||||
// 0x38, 0x21, 0x00, 0xa8, 0x4c, 0x00, 0x01, 0x2c, 0x4e, 0x80, 0x00, 0x20, 0x80, 0x6f, 0x00, 0x00,
|
||||
// 0x80, 0x8f, 0x00, 0x04, 0x39, 0xef, 0x00, 0x08, 0x71, 0x09, 0x00, 0x01, 0x2f, 0x89, 0x00, 0x00,
|
||||
// 0x39, 0x20, 0x00, 0x00, 0x54, 0x6a, 0x1f, 0x7e, 0x54, 0x65, 0x3f, 0x7e, 0x74, 0x6b, 0x10, 0x00,
|
||||
// 0x54, 0x63, 0x01, 0xfe, 0x40, 0x82, 0x00, 0x0c, 0x54, 0xcc, 0x00, 0x0c, 0x48, 0x00, 0x00, 0x08,
|
||||
// 0x7e, 0x0c, 0x83, 0x78, 0x2e, 0x05, 0x00, 0x00, 0x2c, 0x0a, 0x00, 0x01, 0x41, 0xa0, 0x00, 0x2c,
|
||||
// 0x41, 0xa2, 0x00, 0xe4, 0x2c, 0x0a, 0x00, 0x03, 0x41, 0xa0, 0x01, 0xac, 0x41, 0x82, 0x02, 0x50,
|
||||
// 0x2c, 0x0a, 0x00, 0x05, 0x41, 0x80, 0x02, 0xd4, 0x41, 0xa2, 0x04, 0xe0, 0x2c, 0x0a, 0x00, 0x07,
|
||||
// 0x41, 0xa0, 0x05, 0x0c, 0x48, 0x00, 0x05, 0xf0, 0x7d, 0x8c, 0x1a, 0x14, 0x2c, 0x05, 0x00, 0x03,
|
||||
// 0x41, 0x82, 0x00, 0x48, 0x41, 0x81, 0x00, 0x60, 0x40, 0xbe, 0xff, 0x84, 0x2e, 0x05, 0x00, 0x01,
|
||||
// 0x41, 0x91, 0x00, 0x2c, 0x54, 0x8a, 0x84, 0x3e, 0x41, 0x92, 0x00, 0x10, 0x7c, 0x89, 0x61, 0xae,
|
||||
// 0x39, 0x29, 0x00, 0x01, 0x48, 0x00, 0x00, 0x0c, 0x7c, 0x89, 0x63, 0x2e, 0x39, 0x29, 0x00, 0x02,
|
||||
// 0x35, 0x4a, 0xff, 0xff, 0x40, 0xa0, 0xff, 0xe4, 0x4b, 0xff, 0xff, 0x54, 0x55, 0x8c, 0x00, 0x3a,
|
||||
// 0x90, 0x8c, 0x00, 0x00, 0x4b, 0xff, 0xff, 0x48, 0x7c, 0x89, 0x23, 0x78, 0x40, 0x9e, 0x04, 0xc8,
|
||||
// 0x35, 0x29, 0xff, 0xff, 0x41, 0x80, 0x04, 0xc0, 0x7c, 0xa9, 0x78, 0xae, 0x7c, 0xa9, 0x61, 0xae,
|
||||
// 0x4b, 0xff, 0xff, 0xf0, 0x39, 0xef, 0x00, 0x08, 0x40, 0xbe, 0xff, 0x24, 0x80, 0xaf, 0xff, 0xf8,
|
||||
// 0x81, 0x6f, 0xff, 0xfc, 0x54, 0xb1, 0x04, 0x3e, 0x54, 0xaa, 0x85, 0x3e, 0x54, 0xa5, 0x27, 0x3e,
|
||||
// 0x2e, 0x85, 0x00, 0x01, 0x41, 0x96, 0x00, 0x10, 0x41, 0xb5, 0x00, 0x14, 0x7c, 0x89, 0x61, 0xae,
|
||||
// 0x48, 0x00, 0x00, 0x10, 0x7c, 0x89, 0x63, 0x2e, 0x48, 0x00, 0x00, 0x08, 0x7c, 0x89, 0x61, 0x2e,
|
||||
// 0x7c, 0x84, 0x5a, 0x14, 0x7d, 0x29, 0x8a, 0x14, 0x35, 0x4a, 0xff, 0xff, 0x40, 0x80, 0xff, 0xd4,
|
||||
// 0x4b, 0xff, 0xfe, 0xdc, 0x54, 0x69, 0x07, 0xff, 0x41, 0x82, 0x00, 0x10, 0x55, 0x08, 0xf8, 0x7e,
|
||||
// 0x71, 0x09, 0x00, 0x01, 0x2f, 0x89, 0x00, 0x00, 0x2e, 0x85, 0x00, 0x04, 0x2d, 0x8a, 0x00, 0x05,
|
||||
// 0x51, 0x08, 0x08, 0x3c, 0x40, 0x9e, 0x00, 0x78, 0x41, 0x8d, 0x04, 0xb8, 0x7d, 0x8c, 0x1a, 0x14,
|
||||
// 0x41, 0x8c, 0x00, 0x0c, 0x41, 0x94, 0x00, 0x30, 0x48, 0x00, 0x00, 0x1c, 0x40, 0x94, 0x00, 0x10,
|
||||
// 0x55, 0x8c, 0x00, 0x3a, 0x81, 0x6c, 0x00, 0x00, 0x48, 0x00, 0x00, 0x1c, 0x55, 0x8c, 0x00, 0x3c,
|
||||
// 0xa1, 0x6c, 0x00, 0x00, 0x7c, 0x89, 0x20, 0xf8, 0x55, 0x29, 0x84, 0x3e, 0x7d, 0x6b, 0x48, 0x38,
|
||||
// 0x54, 0x84, 0x04, 0x3e, 0x7f, 0x0b, 0x20, 0x40, 0x70, 0xa9, 0x00, 0x03, 0x41, 0x82, 0x00, 0x18,
|
||||
// 0x2c, 0x09, 0x00, 0x02, 0x41, 0x82, 0x00, 0x18, 0x41, 0x81, 0x00, 0x1c, 0x40, 0x9a, 0x00, 0x20,
|
||||
// 0x48, 0x00, 0x00, 0x18, 0x41, 0x9a, 0x00, 0x18, 0x48, 0x00, 0x00, 0x10, 0x41, 0x99, 0x00, 0x10,
|
||||
// 0x48, 0x00, 0x00, 0x08, 0x41, 0x98, 0x00, 0x08, 0x61, 0x08, 0x00, 0x01, 0x40, 0x8e, 0xfe, 0x40,
|
||||
// 0x41, 0x94, 0xfe, 0x3c, 0x81, 0x6f, 0xff, 0xf8, 0x40, 0x9e, 0x00, 0x20, 0x70, 0x6c, 0x00, 0x08,
|
||||
// 0x41, 0x82, 0x00, 0x0c, 0x71, 0x0c, 0x00, 0x01, 0x41, 0x82, 0x00, 0x10, 0x39, 0x8b, 0x00, 0x10,
|
||||
// 0x51, 0x8b, 0x03, 0x36, 0x48, 0x00, 0x00, 0x08, 0x55, 0x6b, 0x07, 0x16, 0x91, 0x6f, 0xff, 0xf8,
|
||||
// 0x4b, 0xff, 0xfe, 0x0c, 0x40, 0xbe, 0xfe, 0x08, 0x54, 0x69, 0x16, 0xba, 0x54, 0x6e, 0x87, 0xfe,
|
||||
// 0x2d, 0x8e, 0x00, 0x00, 0x2e, 0x05, 0x00, 0x04, 0x70, 0xae, 0x00, 0x03, 0x2e, 0x8e, 0x00, 0x02,
|
||||
// 0x41, 0x94, 0x00, 0x14, 0x41, 0x96, 0x00, 0x50, 0x7c, 0x64, 0x07, 0x34, 0x7c, 0x84, 0x7a, 0x14,
|
||||
// 0x48, 0x00, 0x00, 0x68, 0x54, 0x65, 0xa7, 0xff, 0x41, 0x82, 0x00, 0x0c, 0x7d, 0x27, 0x48, 0x2e,
|
||||
// 0x7c, 0x84, 0x4a, 0x14, 0x41, 0x8e, 0x00, 0x08, 0x7c, 0x8c, 0x22, 0x14, 0x2e, 0x8e, 0x00, 0x01,
|
||||
// 0x41, 0x96, 0x00, 0x08, 0x80, 0x84, 0x00, 0x00, 0x54, 0x63, 0x67, 0xff, 0x41, 0x82, 0x00, 0x3c,
|
||||
// 0x40, 0x90, 0x00, 0x0c, 0x7c, 0x84, 0x32, 0x14, 0x48, 0x00, 0x00, 0x30, 0x7c, 0x84, 0x82, 0x14,
|
||||
// 0x48, 0x00, 0x00, 0x28, 0x54, 0x65, 0xa7, 0xff, 0x41, 0x82, 0x00, 0x0c, 0x7d, 0x27, 0x48, 0x2e,
|
||||
// 0x7c, 0x84, 0x4a, 0x14, 0x40, 0x90, 0x00, 0x0c, 0x7c, 0xcc, 0x21, 0x2e, 0x4b, 0xff, 0xfd, 0x80,
|
||||
// 0x7e, 0x0c, 0x21, 0x2e, 0x4b, 0xff, 0xfd, 0x78, 0x40, 0x90, 0x00, 0x0c, 0x7c, 0x86, 0x23, 0x78,
|
||||
// 0x4b, 0xff, 0xfd, 0x6c, 0x7c, 0x90, 0x23, 0x78, 0x4b, 0xff, 0xfd, 0x64, 0x54, 0x89, 0x1e, 0x78,
|
||||
// 0x39, 0x29, 0x00, 0x40, 0x2c, 0x05, 0x00, 0x02, 0x41, 0x80, 0x00, 0x48, 0x54, 0x6b, 0x50, 0x03,
|
||||
// 0x41, 0x82, 0x00, 0x14, 0x41, 0x81, 0x00, 0x08, 0x48, 0x00, 0x00, 0x10, 0x41, 0xbe, 0xfd, 0x40,
|
||||
// 0x48, 0x00, 0x00, 0x08, 0x40, 0xbe, 0xfd, 0x38, 0x2c, 0x05, 0x00, 0x03, 0x41, 0x81, 0x00, 0x10,
|
||||
// 0x41, 0xa2, 0x00, 0x10, 0x7d, 0xe7, 0x48, 0x2e, 0x4b, 0xff, 0xfd, 0x24, 0x7d, 0xe7, 0x49, 0x2e,
|
||||
// 0x7c, 0x64, 0x07, 0x34, 0x54, 0x84, 0x1a, 0x78, 0x7d, 0xef, 0x22, 0x14, 0x4b, 0xff, 0xfd, 0x10,
|
||||
// 0x40, 0xbe, 0xfd, 0x0c, 0x7c, 0xa7, 0x4a, 0x14, 0x40, 0x92, 0x00, 0x14, 0x54, 0x64, 0x04, 0x3e,
|
||||
// 0x91, 0xe5, 0x00, 0x00, 0x90, 0x85, 0x00, 0x04, 0x4b, 0xff, 0xfc, 0xf4, 0x81, 0x25, 0x00, 0x04,
|
||||
// 0x2c, 0x09, 0x00, 0x00, 0x41, 0xa2, 0xfc, 0xe8, 0x39, 0x29, 0xff, 0xff, 0x91, 0x25, 0x00, 0x04,
|
||||
// 0x81, 0xe5, 0x00, 0x00, 0x4b, 0xff, 0xfc, 0xd8, 0x40, 0xbe, 0xfc, 0xd4, 0x54, 0x6b, 0x16, 0xba,
|
||||
// 0x7f, 0x47, 0x5a, 0x14, 0x81, 0x3a, 0x00, 0x00, 0x54, 0x6e, 0x67, 0xbe, 0x41, 0x92, 0x00, 0x84,
|
||||
// 0x2e, 0x05, 0x00, 0x05, 0x40, 0x90, 0x01, 0x74, 0x2e, 0x05, 0x00, 0x03, 0x40, 0x90, 0x00, 0x90,
|
||||
// 0x2e, 0x05, 0x00, 0x01, 0x54, 0x65, 0x87, 0xff, 0x41, 0x82, 0x00, 0x08, 0x7c, 0x8c, 0x22, 0x14,
|
||||
// 0x2f, 0x0e, 0x00, 0x01, 0x40, 0x92, 0x00, 0x24, 0x41, 0xb9, 0x00, 0x18, 0x41, 0x9a, 0x00, 0x0c,
|
||||
// 0x88, 0x84, 0x00, 0x00, 0x48, 0x00, 0x00, 0xf8, 0xa0, 0x84, 0x00, 0x00, 0x48, 0x00, 0x00, 0xf0,
|
||||
// 0x80, 0x84, 0x00, 0x00, 0x48, 0x00, 0x00, 0xe8, 0x54, 0x73, 0xe5, 0x3e, 0x41, 0xb9, 0x00, 0x20,
|
||||
// 0x41, 0x9a, 0x00, 0x10, 0x99, 0x24, 0x00, 0x00, 0x38, 0x84, 0x00, 0x01, 0x48, 0x00, 0x00, 0x18,
|
||||
// 0xb1, 0x24, 0x00, 0x00, 0x38, 0x84, 0x00, 0x02, 0x48, 0x00, 0x00, 0x0c, 0x91, 0x24, 0x00, 0x00,
|
||||
// 0x38, 0x84, 0x00, 0x04, 0x36, 0x73, 0xff, 0xff, 0x40, 0x80, 0xff, 0xd4, 0x4b, 0xff, 0xfc, 0x40,
|
||||
// 0x54, 0x65, 0x87, 0xff, 0x41, 0x82, 0x00, 0x08, 0x7c, 0x84, 0x62, 0x14, 0x71, 0xc5, 0x00, 0x01,
|
||||
// 0x41, 0x82, 0x00, 0x9c, 0x7c, 0x84, 0x4a, 0x14, 0x48, 0x00, 0x00, 0x94, 0x54, 0x6a, 0x87, 0xbe,
|
||||
// 0x54, 0x8e, 0x16, 0xba, 0x7e, 0x67, 0x72, 0x14, 0x40, 0x92, 0x00, 0x08, 0x3a, 0x6f, 0xff, 0xfc,
|
||||
// 0x80, 0x9a, 0x00, 0x00, 0x81, 0x33, 0x00, 0x00, 0x71, 0x4b, 0x00, 0x01, 0x41, 0x82, 0x00, 0x08,
|
||||
// 0x7c, 0x9a, 0x23, 0x78, 0x71, 0x4b, 0x00, 0x02, 0x41, 0x82, 0x00, 0x10, 0x7d, 0x33, 0x4b, 0x78,
|
||||
// 0x40, 0xb2, 0x00, 0x08, 0x7e, 0x6c, 0x9a, 0x14, 0x54, 0x65, 0x67, 0x3f, 0x2c, 0x05, 0x00, 0x09,
|
||||
// 0x40, 0x80, 0x00, 0x54, 0x48, 0x00, 0x00, 0x79, 0x7c, 0x89, 0x22, 0x14, 0x48, 0x00, 0x00, 0x40,
|
||||
// 0x7c, 0x89, 0x21, 0xd6, 0x48, 0x00, 0x00, 0x38, 0x7d, 0x24, 0x23, 0x78, 0x48, 0x00, 0x00, 0x30,
|
||||
// 0x7d, 0x24, 0x20, 0x38, 0x48, 0x00, 0x00, 0x28, 0x7d, 0x24, 0x22, 0x78, 0x48, 0x00, 0x00, 0x20,
|
||||
// 0x7d, 0x24, 0x20, 0x30, 0x48, 0x00, 0x00, 0x18, 0x7d, 0x24, 0x24, 0x30, 0x48, 0x00, 0x00, 0x10,
|
||||
// 0x5d, 0x24, 0x20, 0x3e, 0x48, 0x00, 0x00, 0x08, 0x7d, 0x24, 0x26, 0x30, 0x90, 0x9a, 0x00, 0x00,
|
||||
// 0x4b, 0xff, 0xfb, 0x8c, 0x2c, 0x05, 0x00, 0x0a, 0x41, 0x81, 0xfb, 0x84, 0xc0, 0x5a, 0x00, 0x00,
|
||||
// 0xc0, 0x73, 0x00, 0x00, 0x41, 0x82, 0x00, 0x0c, 0xec, 0x43, 0x10, 0x2a, 0x48, 0x00, 0x00, 0x08,
|
||||
// 0xec, 0x43, 0x00, 0xb2, 0xd0, 0x5a, 0x00, 0x00, 0x4b, 0xff, 0xfb, 0x64, 0x7d, 0x48, 0x02, 0xa6,
|
||||
// 0x54, 0xa5, 0x1e, 0x78, 0x7d, 0x4a, 0x2a, 0x14, 0x80, 0x9a, 0x00, 0x00, 0x81, 0x33, 0x00, 0x00,
|
||||
// 0x7d, 0x48, 0x03, 0xa6, 0x4e, 0x80, 0x00, 0x20, 0x40, 0xbe, 0xfb, 0x44, 0x54, 0x69, 0xc0, 0x3e,
|
||||
// 0x7d, 0x8e, 0x63, 0x78, 0x48, 0x00, 0x00, 0x35, 0x41, 0x92, 0x00, 0x0c, 0x7e, 0x31, 0x22, 0x14,
|
||||
// 0x48, 0x00, 0x00, 0x08, 0x7d, 0x29, 0x22, 0x14, 0x54, 0x64, 0xc4, 0x3f, 0x38, 0xa0, 0x00, 0x00,
|
||||
// 0x41, 0x82, 0xfb, 0x1c, 0x7d, 0x45, 0x88, 0xae, 0x7d, 0x45, 0x49, 0xae, 0x38, 0xa5, 0x00, 0x01,
|
||||
// 0x7c, 0x05, 0x20, 0x00, 0x4b, 0xff, 0xff, 0xec, 0x2e, 0x8a, 0x00, 0x04, 0x55, 0x31, 0x36, 0xba,
|
||||
// 0x2c, 0x11, 0x00, 0x3c, 0x7e, 0x27, 0x88, 0x2e, 0x40, 0x82, 0x00, 0x08, 0x7d, 0xd1, 0x73, 0x78,
|
||||
// 0x41, 0x96, 0x00, 0x08, 0xa2, 0x31, 0x00, 0x00, 0x55, 0x29, 0x56, 0xba, 0x2c, 0x09, 0x00, 0x3c,
|
||||
// 0x7d, 0x27, 0x48, 0x2e, 0x40, 0x82, 0x00, 0x08, 0x7d, 0xc9, 0x73, 0x78, 0x41, 0x96, 0x00, 0x08,
|
||||
// 0xa1, 0x29, 0x00, 0x00, 0x4e, 0x80, 0x00, 0x20, 0x2c, 0x05, 0x00, 0x04, 0x40, 0x80, 0x00, 0x28,
|
||||
// 0x7c, 0x89, 0x23, 0x78, 0x7d, 0xc3, 0x62, 0x14, 0x55, 0xce, 0x00, 0x3c, 0x4b, 0xff, 0xff, 0xad,
|
||||
// 0x7c, 0x84, 0x20, 0xf8, 0x54, 0x84, 0x04, 0x3e, 0x7d, 0x2b, 0x20, 0x38, 0x7e, 0x24, 0x20, 0x38,
|
||||
// 0x4b, 0xff, 0xfb, 0xc4, 0x54, 0x6b, 0xe4, 0x3e, 0x4b, 0xff, 0xfb, 0xbc, 0x7c, 0x9a, 0x23, 0x78,
|
||||
// 0x54, 0x84, 0x18, 0x38, 0x40, 0x92, 0x00, 0x20, 0x40, 0x9e, 0x00, 0x0c, 0x7d, 0xe8, 0x03, 0xa6,
|
||||
// 0x4e, 0x80, 0x00, 0x21, 0x7d, 0xe4, 0x7a, 0x14, 0x39, 0xef, 0x00, 0x07, 0x55, 0xef, 0x00, 0x38,
|
||||
// 0x4b, 0xff, 0xfa, 0x6c, 0x2e, 0x05, 0x00, 0x03, 0x41, 0x91, 0x00, 0x5c, 0x3c, 0xa0, 0x48, 0x00,
|
||||
// 0x7d, 0x83, 0x62, 0x14, 0x55, 0x8c, 0x00, 0x3a, 0x40, 0x92, 0x00, 0x20, 0x40, 0xbe, 0xfa, 0x50,
|
||||
// 0x57, 0x44, 0x00, 0x3a, 0x7c, 0x8c, 0x20, 0x50, 0x50, 0x85, 0x01, 0xba, 0x50, 0x65, 0x07, 0xfe,
|
||||
// 0x90, 0xac, 0x00, 0x00, 0x4b, 0xff, 0xfa, 0x38, 0x40, 0xbe, 0xff, 0xbc, 0x7d, 0x2c, 0x78, 0x50,
|
||||
// 0x51, 0x25, 0x01, 0xba, 0x90, 0xac, 0x00, 0x00, 0x39, 0x8c, 0x00, 0x04, 0x7d, 0x6f, 0x22, 0x14,
|
||||
// 0x39, 0x6b, 0xff, 0xfc, 0x7d, 0x2b, 0x60, 0x50, 0x51, 0x25, 0x01, 0xba, 0x90, 0xab, 0x00, 0x00,
|
||||
// 0x4b, 0xff, 0xff, 0x94, 0x2e, 0x05, 0x00, 0x06, 0x41, 0x92, 0x00, 0x28, 0x4b, 0xff, 0xfb, 0x28,
|
||||
// 0x55, 0x8c, 0x84, 0x3e, 0x57, 0x44, 0x84, 0x3e, 0x57, 0x5a, 0x04, 0x3e, 0x7c, 0x0c, 0x20, 0x00,
|
||||
// 0x41, 0x80, 0xfb, 0xa8, 0x7c, 0x0c, 0xd0, 0x00, 0x40, 0x80, 0xfb, 0xa0, 0x4b, 0xff, 0xf9, 0xe0,
|
||||
// 0x57, 0x45, 0xff, 0xfe, 0x68, 0xa5, 0x00, 0x01, 0x71, 0x03, 0x00, 0x01, 0x7c, 0x05, 0x18, 0x00,
|
||||
// 0x41, 0x82, 0x00, 0x1c, 0x51, 0x1a, 0x0f, 0xbc, 0x6b, 0x5a, 0x00, 0x02, 0x57, 0x45, 0xff, 0xff,
|
||||
// 0x41, 0x82, 0x00, 0x08, 0x6b, 0x5a, 0x00, 0x01, 0x93, 0x4f, 0xff, 0xfc, 0x53, 0x48, 0x07, 0xfe,
|
||||
// 0x4b, 0xff, 0xf9, 0xac, 0x2c, 0x0b, 0x00, 0x00, 0x41, 0x82, 0x01, 0x38, 0x2c, 0x05, 0x00, 0x01,
|
||||
// 0x41, 0x82, 0x00, 0x18, 0x2c, 0x05, 0x00, 0x02, 0x41, 0x82, 0x00, 0x14, 0x2c, 0x05, 0x00, 0x03,
|
||||
// 0x41, 0x82, 0x00, 0x70, 0x4b, 0xff, 0xf9, 0x40, 0x54, 0xcc, 0x00, 0x0c, 0x54, 0x97, 0x46, 0x3e,
|
||||
// 0x54, 0x98, 0xc4, 0x3e, 0x54, 0x84, 0x06, 0x3e, 0x40, 0x9e, 0x00, 0xfc, 0x56, 0xf9, 0x06, 0x31,
|
||||
// 0x7d, 0x9a, 0x63, 0x78, 0x7f, 0x43, 0xd2, 0x14, 0x57, 0x5a, 0x00, 0x3a, 0x41, 0x82, 0x00, 0x18,
|
||||
// 0x7e, 0xf7, 0x07, 0x74, 0x7e, 0xf7, 0x00, 0xd0, 0x1f, 0x37, 0x00, 0x02, 0x3b, 0x39, 0x00, 0x04,
|
||||
// 0x7f, 0x59, 0xd0, 0x50, 0x2c, 0x17, 0x00, 0x00, 0x41, 0x82, 0x00, 0x1c, 0x3b, 0x20, 0x00, 0x00,
|
||||
// 0x7e, 0xe9, 0x03, 0xa6, 0xa3, 0x7a, 0x00, 0x04, 0x7f, 0x79, 0xca, 0x78, 0x3b, 0x5a, 0x00, 0x02,
|
||||
// 0x42, 0x00, 0xff, 0xf4, 0x7c, 0x18, 0xc8, 0x00, 0x40, 0x82, 0x00, 0xac, 0x4b, 0xff, 0xfe, 0x90,
|
||||
// 0x51, 0x08, 0x08, 0x3c, 0x40, 0x9e, 0x00, 0x9c, 0x54, 0x77, 0xb0, 0x03, 0x41, 0x81, 0x00, 0x88,
|
||||
// 0x41, 0x80, 0x00, 0x8c, 0x54, 0x7e, 0x06, 0x3e, 0x1f, 0xde, 0x00, 0x02, 0x54, 0x97, 0x00, 0x1e,
|
||||
// 0x6e, 0xf8, 0x80, 0x00, 0x2c, 0x18, 0x00, 0x00, 0x40, 0x82, 0x00, 0x08, 0x62, 0xf7, 0x30, 0x00,
|
||||
// 0x54, 0x98, 0x80, 0x1e, 0x1f, 0x3e, 0x00, 0x04, 0x7f, 0x19, 0xc0, 0x50, 0x3b, 0x20, 0x00, 0x00,
|
||||
// 0x1f, 0x59, 0x00, 0x04, 0x7f, 0x6f, 0xd0, 0x2e, 0x7f, 0x57, 0xd0, 0x2e, 0x3b, 0x39, 0x00, 0x01,
|
||||
// 0x7c, 0x17, 0xc0, 0x40, 0x41, 0x81, 0x00, 0x34, 0x7c, 0x19, 0xf0, 0x00, 0x41, 0x81, 0x00, 0x14,
|
||||
// 0x7c, 0x1a, 0xd8, 0x00, 0x41, 0x82, 0xff, 0xdc, 0x3a, 0xf7, 0x00, 0x04, 0x4b, 0xff, 0xff, 0xd0,
|
||||
// 0x80, 0x6f, 0xff, 0xf8, 0x60, 0x63, 0x03, 0x00, 0x90, 0x6f, 0xff, 0xf8, 0x92, 0xef, 0xff, 0xfc,
|
||||
// 0x7e, 0xf0, 0xbb, 0x78, 0x48, 0x00, 0x00, 0x1c, 0x80, 0x6f, 0xff, 0xf8, 0x60, 0x63, 0x01, 0x00,
|
||||
// 0x90, 0x6f, 0xff, 0xf8, 0x61, 0x08, 0x00, 0x01, 0x48, 0x00, 0x00, 0x08, 0x7c, 0x90, 0x23, 0x78,
|
||||
// 0x54, 0x64, 0x06, 0x3e, 0x1c, 0x84, 0x00, 0x08, 0x7d, 0xe4, 0x7a, 0x14, 0x4b, 0xff, 0xf8, 0x70,
|
||||
// 0x40, 0x92, 0x00, 0x0c, 0x39, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x14, 0x54, 0x69, 0x06, 0xff,
|
||||
// 0x54, 0x65, 0x67, 0xfe, 0x7d, 0x08, 0x4c, 0x30, 0x55, 0x17, 0xff, 0xff, 0x40, 0x82, 0x00, 0x08,
|
||||
// 0x7d, 0x08, 0x2a, 0x78, 0x54, 0x85, 0x00, 0x1f, 0x41, 0x82, 0x00, 0x08, 0x7c, 0xa6, 0x2b, 0x78,
|
||||
// 0x54, 0x85, 0x80, 0x1f, 0x41, 0x82, 0x00, 0x08, 0x7c, 0xb0, 0x2b, 0x78, 0x4b, 0xff, 0xf8, 0x30,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
//};
|
82
Config.c
Normal file
82
Config.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include "Config.h"
|
||||
|
||||
DML_CFG *DMLCfg;
|
||||
|
||||
void ConfigInit( DML_CFG *Cfg )
|
||||
{
|
||||
DMLCfg = (DML_CFG*)0xFFFE4200;
|
||||
|
||||
memset32( DMLCfg, 0, sizeof(DML_CFG) );
|
||||
|
||||
//If a loader supplied any options we use them otherwise use the code defines
|
||||
if( Cfg->Magicbytes == 0xD1050CF6 )
|
||||
{
|
||||
memcpy( DMLCfg, Cfg, sizeof( DML_CFG ) );
|
||||
|
||||
} else {
|
||||
|
||||
dbgprintf("No valid config found in RAM\n");
|
||||
dbgprintf("Version:%08X\n", DMLCfg->Version );
|
||||
dbgprintf("Config :%08X\n", DMLCfg->Config );
|
||||
|
||||
DMLCfg->Config = 0;
|
||||
#ifdef CHEATHOOK
|
||||
DMLCfg->Config |= DML_CFG_CHEATS;
|
||||
#endif
|
||||
#ifdef DEBUGGER
|
||||
DMLCfg->Config |= DML_CFG_DEBUGGER;
|
||||
#endif
|
||||
#ifdef DEBUGGERWAIT
|
||||
DMLCfg->Config |= DML_CFG_DEBUGWAIT;
|
||||
#endif
|
||||
#ifdef CARDMODE
|
||||
DMLCfg->Config |= DML_CFG_NMM;
|
||||
#endif
|
||||
#ifdef CARDDEBUG
|
||||
DMLCfg->Config |= DML_CFG_NMM_DEBUG;
|
||||
#endif
|
||||
#ifdef ACTIVITYLED
|
||||
DMLCfg->Config |= DML_CFG_ACTIVITY_LED;
|
||||
#endif
|
||||
#ifdef PADHOOK
|
||||
DMLCfg->Config |= DML_CFG_PADHOOK;
|
||||
#endif
|
||||
DMLCfg->Magicbytes = 0xD1050CF6;
|
||||
DMLCfg->Version = CONFIG_VERSION;
|
||||
DMLCfg->VideoMode = DML_VID_DML_AUTO;
|
||||
}
|
||||
|
||||
//Check if a memcard is inserted in Slot A
|
||||
if( (read32(0xD806800) & 0x1000) == 0x1000 )
|
||||
{
|
||||
DMLCfg->Config &= ~DML_CFG_NMM; // disable NMM
|
||||
}
|
||||
|
||||
dbgprintf("Config:%08X\n", DMLCfg->Config );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
char *ConfigGetGamePath( void )
|
||||
{
|
||||
return DMLCfg->GamePath;
|
||||
}
|
||||
char *ConfigGetCheatPath( void )
|
||||
{
|
||||
return DMLCfg->CheatPath;
|
||||
}
|
100
Config.h
Normal file
100
Config.h
Normal file
@ -0,0 +1,100 @@
|
||||
#ifndef _CFG_
|
||||
#define _CFG_
|
||||
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
#include "alloc.h"
|
||||
#include "vsprintf.h"
|
||||
#include "HW.h"
|
||||
|
||||
#define EXI_BASE 0x0D806800
|
||||
|
||||
typedef struct GC_SRAM
|
||||
{
|
||||
/* 0x00 */ u16 CheckSum1;
|
||||
/* 0x02 */ u16 CheckSum2;
|
||||
/* 0x04 */ u32 ead0;
|
||||
/* 0x08 */ u32 ead1;
|
||||
/* 0x0C */ u32 CounterBias;
|
||||
/* 0x10 */ u8 DisplayOffsetH;
|
||||
/* 0x11 */ u8 BootMode; // Bit 6 PAL60 flag
|
||||
/* 0x12 */ u8 Language;
|
||||
/* 0x13 */ u8 Flags;
|
||||
/*
|
||||
bit desc 0 1
|
||||
0 -\_ Video mode
|
||||
1 -/
|
||||
2 Sound mode Mono Stereo
|
||||
3 always 1
|
||||
4 always 0
|
||||
5 always 1
|
||||
6 ?
|
||||
7 Prog mode off on
|
||||
*/
|
||||
/* 0x14 */ u8 FlashID[2*12];
|
||||
/* 0x2C */ u32 WirelessKBID;
|
||||
/* 0x30 */ u16 WirlessPADID[4];
|
||||
/* 0x38 */ u8 LastDVDError;
|
||||
/* 0x39 */ u8 Reserved;
|
||||
/* 0x3A */ u16 FlashIDChecksum[2];
|
||||
/* 0x3C */ u16 Unused;
|
||||
} GC_SRAM;
|
||||
|
||||
typedef struct DML_CFG
|
||||
{
|
||||
u32 Magicbytes; // 0xD1050CF6
|
||||
u32 Version; // 0x00000002
|
||||
u32 VideoMode;
|
||||
u32 Config;
|
||||
char GamePath[255];
|
||||
char CheatPath[255];
|
||||
} DML_CFG;
|
||||
|
||||
enum dmlconfig
|
||||
{
|
||||
DML_CFG_CHEATS = (1<<0),
|
||||
DML_CFG_DEBUGGER = (1<<1),
|
||||
DML_CFG_DEBUGWAIT = (1<<2),
|
||||
DML_CFG_NMM = (1<<3),
|
||||
DML_CFG_NMM_DEBUG = (1<<4),
|
||||
DML_CFG_GAME_PATH = (1<<5),
|
||||
DML_CFG_CHEAT_PATH = (1<<6),
|
||||
DML_CFG_ACTIVITY_LED= (1<<7),
|
||||
DML_CFG_PADHOOK = (1<<8),
|
||||
DML_CFG_FORCE_WIDE = (1<<9),
|
||||
DML_CFG_BOOT_DISC = (1<<10),
|
||||
DML_CFG_BOOT_DISC2 = (1<<11),
|
||||
DML_CFG_NODISC = (1<<12),
|
||||
DML_CFG_SCREENSHOT = (1<<13),
|
||||
};
|
||||
|
||||
enum dmlvideomode
|
||||
{
|
||||
DML_VID_DML_AUTO = (0<<16),
|
||||
DML_VID_FORCE = (1<<16),
|
||||
DML_VID_NONE = (2<<16),
|
||||
|
||||
DML_VID_FORCE_PAL50 = (1<<0),
|
||||
DML_VID_FORCE_PAL60 = (1<<1),
|
||||
DML_VID_FORCE_NTSC = (1<<2),
|
||||
DML_VID_FORCE_PROG = (1<<3),
|
||||
};
|
||||
|
||||
enum VideoModes
|
||||
{
|
||||
GCVideoModeNone = 0,
|
||||
GCVideoModePAL60 = 1,
|
||||
GCVideoModeNTSC = 2,
|
||||
GCVideoModePROG = 3,
|
||||
};
|
||||
|
||||
void ConfigInit( DML_CFG *Cfg );
|
||||
u32 ConfigGetConfig( u32 Config );
|
||||
void ConfigSetConfig( u32 Config );
|
||||
void ConfigClearConfig( u32 Config );
|
||||
u32 ConfigGetVideMode( void );
|
||||
|
||||
char *ConfigGetGamePath( void );
|
||||
char *ConfigGetCheatPath( void );
|
||||
|
||||
#endif
|
443
DVD.c
Normal file
443
DVD.c
Normal file
@ -0,0 +1,443 @@
|
||||
#include "DVD.h"
|
||||
|
||||
DVDConfig *DICfg = (DVDConfig *)NULL;
|
||||
u32 read;
|
||||
static char GamePath[256];
|
||||
|
||||
extern FIL GameFile;
|
||||
extern u32 FSTMode;
|
||||
extern u32 DOLMaxOff;
|
||||
extern u32 DOLOffset;
|
||||
|
||||
u8 HardDriveConnected;
|
||||
FATFS fatfs;
|
||||
|
||||
static u8 *FSTable ALIGNED(32);
|
||||
|
||||
u32 ApploaderSize = 0;
|
||||
u32 dolOffset = 0;
|
||||
u32 FSTableSize = 0;
|
||||
u32 FSTableOffset = 0;
|
||||
|
||||
u32 FCEntry=0;
|
||||
FileCache FC[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 )
|
||||
{
|
||||
int i=0;
|
||||
s32 fres = FR_DISK_ERR;
|
||||
int MountFail=0;
|
||||
HardDriveConnected = 0;
|
||||
|
||||
while(!HardDriveConnected)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
fres = f_mount(0, &fatfs );
|
||||
dbgprintf( "DIP:f_mount():%d\n", fres );
|
||||
if( fres == FR_OK )
|
||||
break;
|
||||
else
|
||||
MountFail++;
|
||||
|
||||
if( MountFail == 10 )
|
||||
{
|
||||
dbgprintf( "DIP:too much fail! looping now!\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
udelay(500000);
|
||||
}
|
||||
|
||||
//try to open a file, it doesn't have to exist, just testing if FS works
|
||||
FIL f;
|
||||
fres = f_open( &f, "/randmb.in", FA_READ|FA_OPEN_EXISTING );
|
||||
switch(fres)
|
||||
{
|
||||
case FR_OK:
|
||||
f_close( &f );
|
||||
case FR_NO_PATH:
|
||||
case FR_NO_FILE:
|
||||
{
|
||||
HardDriveConnected = 1;
|
||||
fres = FR_OK;
|
||||
} break;
|
||||
default:
|
||||
case FR_DISK_ERR:
|
||||
{
|
||||
dbgprintf( "DIP:Disk error\n", fres );
|
||||
while(1);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if( fres != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:Could not find any USB device!");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
s32 DVDSelectGame( void )
|
||||
{
|
||||
char *str = (char*)malloca( 256, 32 );
|
||||
u32 i=0;
|
||||
|
||||
if( ConfigGetConfig(DML_CFG_GAME_PATH) )
|
||||
{
|
||||
sprintf( str, "%s", ConfigGetGamePath() );
|
||||
|
||||
} else {
|
||||
dbgprintf("DIP:No game path was supplied!\n");
|
||||
free(str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 fres = f_open( &GameFile, str, FA_READ );
|
||||
if( fres != FR_OK )
|
||||
{
|
||||
sprintf( GamePath, "%s", str );
|
||||
|
||||
//Try to switch to FST mode
|
||||
if( !FSTInit() )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
DVDCreateLinkMap(&GameFile);
|
||||
|
||||
f_lseek( &GameFile, 0 );
|
||||
f_read( &GameFile, (void*)0, 0x20, &read );
|
||||
|
||||
f_lseek( &GameFile, 0 );
|
||||
f_read( &GameFile, str, 0x400, &read );
|
||||
|
||||
dbgprintf("DIP:Loading game %.6s: %s\n", str, (char *)(str+0x20));
|
||||
|
||||
f_lseek( &GameFile, 0x420 );
|
||||
f_read( &GameFile, str, 0x40, &read );
|
||||
}
|
||||
|
||||
free( str );
|
||||
|
||||
return DI_SUCCESS;
|
||||
}
|
||||
u32 FSTInit( void )
|
||||
{
|
||||
char Path[256];
|
||||
FIL fd;
|
||||
u32 read;
|
||||
|
||||
sprintf( Path, "%ssys/boot.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
|
||||
u8 *rbuf = (u8*)malloc( 0x100 );
|
||||
|
||||
f_lseek( &fd, 0 );
|
||||
f_read( &fd, rbuf, 0x100, &read );
|
||||
|
||||
dbgprintf("DIP:Loading game %.6s: %s\n", rbuf, (char *)(rbuf+0x20));
|
||||
|
||||
//Read DOL/FST offset/sizes for later usage
|
||||
f_lseek( &fd, 0x0420 );
|
||||
f_read( &fd, rbuf, 0x20, &read );
|
||||
|
||||
dolOffset = *(u32*)(rbuf);
|
||||
FSTableOffset = *(u32*)(rbuf+4);
|
||||
FSTableSize = *(u32*)(rbuf+8);
|
||||
|
||||
free( rbuf );
|
||||
|
||||
dbgprintf( "DIP:FSTableOffset:%08X\n", FSTableOffset );
|
||||
dbgprintf( "DIP:FSTableSize: %08X\n", FSTableSize );
|
||||
dbgprintf( "DIP:DolOffset: %08X\n", dolOffset );
|
||||
|
||||
FSTMode = 1;
|
||||
|
||||
f_close( &fd );
|
||||
}
|
||||
|
||||
//Init cache
|
||||
u32 count = 0;
|
||||
for( count=0; count < FILECACHE_MAX; ++count )
|
||||
{
|
||||
FCState[count] = 0xdeadbeef;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Asciify( char *str )
|
||||
{
|
||||
int i=0;
|
||||
for( i=0; i < strlen(str); i++ )
|
||||
if( str[i] < 0x20 || str[i] > 0x7F )
|
||||
str[i] = '_';
|
||||
}
|
||||
void FSTRead( char *Buffer, u32 Length, u32 Offset )
|
||||
{
|
||||
char Path[256];
|
||||
FIL fd;
|
||||
u32 read;
|
||||
int i,j;
|
||||
|
||||
if( Offset >= FSTableOffset+FSTableSize ) {
|
||||
|
||||
//Get FSTTable offset from low memory, must be set by apploader
|
||||
if( FSTable == NULL )
|
||||
{
|
||||
FSTable = (u8*)((*(vu32*)0x38) & 0x7FFFFFFF);
|
||||
//dbgprintf("DIP:FSTOffset: %08X\n", (u32)FSTable );
|
||||
}
|
||||
|
||||
//try cache first!
|
||||
for( i=0; i < FILECACHE_MAX; ++i )
|
||||
{
|
||||
if( FCState[i] == 0xdeadbeef )
|
||||
continue;
|
||||
|
||||
if( Offset >= FC[i].Offset )
|
||||
{
|
||||
u64 nOffset = Offset - FC[i].Offset;
|
||||
if( nOffset < FC[i].Size )
|
||||
{
|
||||
//dbgprintf("DIP:[Cache:%02d][%08X:%05X]\n", i, (u32)(nOffset>>2), Length );
|
||||
f_lseek( &(FC[i].File), nOffset );
|
||||
f_read( &(FC[i].File), Buffer, ((Length)+31)&(~31), &read );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//The fun part!
|
||||
|
||||
u32 Entries = *(u32*)(FSTable+0x08);
|
||||
char *NameOff = (char*)(FSTable + Entries * 0x0C);
|
||||
FEntry *fe = (FEntry*)(FSTable);
|
||||
|
||||
u32 Entry[16];
|
||||
u32 LEntry[16];
|
||||
u32 level=0;
|
||||
|
||||
for( i=1; i < Entries; ++i )
|
||||
{
|
||||
if( level )
|
||||
{
|
||||
while( LEntry[level-1] == i )
|
||||
{
|
||||
//printf("[%03X]leaving :\"%s\" Level:%d\n", i, buffer + NameOff + swap24( fe[Entry[level-1]].NameOffset ), level );
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
if( fe[i].Type )
|
||||
{
|
||||
//Skip empty folders
|
||||
if( fe[i].NextOffset == i+1 )
|
||||
continue;
|
||||
|
||||
//printf("[%03X]Entering:\"%s\" Level:%d leave:%04X\n", i, buffer + NameOff + swap24( fe[i].NameOffset ), level, swap32( fe[i].NextOffset ) );
|
||||
Entry[level] = i;
|
||||
LEntry[level++] = fe[i].NextOffset;
|
||||
if( level > 15 ) // something is wrong!
|
||||
break;
|
||||
} else {
|
||||
|
||||
if( Offset >= fe[i].FileOffset )
|
||||
{
|
||||
u32 nOffset = (Offset - fe[i].FileOffset);
|
||||
if( nOffset < fe[i].FileLength )
|
||||
{
|
||||
// dbgprintf("DIP:Offset:%08X FOffset:%08X Dif:%08X Flen:%08X nOffset:%08X\n", Offset, fe[i].FileOffset, Offset-fe[i].FileOffset, fe[i].FileLength, nOffset );
|
||||
|
||||
//Do not remove!
|
||||
memset( Path, 0, 256 );
|
||||
sprintf( Path, "%sroot/", GamePath );
|
||||
|
||||
for( j=0; j<level; ++j )
|
||||
{
|
||||
if( j )
|
||||
Path[strlen(Path)] = '/';
|
||||
memcpy( Path+strlen(Path), NameOff + fe[Entry[j]].NameOffset, strlen(NameOff + fe[Entry[j]].NameOffset ) );
|
||||
}
|
||||
if( level )
|
||||
Path[strlen(Path)] = '/';
|
||||
memcpy( Path+strlen(Path), NameOff + fe[i].NameOffset, strlen(NameOff + fe[i].NameOffset) );
|
||||
|
||||
if( FCEntry >= FILECACHE_MAX )
|
||||
FCEntry = 0;
|
||||
|
||||
if( FCState[FCEntry] != 0xdeadbeef )
|
||||
{
|
||||
f_close( &(FC[FCEntry].File) );
|
||||
FCState[FCEntry] = 0xdeadbeef;
|
||||
}
|
||||
|
||||
Asciify( Path );
|
||||
|
||||
f_open( &(FC[FCEntry].File), Path, FA_READ );
|
||||
|
||||
FC[FCEntry].Size = fe[i].FileLength;
|
||||
FC[FCEntry].Offset = fe[i].FileOffset;
|
||||
FCState[FCEntry] = 0x23;
|
||||
|
||||
DVDCreateLinkMap(&(FC[FCEntry].File));
|
||||
|
||||
f_lseek( &(FC[FCEntry].File), nOffset );
|
||||
f_read( &(FC[FCEntry].File), Buffer, Length, &read );
|
||||
|
||||
FCEntry++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ( Offset >= FSTableOffset ) {
|
||||
|
||||
Offset -= FSTableOffset;
|
||||
|
||||
sprintf( Path, "%ssys/fst.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[fst.bin] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
f_close( &fd );
|
||||
|
||||
if( FSTable == NULL )
|
||||
{
|
||||
FSTable = (u8*)Buffer;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ( Offset >= dolOffset ) {
|
||||
|
||||
Offset -= dolOffset;
|
||||
|
||||
sprintf( Path, "%ssys/main.dol", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[main.dol] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ( Offset >= 0x2440 ) {
|
||||
|
||||
Offset -= 0x2440;
|
||||
|
||||
sprintf( Path, "%ssys/apploader.img", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[apploader.img] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ( Offset >= 0x440 ) {
|
||||
|
||||
Offset -= 0x440;
|
||||
|
||||
sprintf( Path, "%ssys/bi2.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[bi2.bin] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
sprintf( Path, "%ssys/boot.bin", GamePath );
|
||||
if( f_open( &fd, Path, FA_READ ) != FR_OK )
|
||||
{
|
||||
dbgprintf( "DIP:[%s] Failed to open!\n", Path );
|
||||
return;
|
||||
} else {
|
||||
//dbgprintf( "DIP:[boot.bin] Offset:%08X Size:%08X\n", Offset, Length );
|
||||
|
||||
f_lseek( &fd, Offset );
|
||||
f_read( &fd, Buffer, Length, &read );
|
||||
|
||||
f_close( &fd );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
29
DVD.h
Normal file
29
DVD.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef _DVD_
|
||||
#define _DVD_
|
||||
|
||||
#include "global.h"
|
||||
#include "HW.h"
|
||||
#include "Config.h"
|
||||
#include "ff.h"
|
||||
#include "dol.h"
|
||||
#include "Drive.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 SlotID;
|
||||
u32 Region;
|
||||
u32 Gamecount;
|
||||
u32 Config;
|
||||
u8 GameInfo[][0x80];
|
||||
} DVDConfig;
|
||||
|
||||
void DVDInit( void );
|
||||
void DVDReadConfig( void );
|
||||
s32 DVDSelectGame( void );
|
||||
void DVDUpdateFSTRAM( void );
|
||||
void DiscBackup( u32 FrameBuffer );
|
||||
|
||||
u32 FSTInit( void );
|
||||
void FSTRead( char *Buffer, u32 Length, u32 Offset );
|
||||
|
||||
#endif
|
10
DVDPatches.c
Normal file
10
DVDPatches.c
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef __DVDPATCHES__
|
||||
#define __DVDPATCHES__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include "asm\DVDInquiryAsync.h"
|
||||
#include "asm\DVDSeekAbsAsyncPrio.h"
|
||||
#include "asm\padipc.h"
|
||||
|
||||
#endif
|
@ -1,2 +0,0 @@
|
||||
#labels Featured
|
||||
<wiki:gadget url="http://crediar.no-ip.com/down.xml" width="100%" height="400" up_projectName="diosmioslite"/>
|
124
Drive.c
Normal file
124
Drive.c
Normal file
@ -0,0 +1,124 @@
|
||||
#include "Drive.h"
|
||||
|
||||
void DVDLowReset( void )
|
||||
{
|
||||
clear32( HW_RESETS, (1<<10) | (1<<17) );
|
||||
set32( HW_RESETS, (1<<10) | (1<<17) );
|
||||
}
|
||||
u32 DVDLowGetError( void )
|
||||
{
|
||||
write32( 0x0D806000, 0x2E );
|
||||
write32( 0x0D806008, 0xE0000000 );
|
||||
write32( 0x0D806020, 0 );
|
||||
write32( 0x0D80601c, 1 );
|
||||
|
||||
while( read32(0x0D80601c) & 1 );
|
||||
|
||||
set32( 0x0D806000, (1<<4) );
|
||||
|
||||
return read32( 0x0D806020 );
|
||||
}
|
||||
u32 DVDLowSeek( void )
|
||||
{
|
||||
write32( 0x0D806000, 0x2E );
|
||||
write32( 0x0D806008, 0xAB000000 );
|
||||
write32( 0x0D806020, 0 );
|
||||
write32( 0x0D80601c, 1 );
|
||||
|
||||
while( read32(0x0D80601c) & 1 );
|
||||
|
||||
set32( 0x0D806000, (1<<4) );
|
||||
|
||||
return read32( 0x0D806020 );
|
||||
}
|
||||
u32 DVDLowStopMotor( void )
|
||||
{
|
||||
write32( 0x0D806000, 0x2E );
|
||||
write32( 0x0D806008, 0xE3000000 );
|
||||
write32( 0x0D806020, 0 );
|
||||
write32( 0x0D80601c, 1 );
|
||||
|
||||
while( read32(0x0D80601c) & 1 );
|
||||
|
||||
set32( 0x0D806000, (1<<4) );
|
||||
|
||||
return read32( 0x0D806020 );
|
||||
}
|
||||
u32 LowReadDiscID( void *data )
|
||||
{
|
||||
write32( 0x0D806008, 0xA8000040 );
|
||||
write32( 0x0D80600C, 0 );
|
||||
write32( 0x0D806010, 0x20 );
|
||||
write32( 0x0D806018, 0x20 );
|
||||
|
||||
write32( 0x0D806014, (u32)data );
|
||||
|
||||
write32( 0x0D806000, 0x3A );
|
||||
|
||||
write32( 0x0D80601C, 3 );
|
||||
|
||||
while (1)
|
||||
{
|
||||
if( read32( 0x0D806000 ) & (1<<2) )
|
||||
{
|
||||
set32( 0x0D806000, (1<<2) );
|
||||
return 1;
|
||||
}
|
||||
if( read32( 0x0D806000 ) & (1<<4) )
|
||||
{
|
||||
set32( 0x0D806000, (1<<4) );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
u32 LowRead( void *data, u32 Offset, u32 Length )
|
||||
{
|
||||
write32( 0x0D806008, 0xA8000000 );
|
||||
write32( 0x0D80600C, Offset>>2 );
|
||||
write32( 0x0D806010, Length );
|
||||
write32( 0x0D806018, Length );
|
||||
|
||||
write32( 0x0D806014, (u32)data );
|
||||
|
||||
write32( 0x0D806000, 0x3A );
|
||||
|
||||
write32( 0x0D80601C, 3 );
|
||||
|
||||
while (1)
|
||||
{
|
||||
if( read32( 0x0D806000 ) & (1<<2) )
|
||||
{
|
||||
set32( 0x0D806000, (1<<2) );
|
||||
return 1;
|
||||
}
|
||||
if( read32( 0x0D806000 ) & (1<<4) )
|
||||
{
|
||||
set32( 0x0D806000, (1<<4) );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
u32 DVDEnableAudioStreaming( u32 Enable )
|
||||
{
|
||||
write32( 0x0D806004, read32( 0x0D806004 ) );
|
||||
|
||||
write32( 0x0D806008, 0xE4000000 | (Enable<<16) | 0x0A );
|
||||
|
||||
write32( 0x0D80601C, 1 );
|
||||
|
||||
while( read32(0x0D80601C) & 1 );
|
||||
|
||||
while(1)
|
||||
{
|
||||
if( read32( 0x0D806000 ) & 4 )
|
||||
return DI_ERROR;
|
||||
if(!read32(0x0D806018))
|
||||
return DI_SUCCESS;
|
||||
}
|
||||
|
||||
return DI_FATAL;
|
||||
}
|
16
Drive.h
Normal file
16
Drive.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _DRIVE_
|
||||
#define _DRIVE_
|
||||
|
||||
#include "global.h"
|
||||
#include "HW.h"
|
||||
#include "memory.h"
|
||||
|
||||
void DVDLowReset( void );
|
||||
u32 DVDEnableAudioStreaming( u32 Enable );
|
||||
u32 DVDLowGetError( void );
|
||||
u32 DVDLowStopMotor( void );
|
||||
u32 LowReadDiscID( void *data );
|
||||
u32 LowRead( void *data, u32 Offset, u32 Length );
|
||||
u32 DVDLowSeek( void );
|
||||
|
||||
#endif
|
80
FAQ.wiki
80
FAQ.wiki
@ -1,80 +0,0 @@
|
||||
#labels Phase-Support,Featured
|
||||
#Mashup of frequently asked questions
|
||||
|
||||
<wiki:toc max_depth="2"/>
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= I just get a black screen (no DIOS MIOS splash screen) =
|
||||
Chances are high that your USB2IDE device isn't supported.
|
||||
* Assure that your HDD is formatted with FAT32, no other FS is supported.
|
||||
* Only cluster sizes 32KB or less are supported.
|
||||
* Only 2TB drives or less are supported.
|
||||
* The FAT32 partition MUST be the first primaly partition on the HDD, otherwise it will not work.
|
||||
* If all the above are ok try another USB2IDE device or wait for an update.
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= I just get a black screen AFTER the DIOS MIOS splash screen =
|
||||
Before anything check the [https://code.google.com/p/diosmios/wiki/GameIssues game issues] wiki page.
|
||||
If your game isn't listed you should try the following:
|
||||
* Verify that your dump is ok, just google for the md5 hash.
|
||||
* Try to install the game with DiscEX (without -c)
|
||||
* Assure that the game isn't just waiting for the debugger
|
||||
* Try to use a game version that matches your region
|
||||
* Verify your loader settings and turn off things like NMM/Force-Prog, NMM/Force-Prog can cause black screens
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= It takes long for the DIOS MIOS splash screen to show up =
|
||||
DIOS MIOS looks for an USB device on port 0 first and has code in place which waits for a device to become ready, only after (10seconds) it tries port 1.
|
||||
* Simply connect your device to port 0 instead.
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= I get a green screen after the DIOS MIOS splash screen =
|
||||
This usually can have three reasons:
|
||||
* You have the debugger with waiting enabled
|
||||
* The game just crashed (should get a crash dump via USBGecko if `__`fwrite patch was applied)
|
||||
* The game tried to switch from one video mode to another, usually happens when loading USA games on EUR systems or vice versa.
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= I get "Fatal error app_main:dst not in MEM1!" =
|
||||
GCLoader got incorrect data when reading from the ISO
|
||||
* Verify that your HDD is using 32KB cluster size or less, this error can happen with 64KB cluster size.
|
||||
* Verify that your dump is ok, just google for the md5 hash.
|
||||
* Try to install the game again (delete the old folder before)
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= I get "Fatal error apploader size is zero!" =
|
||||
This means DM was unable to mount the selected ISO for whatever reason.
|
||||
* Verify that your dump is ok, just google for the md5 hash.
|
||||
* Try to install the game again (delete the old folder before)
|
||||
* Your loader is using an incorrect config version
|
||||
* You installed DIOS MIOS and are trying to load a game from SD card
|
||||
* You installed DIOS MIOS Lite and are trying to load a game from an USB device
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= I get "Fatal error entrypoint is not within MEM1!" =
|
||||
This means the apploader could not load the main.dol
|
||||
* Verify that your dump is ok, just google for the md5 hash.
|
||||
* If you used GCReEX or DiscEX -c try DiscEX without -c to install the game as some games might break if you modify them
|
||||
* Try to install the game again (delete the old folder before)
|
||||
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= My system shuts down when using NMM while loading/saving =
|
||||
* In short NMM isn't supported for that game.
|
||||
* This means a fatal error occurred in the NMM code and it could no longer assure stable program execution.
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= NoDisc patch doesn't work =
|
||||
* It seems many loaders havn't caught up yet since NoDisc is no longer controlled via the config but instead just but either having a disc in the drive or not.
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= Will NTFS ever be supported? =
|
||||
* No, it would also take way more space than there is available. Just so you know libNTFS for Wii/GC is about 500KB, total memory DM can use is 96KB and almost everything is already used up.
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= Will the Wiimote/Classic Controller ever be supported? =
|
||||
* No, this would require a complete SDIO/BlueTooth/Wiimote lib, which would also take up way more space than available. (BT+Wiimote lib in libOGC are ~600KB).
|
||||
|
||||
[http://det1re.de/a/sneek/sneek_div.png]
|
||||
= Will WBFS ever be supported? =
|
||||
HAHA nice joke.
|
42
FwritePatches.c
Normal file
42
FwritePatches.c
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
unsigned char VIFlush[8] =
|
||||
{
|
||||
0x7C, 0x80, 0x03, 0x78,
|
||||
0x7C, 0xA3, 0x1B, 0x78,
|
||||
} ;
|
||||
|
||||
//unsigned char __fwrite[] =
|
||||
//{
|
||||
// 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0x88, 0x40, 0x86, 0x00, 0x24,
|
||||
//} ;
|
||||
//
|
||||
//unsigned char __fwriteGC[] =
|
||||
//{
|
||||
// 0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x34, 0xBF, 0x21, 0x00, 0x14,
|
||||
// 0x7C, 0x99, 0x23, 0x78, 0x7C, 0xDA, 0x33, 0x78, 0x7C, 0x7B, 0x1B, 0x78, 0x7C, 0xBC, 0x2B, 0x78,
|
||||
// 0x38, 0x80, 0x00, 0x00, 0x7F, 0x43, 0xD3, 0x78,
|
||||
//} ;
|
||||
//unsigned char __fwriteGCB[] =
|
||||
//{
|
||||
// 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x04, 0x94, 0x21, 0xFF, 0xB8, 0xBF, 0x21, 0x00, 0x2C,
|
||||
// 0x3B, 0x44, 0x00, 0x00, 0x3B, 0x66, 0x00, 0x00, 0x3B, 0x83, 0x00, 0x00, 0x3B, 0x25, 0x00, 0x00,
|
||||
// 0x38, 0x7B, 0x00, 0x00, 0x38, 0x80, 0x00, 0x00,
|
||||
//} ;
|
||||
//unsigned char __fwriteGCC[32] =
|
||||
//{
|
||||
// 0x94, 0x21, 0xFF, 0xB0, 0x7C, 0x08, 0x02, 0xA6, 0x90, 0x01, 0x00, 0x54, 0xBE, 0x81, 0x00, 0x20,
|
||||
// 0x7C, 0x97, 0x23, 0x78, 0x7C, 0xDF, 0x33, 0x78, 0x38, 0x80, 0x00, 0x00, 0x90, 0x61, 0x00, 0x08,
|
||||
//} ;
|
||||
|
||||
unsigned char patch_fwrite_GC[144] =
|
||||
{
|
||||
0x7C, 0x85, 0x21, 0xD7, 0x40, 0x81, 0x00, 0x84, 0x3C, 0xE0, 0xCC, 0x00, 0x3D, 0x40, 0xCC, 0x00,
|
||||
0x3D, 0x60, 0xCC, 0x00, 0x60, 0xE7, 0x68, 0x14, 0x61, 0x4A, 0x68, 0x24, 0x61, 0x6B, 0x68, 0x20,
|
||||
0x38, 0xC0, 0x00, 0x00, 0x7C, 0x06, 0x18, 0xAE, 0x54, 0x00, 0xA0, 0x16, 0x64, 0x08, 0xB0, 0x00,
|
||||
0x38, 0x00, 0x00, 0xD0, 0x90, 0x07, 0x00, 0x00, 0x7C, 0x00, 0x06, 0xAC, 0x91, 0x0A, 0x00, 0x00,
|
||||
0x7C, 0x00, 0x06, 0xAC, 0x38, 0x00, 0x00, 0x19, 0x90, 0x0B, 0x00, 0x00, 0x7C, 0x00, 0x06, 0xAC,
|
||||
0x80, 0x0B, 0x00, 0x00, 0x7C, 0x00, 0x04, 0xAC, 0x70, 0x09, 0x00, 0x01, 0x40, 0x82, 0xFF, 0xF4,
|
||||
0x80, 0x0A, 0x00, 0x00, 0x7C, 0x00, 0x04, 0xAC, 0x39, 0x20, 0x00, 0x00, 0x91, 0x27, 0x00, 0x00,
|
||||
0x7C, 0x00, 0x06, 0xAC, 0x74, 0x09, 0x04, 0x00, 0x41, 0x82, 0xFF, 0xB8, 0x38, 0xC6, 0x00, 0x01,
|
||||
0x7F, 0x86, 0x20, 0x00, 0x40, 0x9E, 0xFF, 0xA0, 0x7C, 0xA3, 0x2B, 0x78, 0x4E, 0x80, 0x00, 0x20,
|
||||
};
|
47
GCPad.h
Normal file
47
GCPad.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef __GCPAD__
|
||||
#define __GCPAD__
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool ErrorStatus :1;
|
||||
bool ErrorLatch :1;
|
||||
u32 Reserved :1;
|
||||
bool Start :1;
|
||||
|
||||
bool Y :1;
|
||||
bool X :1;
|
||||
bool B :1;
|
||||
bool A :1;
|
||||
|
||||
u32 AlwaysSet :1;
|
||||
bool R :1;
|
||||
bool L :1;
|
||||
bool Z :1;
|
||||
|
||||
bool Up :1;
|
||||
bool Down :1;
|
||||
bool Right :1;
|
||||
bool Left :1;
|
||||
|
||||
s16 StickX :8;
|
||||
s16 StickY :8;
|
||||
};
|
||||
u32 Buttons;
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
s16 CStickX;
|
||||
s16 CStickY;
|
||||
s16 LShoulder;
|
||||
s16 RShoulder;
|
||||
};
|
||||
u32 Sticks;
|
||||
};
|
||||
} GCPadStatus;
|
||||
#endif
|
||||
|
@ -1,73 +0,0 @@
|
||||
#summary This page has a list of games that have issues or require fixing to work on DIOS MIOS
|
||||
#labels Featured
|
||||
|
||||
|
||||
= Games that don't work due certain protections=
|
||||
|
||||
|| Name || Reason ||
|
||||
|| PSO 3 || Seems to selfcheck itself and stuff (check) ||
|
||||
|
||||
|
||||
|
||||
= Games that break when modifying the ISO using DiscEX -c =
|
||||
|
||||
|
||||
|| Name || Reason ||
|
||||
|| Kirby's Air Ride || Unknown ||
|
||||
|| Phantasy Star Online Episode I & II || hack requires unchanged FST ||
|
||||
|
||||
= Games that break when modifying the ISO using GCReEx -x =
|
||||
|
||||
|
||||
|| Name || Reason ||
|
||||
|| The Legend of Zelda Collector's Edition || Unknown ||
|
||||
|| The Legend of Zelda OoT/Master Quest || Unknown ||
|
||||
|| AUS Multi Game Demo Disc 3 || Unknown ||
|
||||
|| Metroid Prime 2: Echoes Bonus Disc || Unknown ||
|
||||
|| Star Wars Rebel Strike Preview Disc || Unknown ||
|
||||
|| Nintendo GameCube Preview Disc: May 2003 || Unknown ||
|
||||
|| Sonic Gems Collection || Unknown ||
|
||||
|| Enter the Matrix || Unknown ||
|
||||
|| Mario Party 4 || Unknown ||
|
||||
|
||||
Probably all games that use TGCs.
|
||||
|
||||
|
||||
= Games that have issue due using audio streaming =
|
||||
|| Name || Effect ||
|
||||
|| 1080 Avalanche || No music during gameplay ||
|
||||
|| IKARUGA || No music during gameplay ||
|
||||
|| XGRA - Extreme G Racing Association || No music during gameplay ||
|
||||
|| Eternal Darkness || No music during gameplay ||
|
||||
|| Mario Soccer || No music during gameplay ||
|
||||
|| Mario Superstar Baseb || No music during gameplay ||
|
||||
|| Star Fox Adventures || No voices and music, subtitles are late ||
|
||||
|| Super Monkey Ball || No music during gameplay ||
|
||||
|| WAVE RACE BLUE STORM || No music during gameplay ||
|
||||
|| Bomberman Generation || No music during gameplay ||
|
||||
|| Bloody Roar: Primal Fury || No music during gameplay ||
|
||||
|| MX Superfly || No music during gameplay ||
|
||||
|| Resident Evil 4 Preview Disc || No music during gameplay ||
|
||||
|| Shikigami no Shiro II || No music during gameplay ||
|
||||
|| Naruto: Clash of Ninja || No music/dialog during gameplay ||
|
||||
|| Naruto: Clash of Ninja 2 || No music/dialog during gameplay ||
|
||||
|| Star Wars: The Clone Wars || No music during gameplay ||
|
||||
|| Tak and the Power of Juju || No music during gameplay ||
|
||||
|| Tony Hawk's Pro Skater 3 || No music during gameplay ||
|
||||
|| Tony Hawk's Pro Skater 4 || No music during gameplay ||
|
||||
|| Tube Slider || No music during gameplay ||
|
||||
|| Legend of Zelda: Ocarina of Time / Master Quest || No music during game selection ||
|
||||
|| Lotus Challenge || No music during gameplay ||
|
||||
|| Lost Kingdoms || No music during gameplay ||
|
||||
|| Alien Hominid || No music during gameplay ||
|
||||
|| Crazy Taxi || No music during gameplay ||
|
||||
|| Crash Bandicoot The Wrath of Cortex || No music during gameplay ||
|
||||
|| Cel Damage || No music during gameplay ||
|
||||
|| Star Wars: Jedi Knight II: Jedi Outcast || No music during gameplay ||
|
||||
|
||||
|
||||
|
||||
= Games that have issue due MIOS patching not being applied =
|
||||
|
||||
==*[http://crediar.no-ip.com/gc/ Official DIOS MIOS (Lite) Compatibility List]*==
|
||||
|
88
HW.h
Normal file
88
HW.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef _HW_
|
||||
#define _HW_
|
||||
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "alloc.h"
|
||||
#include "dip.h"
|
||||
#include "GCPad.h"
|
||||
|
||||
#define P2C(x) ((x)&0x7FFFFFFF)
|
||||
|
||||
#define HW_BASE 0x0d800000
|
||||
#define HW_MEMIRR (HW_BASE+0x60)
|
||||
#define HW_AHBPROT (HW_BASE+0x64)
|
||||
|
||||
#define HW_DDRCTRL_ADDR (HW_BASE+0x74)
|
||||
#define HW_DDRCTRL_VAL (HW_BASE+0x76)
|
||||
|
||||
#define HW_GPIO_ENABLE (HW_BASE+0xDC)
|
||||
#define HW_GPIO_OUT (HW_BASE+0xE0)
|
||||
#define HW_GPIO_DIR (HW_BASE+0xE4)
|
||||
#define HW_GPIO_IN (HW_BASE+0xE8)
|
||||
#define HW_GPIO_INTLVL (HW_BASE+0xEC)
|
||||
#define HW_GPIO_INTFLAG (HW_BASE+0xF0)
|
||||
#define HW_GPIO_INTMASK (HW_BASE+0xF4)
|
||||
#define HW_GPIO_INMIR (HW_BASE+0xF8)
|
||||
#define HW_GPIO_OWNER (HW_BASE+0xFC)
|
||||
|
||||
#define HW_ACRPLLSYS (HW_BASE+0x1B0)
|
||||
#define HW_ACRPLLSYSEXT (HW_BASE+0x1B4)
|
||||
|
||||
#define DIFLAGS_PPCBOOT (1<<20)
|
||||
|
||||
|
||||
#define IRQ_TIMER (1<<0)
|
||||
#define IRQ_NAND (1<<1)
|
||||
#define IRQ_AES (1<<2)
|
||||
#define IRQ_SHA1 (1<<3)
|
||||
#define IRQ_EHCI (1<<4)
|
||||
#define IRQ_OHCI0 (1<<5)
|
||||
#define IRQ_OHCI1 (1<<6)
|
||||
#define IRQ_SDHC (1<<7)
|
||||
#define IRQ_WIFI (1<<8)
|
||||
#define IRQ_GPIO1B (1<<10)
|
||||
#define IRQ_GPIO1 (1<<11)
|
||||
#define IRQ_RESET (1<<17)
|
||||
#define IRQ_PPCIPC (1<<30)
|
||||
#define IRQ_IPC (1<<31)
|
||||
|
||||
#define GPIO_POWER (1<<1)
|
||||
#define GPIO_EJECT (1<<9)
|
||||
|
||||
extern void DRAMCTRLWrite( u32 Register, u32 Value );
|
||||
extern u32 DRAMCTRLRead( u32 Register );
|
||||
|
||||
void EHCIInit( void );
|
||||
|
||||
void EXIControl( u32 value );
|
||||
|
||||
void MIOSHWInit( u32 A, u32 B );
|
||||
void MIOSInit( void );
|
||||
void MEMInitLow( void );
|
||||
void BootPPC( void );
|
||||
void UNKInit( u32 A, u32 B );
|
||||
void DRAMInit( u32 A, u32 B );
|
||||
void ChangeClock( void );
|
||||
void PPCReset( void );
|
||||
void HWResetDisable( void );
|
||||
void HWResetEnable( void );
|
||||
void HW_184( void );
|
||||
void HW_184_2( void );
|
||||
|
||||
void GetRevision( u32 *Version, u32 *Revision );
|
||||
|
||||
void HWMAgic( u32 R0, u32 R1, u32 R2, u32 R3 );
|
||||
|
||||
u32 DRAMRead( u32 ValueA );
|
||||
void DRAMWrite( u32 ValueA, u32 ValueB );
|
||||
|
||||
u32 RegRead( u32 Register );
|
||||
void RegWrite( u32 Register, u32 Value );
|
||||
void HWRegWriteBatch( u32 A, u32 B, u32 C, u32 D, u32 delay );
|
||||
|
||||
void Shutdown( void );
|
||||
|
||||
#endif
|
53
Makefile
Normal file
53
Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
PREFIX = $(DEVKITARM)/bin/arm-eabi-
|
||||
CC = $(PREFIX)gcc
|
||||
AS = $(PREFIX)as
|
||||
LD = $(PREFIX)gcc
|
||||
SSTRIP = $(DEVKITARM)/bin/arm-eabi-strip
|
||||
|
||||
CFLAGS = -mbig-endian -fomit-frame-pointer -O2 -Wall -I. -mcpu=arm926ej-s -mthumb
|
||||
CFLAGS += -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-toupper -fno-builtin-memcmp -fno-builtin-malloc -fno-builtin-free
|
||||
|
||||
ASFLAGS = -mbig-endian -mcpu=arm926ej-s
|
||||
|
||||
LDFLAGS = -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,iosmodule.ld,-Map,iosmodule.map -n
|
||||
|
||||
LIBS = -lgcc
|
||||
|
||||
TARGET = iosmodule.elf
|
||||
OBJECTS = start.o utils_asm.o HW.o Card.o memory.o memory_asm.o Config.o common.o ff.o diskio.o alloc.o Drive.o DVD.o dip.o Patches.o main.o vsprintf.o string.o tiny_ehci_glue.o usb_os.o
|
||||
.PHONY: FORCE
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET) : iosmodule.ld $(OBJECTS)
|
||||
@echo "LD $@"
|
||||
@$(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
|
||||
@echo $(SSTRIP) -s $@
|
||||
|
||||
|
||||
%.o : %.s
|
||||
@echo "AS $@"
|
||||
@$(CC) $(CFLAGS) -D_LANGUAGE_ASSEMBLY -c -x assembler-with-cpp -o $@ $<
|
||||
|
||||
%.o : %.S
|
||||
@echo "AS $@"
|
||||
@$(CC) $(CFLAGS) -D_LANGUAGE_ASSEMBLY -c -x assembler-with-cpp -o $@ $<
|
||||
|
||||
%.o : %.c
|
||||
@echo "CC $@"
|
||||
@$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
%.d: %.c
|
||||
@echo "DEP $@"
|
||||
@set -e; $(CC) -M $(CFLAGS) $< \
|
||||
| sed 's?\($*\)\.o[ :]*?\1.o $@ : ?g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
%.d: %.S
|
||||
@echo "DEP $@"
|
||||
@touch $@
|
||||
|
||||
-include $(OBJECTS:.o=.d)
|
||||
|
||||
clean:
|
||||
-rm -f *.elf *.o *.bin *.d *.map
|
84
Patches.h
Normal file
84
Patches.h
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef _PATCHES_
|
||||
#define _PATCHES_
|
||||
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
#include "alloc.h"
|
||||
#include "ff.h"
|
||||
#include "vsprintf.h"
|
||||
#include "HW.h"
|
||||
#include "dol.h"
|
||||
#include "Config.h"
|
||||
|
||||
#define MAX_FB 3
|
||||
|
||||
typedef struct PatchInfo
|
||||
{
|
||||
u8 *Signature;
|
||||
u8 *Mask;
|
||||
u32 Length;
|
||||
u32 FunctionLength;
|
||||
u8 *Patch;
|
||||
u32 PatchLength;
|
||||
char *Name;
|
||||
} PatchInfo;
|
||||
|
||||
typedef struct FuncPattern
|
||||
{
|
||||
u32 Length;
|
||||
u32 Loads;
|
||||
u32 Stores;
|
||||
u32 FCalls;
|
||||
u32 Branch;
|
||||
u32 Moves;
|
||||
u8 *Patch;
|
||||
u32 PatchLength;
|
||||
char *Name;
|
||||
u32 Group;
|
||||
u32 Found;
|
||||
} FuncPattern;
|
||||
|
||||
typedef struct PatchCache
|
||||
{
|
||||
u32 Offset;
|
||||
u32 PatchID;
|
||||
|
||||
} PatchCache;
|
||||
|
||||
typedef struct _gx_rmodeobj {
|
||||
u32 viTVMode;
|
||||
u16 fbWidth;
|
||||
u16 efbHeight;
|
||||
u16 xfbHeight;
|
||||
u16 viXOrigin;
|
||||
u16 viYOrigin;
|
||||
u16 viWidth;
|
||||
u16 viHeight;
|
||||
u32 xfbMode;
|
||||
u8 field_rendering;
|
||||
u8 aa;
|
||||
u8 sample_pattern[12][2];
|
||||
u8 vfilter[7];
|
||||
} 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 GXEurgb60Hz480IntDf 1
|
||||
#define GXMpal480IntDf 2
|
||||
#define GXNtsc480IntDf 3
|
||||
#define GXNtsc480Int 4
|
||||
|
||||
void SMenuAddFramebuffer( void );
|
||||
void ScreenShot( void );
|
||||
void DoPatches( char *ptr, u32 size, u32 SectionOffset );
|
||||
void DoCardPatches( char *ptr, u32 size, u32 SectionOffset );
|
||||
void DoPatchesLoader( char *ptr, u32 size );
|
||||
|
||||
#endif
|
205
alloc.c
Normal file
205
alloc.c
Normal file
@ -0,0 +1,205 @@
|
||||
#include "alloc.h"
|
||||
#include "vsprintf.h"
|
||||
|
||||
u8 *RAM;//[_AHEAP_SIZE_TOTAL];
|
||||
HeapInfoEntry *HeapInfoEntries=(HeapInfoEntry *)NULL;
|
||||
|
||||
extern u32 DRAMRead( u32 a );
|
||||
extern void DRAMWrite( u32 a, u32 b );
|
||||
|
||||
void HeapInit( u8 *Offset )
|
||||
{
|
||||
//RAM = (u8*)0xFFFE4000;
|
||||
//RAM = (u8*)0x13600000;
|
||||
//RAM = (u8*)0x00600000;
|
||||
|
||||
RAM = Offset;
|
||||
|
||||
HeapInfoEntries = (HeapInfoEntry*)(RAM+_AHEAP_SIZE);
|
||||
memset32( HeapInfoEntries, 0, _AHEAP_INFO_SIZE );
|
||||
|
||||
while( HeapInfoEntries[0].Offset != 0 )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("Alloc:Failed to clear memory!:%08X", HeapInfoEntries[0].Offset );
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
// dbgprintf("Cleared 0x%04X bytes Space for %d allocs\n", _AHEAP_INFO_SIZE, _AHEAP_INFO_SIZE / 8 );
|
||||
|
||||
}
|
||||
void *malloc( u32 _size )
|
||||
{
|
||||
if( _size == 0 )
|
||||
return NULL;
|
||||
|
||||
if( _size > _AHEAP_SIZE )
|
||||
return NULL;
|
||||
|
||||
//align size to 32, easy cheat toallow all allocs to be aligned easily
|
||||
u32 size = (_size+0x1F) & (~0x1F);
|
||||
|
||||
//find a free entry to be used
|
||||
u32 entry = 0xdeadbeef;
|
||||
u32 i;
|
||||
|
||||
for( i=0; i < _AHEAP_INFO_SIZE / sizeof(HeapInfoEntry); ++i )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset == 0 )
|
||||
{
|
||||
entry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( entry == 0xdeadbeef )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("Alloc: run out of entries!\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
//dbgprintf("Alloc:Using entry:%d to alloc %u(%u) bytes...\n", entry, size, _size );
|
||||
|
||||
//Now we search a used entry
|
||||
u32 used_entry = 0xdeadbeef;
|
||||
|
||||
for( i=0; i < _AHEAP_INFO_SIZE / sizeof(HeapInfoEntry); ++i )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset == 0 )
|
||||
continue;
|
||||
|
||||
used_entry = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if( used_entry == 0xdeadbeef )
|
||||
{
|
||||
//dbgprintf("There are no other entries used atm\n");
|
||||
HeapInfoEntries[entry].Offset = RAM;
|
||||
HeapInfoEntries[entry].Size = size;
|
||||
//dbgprintf("alloc1: ptr:%p size:%08X Entry:%d\n", HeapInfoEntries[entry].Offset, HeapInfoEntries[entry].Size, entry );
|
||||
return HeapInfoEntries[entry].Offset;
|
||||
}
|
||||
|
||||
find_space:
|
||||
;
|
||||
//dbgprintf("[%02d]Offset:%08X Size:%08X\n", used_entry, HeapInfoEntries[used_entry].Offset, HeapInfoEntries[used_entry].Size );
|
||||
|
||||
//now we search for the next closest and the previous closest entry
|
||||
u32 next = 0xdeadbeef;
|
||||
u32 prev = 0xdeadbeef;
|
||||
|
||||
for( i=0; i < _AHEAP_INFO_SIZE / sizeof(HeapInfoEntry); ++i )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset == 0 )
|
||||
continue;
|
||||
if( used_entry == i )
|
||||
continue;
|
||||
|
||||
if( next == 0xdeadbeef )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset > HeapInfoEntries[used_entry].Offset )
|
||||
next = i;
|
||||
} else {
|
||||
if( HeapInfoEntries[i].Offset < HeapInfoEntries[next].Offset && HeapInfoEntries[i].Offset > HeapInfoEntries[used_entry].Offset )
|
||||
next = i;
|
||||
}
|
||||
|
||||
if( prev == 0xdeadbeef )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset < HeapInfoEntries[used_entry].Offset )
|
||||
prev = i;
|
||||
} else {
|
||||
if( HeapInfoEntries[i].Offset > HeapInfoEntries[prev].Offset && HeapInfoEntries[i].Offset < HeapInfoEntries[used_entry].Offset )
|
||||
prev = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( next == 0xdeadbeef )
|
||||
{
|
||||
//dbgprintf("This is the last entry\n");
|
||||
|
||||
//check if there is engough space left for our alloc
|
||||
|
||||
if( (u32)(HeapInfoEntries[used_entry].Offset-RAM) + HeapInfoEntries[used_entry].Size + size <= _AHEAP_SIZE )
|
||||
{
|
||||
HeapInfoEntries[entry].Offset = HeapInfoEntries[used_entry].Offset + HeapInfoEntries[used_entry].Size;
|
||||
HeapInfoEntries[entry].Size = size;
|
||||
//dbgprintf("alloc2: ptr:%p size:%08X Entry:%d\n", HeapInfoEntries[entry].Offset, HeapInfoEntries[entry].Size, entry );
|
||||
return HeapInfoEntries[entry].Offset;
|
||||
}
|
||||
;//dbgprintf("2Not enough space left only had:%d\n", HEAP_SIZE - ((u32)(HeapInfoEntries[used_entry].Offset-RAM) + HeapInfoEntries[used_entry].Size) );
|
||||
} else if( (u32)(HeapInfoEntries[used_entry].Offset) + HeapInfoEntries[used_entry].Size + size < (u32)(HeapInfoEntries[next].Offset) )
|
||||
{
|
||||
HeapInfoEntries[entry].Offset = HeapInfoEntries[used_entry].Offset + HeapInfoEntries[used_entry].Size;
|
||||
HeapInfoEntries[entry].Size = size;
|
||||
//dbgprintf("alloc4: ptr:%p size:%08X Entry:%d\n", HeapInfoEntries[entry].Offset, HeapInfoEntries[entry].Size, entry );
|
||||
return HeapInfoEntries[entry].Offset;
|
||||
} else {
|
||||
;//dbgprintf("4Not enough space left only had:%d %d:%d\n", (u32)( HeapInfoEntries[next].Offset - HeapInfoEntries[used_entry].Offset ) - HeapInfoEntries[used_entry].Size, next, used_entry );
|
||||
}
|
||||
|
||||
if( prev == 0xdeadbeef )
|
||||
{
|
||||
//dbgprintf("This is the first entry\n");
|
||||
if( (u32)(HeapInfoEntries[used_entry].Offset-RAM) >= size )
|
||||
{
|
||||
HeapInfoEntries[entry].Offset = HeapInfoEntries[used_entry].Offset - size;
|
||||
HeapInfoEntries[entry].Size = size;
|
||||
//dbgprintf("alloc3: ptr:%p size:%08X Entry:%d\n", HeapInfoEntries[entry].Offset, HeapInfoEntries[entry].Size, entry );
|
||||
return HeapInfoEntries[entry].Offset;
|
||||
}
|
||||
;//dbgprintf("3Not enough space left only had:%d\n", (u32)(HeapInfoEntries[used_entry].Offset-RAM) );
|
||||
} else if( (u32)(HeapInfoEntries[prev].Offset) + HeapInfoEntries[prev].Size + size < (u32)(HeapInfoEntries[used_entry].Offset) )
|
||||
{
|
||||
HeapInfoEntries[entry].Offset = HeapInfoEntries[prev].Offset + HeapInfoEntries[prev].Size;
|
||||
HeapInfoEntries[entry].Size = size;
|
||||
//dbgprintf("alloc5: ptr:%p size:%08X Entry:%d\n", HeapInfoEntries[entry].Offset, HeapInfoEntries[entry].Size, entry );
|
||||
return HeapInfoEntries[entry].Offset;
|
||||
} else {
|
||||
;//dbgprintf("5Not enough space left only had:%d\n", (u32)(HeapInfoEntries[used_entry].Offset-HeapInfoEntries[prev].Offset) - HeapInfoEntries[prev].Size );
|
||||
}
|
||||
|
||||
//if we land here we have to go to the next entry
|
||||
u32 temp = used_entry + 1;
|
||||
used_entry = 0xdeadbeef;
|
||||
|
||||
for( i=temp; i < _AHEAP_INFO_SIZE / sizeof(HeapInfoEntry); ++i )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset == 0 )
|
||||
continue;
|
||||
|
||||
used_entry = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if( used_entry != 0xdeadbeef )
|
||||
goto find_space;
|
||||
|
||||
dbgprintf("Alloc:failed to alloc %d bytes\n", size );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
void *malloca( u32 size, u32 align )
|
||||
{
|
||||
return malloc( size );
|
||||
}
|
||||
void free( void *ptr )
|
||||
{
|
||||
if( ptr == NULL )
|
||||
return;
|
||||
|
||||
u32 i;
|
||||
for( i=0; i < _AHEAP_INFO_SIZE / sizeof(HeapInfoEntry); ++i )
|
||||
{
|
||||
if( HeapInfoEntries[i].Offset == ptr )
|
||||
{
|
||||
//dbgprintf("free: ptr:%p size:%08X Entry:%d\n", HeapInfoEntries[i].Offset, HeapInfoEntries[i].Size, i );
|
||||
HeapInfoEntries[i].Offset = NULL;
|
||||
HeapInfoEntries[i].Size = 0;
|
||||
ptr = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
23
alloc.h
Normal file
23
alloc.h
Normal file
@ -0,0 +1,23 @@
|
||||
#include "utils.h"
|
||||
#include "memory.h"
|
||||
#include "HW.h"
|
||||
|
||||
#ifndef _ALLOC_
|
||||
#define _ALLOC_
|
||||
|
||||
#define _AHEAP_SIZE_TOTAL 0x3000
|
||||
#define _AHEAP_INFO_SIZE 0x0100
|
||||
#define _AHEAP_SIZE _AHEAP_SIZE_TOTAL-_AHEAP_INFO_SIZE
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *Offset;
|
||||
u32 Size;
|
||||
} HeapInfoEntry;
|
||||
|
||||
void HeapInit( u8 *Offset );
|
||||
void *malloc( u32 size );
|
||||
void *malloca( u32 size, u32 align );
|
||||
void free( void *ptr );
|
||||
|
||||
#endif
|
23
asm/CARDCheck.S
Normal file
23
asm/CARDCheck.S
Normal file
@ -0,0 +1,23 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDCheck:
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
li %r3, 0
|
||||
end:
|
||||
|
||||
lis %r4, 0xC000
|
||||
stw %r3, 0x2F94(%r4)
|
||||
|
||||
mtlr %r0
|
||||
blr
|
43
asm/CARDCheckAsync.S
Normal file
43
asm/CARDCheckAsync.S
Normal file
@ -0,0 +1,43 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 cb( chan, res )
|
||||
|
||||
CARDCheck:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq NoCardNoCB
|
||||
|
||||
mtctr %r4
|
||||
li %r4, -3
|
||||
bctrl
|
||||
|
||||
NoCardNoCB:
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq CardNoCB
|
||||
|
||||
mtctr %r4
|
||||
li %r4, 0
|
||||
bctrl
|
||||
|
||||
CardNoCB:
|
||||
li %r3, 0
|
||||
end:
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
||||
|
60
asm/CARDCheckEX.S
Normal file
60
asm/CARDCheckEX.S
Normal file
@ -0,0 +1,60 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 *xfer bytes used to repair the FS
|
||||
# r5 cb
|
||||
|
||||
CARDCheckEx:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq NoCardZeroPtr
|
||||
|
||||
li %r6, 0
|
||||
stw %r6, 0(%r4)
|
||||
|
||||
NoCardZeroPtr:
|
||||
cmpwi %r5, 0
|
||||
beq NoCardNoCB
|
||||
|
||||
mtctr %r5
|
||||
li %r4, -3
|
||||
bctrl
|
||||
|
||||
NoCardNoCB:
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq CardZeroPtr
|
||||
|
||||
li %r6, 0
|
||||
stw %r6, 0(%r4)
|
||||
|
||||
CardZeroPtr:
|
||||
cmpwi %r5, 0
|
||||
beq CardNoCB
|
||||
|
||||
mtctr %r5
|
||||
li %r4, 0
|
||||
bctrl
|
||||
|
||||
CardNoCB:
|
||||
li %r3, 0
|
||||
end:
|
||||
lis %r4, 0xC000
|
||||
stw %r3, 0x2F94(%r4)
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
47
asm/CARDClose.S
Normal file
47
asm/CARDClose.S
Normal file
@ -0,0 +1,47 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 FileInfo
|
||||
|
||||
CARDClose:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC100
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
lwz %r0, 0x04(%r3)
|
||||
stw %r0, 0x2F64(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
90
asm/CARDCreate.S
Normal file
90
asm/CARDCreate.S
Normal file
@ -0,0 +1,90 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 fileName
|
||||
# r5 size
|
||||
# r6 fileInfo
|
||||
# r7 cb
|
||||
|
||||
CARDCreate:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
li %r4, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x28(%sp)
|
||||
stmw %r27, 0x14(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r7
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC200
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
stw %r6, 0x2F6C(%r7)
|
||||
|
||||
#cache workaround for the filename
|
||||
li %r5, 8
|
||||
mtctr %r5
|
||||
lis %r5, 0xC000
|
||||
invalidloop:
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0x17E0(%r5)
|
||||
addi %r4, %r4, 4
|
||||
addi %r5, %r5, 4
|
||||
bdnz invalidloop
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r0, 0x2F90(%r7)
|
||||
stw %r0, 0x04(%r6)
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lis %r7, 0xC000
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lmw %r27, 0x14(%sp)
|
||||
lwz %r0, 0x2C(%sp)
|
||||
addi %sp, %sp, 0x28
|
||||
mtlr %r0
|
||||
blr
|
||||
|
80
asm/CARDDelete.S
Normal file
80
asm/CARDDelete.S
Normal file
@ -0,0 +1,80 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 fileName
|
||||
# r5 cb
|
||||
|
||||
CARDDelete:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r5
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC600
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
|
||||
#cache workaround for the filename
|
||||
li %r5, 8
|
||||
mtctr %r5
|
||||
lis %r5, 0xC000
|
||||
invalidloop:
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0x17E0(%r5)
|
||||
addi %r4, %r4, 4
|
||||
addi %r5, %r5, 4
|
||||
bdnz invalidloop
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lis %r7, 0xC000
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
||||
|
69
asm/CARDFastDelete.S
Normal file
69
asm/CARDFastDelete.S
Normal file
@ -0,0 +1,69 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileNo
|
||||
# r5 cb
|
||||
|
||||
CARDFastDelete:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r5
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xCA00
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lis %r7, 0xC000
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
||||
|
62
asm/CARDFastOpen.S
Normal file
62
asm/CARDFastOpen.S
Normal file
@ -0,0 +1,62 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileNo
|
||||
# r5 FileInfo
|
||||
|
||||
CARDFastOpen:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
bne NoCard
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC500
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r3, 0x2F90(%r7)
|
||||
stw %r3, 0x10(%r5)
|
||||
stw %r4, 0x04(%r5)
|
||||
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
b end
|
||||
|
||||
NoCard:
|
||||
li %r3, -3
|
||||
end:
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
32
asm/CARDFreeBlocks.S
Normal file
32
asm/CARDFreeBlocks.S
Normal file
@ -0,0 +1,32 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 byteNotUsed
|
||||
# r5 filesNotUsed
|
||||
|
||||
CARDFreeBlocks:
|
||||
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
lis %r3, 0x7F
|
||||
addi %r3, %r3, 0x6000
|
||||
stw %r3, 0(%r4)
|
||||
|
||||
li %r3, 16
|
||||
stw %r3, 0(%r5)
|
||||
|
||||
li %r3, 0
|
||||
|
||||
end:
|
||||
|
||||
mtlr %r0
|
||||
blr
|
30
asm/CARDGetEncoding.S
Normal file
30
asm/CARDGetEncoding.S
Normal file
@ -0,0 +1,30 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 endcoding(u16)
|
||||
|
||||
CARDGetEncoding:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#0 is USA/EUR, 1 is JAP
|
||||
li %r0, 0
|
||||
sth %r0, 0(%r4)
|
||||
|
||||
end:
|
||||
li %r3, 0
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
30
asm/CARDGetMemSize.S
Normal file
30
asm/CARDGetMemSize.S
Normal file
@ -0,0 +1,30 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 size(u16)
|
||||
|
||||
CARDGetMemSize:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#possible sizes 4,8,16,32,64,128
|
||||
li %r0, 8
|
||||
sth %r0, 0(%r4)
|
||||
|
||||
end:
|
||||
li %r3, 0
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
19
asm/CARDGetResultCode.S
Normal file
19
asm/CARDGetResultCode.S
Normal file
@ -0,0 +1,19 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDGetResultCode:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
lis %r3, 0xC000
|
||||
lwz %r3, 0x2F94(%r3)
|
||||
end:
|
||||
|
||||
blr
|
29
asm/CARDGetSerialNo.S
Normal file
29
asm/CARDGetSerialNo.S
Normal file
@ -0,0 +1,29 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 serialNo
|
||||
|
||||
CARDGetSerialNo:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
|
||||
lis %r3, 0xc7bd
|
||||
subi %r3, %r3, 0x26C
|
||||
stw %r3, 0x00(%r4)
|
||||
|
||||
lis %r3, 0xf47f
|
||||
subi %r3, %r3, 0x3924
|
||||
stw %r3, 0x04(%r4)
|
||||
|
||||
li %r3, 0
|
||||
|
||||
mtlr %r0
|
||||
blr
|
74
asm/CARDGetStats.S
Normal file
74
asm/CARDGetStats.S
Normal file
@ -0,0 +1,74 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileNo
|
||||
# r5 Stat
|
||||
# r6 cb
|
||||
|
||||
CARDGetStats:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, 0
|
||||
li %r4, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r6
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC300
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
#cache workaround
|
||||
li %r6, 27
|
||||
mtctr %r6
|
||||
lis %r6, 0xC000
|
||||
addi %r6, %r6, 0x1780
|
||||
invalidloop:
|
||||
lwz %r0, 0(%r6)
|
||||
stw %r0, 0(%r5)
|
||||
addi %r5, %r5, 4
|
||||
addi %r6, %r6, 4
|
||||
bdnz invalidloop
|
||||
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
17
asm/CARDGetXferredBytes.S
Normal file
17
asm/CARDGetXferredBytes.S
Normal file
@ -0,0 +1,17 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDGetEncoding:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
lis %r3, 0xC000
|
||||
lwz %r3, 0x2FA0(%r3)
|
||||
|
||||
blr
|
26
asm/CARDMount.S
Normal file
26
asm/CARDMount.S
Normal file
@ -0,0 +1,26 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 workarea
|
||||
# r5 detachCallback
|
||||
|
||||
CARDMount:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
li %r3, 0
|
||||
end:
|
||||
|
||||
lwz %r0, 4(%sp)
|
||||
mtlr %r0
|
||||
blr
|
42
asm/CARDMountAsync.S
Normal file
42
asm/CARDMountAsync.S
Normal file
@ -0,0 +1,42 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 workarea
|
||||
# r5 detachCallback
|
||||
# r6 attachCallback
|
||||
|
||||
CARDMountAsync:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, -3
|
||||
lis %r7, 0xC000
|
||||
stw %r3, 0x2F94(%r7)
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
|
||||
cmpwi %r6, 0
|
||||
beq end
|
||||
|
||||
mtctr %r6
|
||||
bctrl
|
||||
|
||||
end:
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
lis %r7, 0xC000
|
||||
stw %r3, 0x2F94(%r7)
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
71
asm/CARDOpen.S
Normal file
71
asm/CARDOpen.S
Normal file
@ -0,0 +1,71 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 FileName
|
||||
# r5 FileInfo
|
||||
|
||||
CARDOpen:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
cmpwi %r3, 0
|
||||
bne NoCard
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
lis %r7, 0xC000
|
||||
#cmd is the same as the offset, one opcode saved!
|
||||
stw %r7, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
#cache workaround for the filename
|
||||
li %r3, 8
|
||||
mtctr %r3
|
||||
lis %r3, 0xC000
|
||||
invalidloop:
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0x17E0(%r3)
|
||||
addi %r4, %r4, 4
|
||||
addi %r3, %r3, 4
|
||||
bdnz invalidloop
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
lwz %r0, 0x2F90(%r7)
|
||||
stw %r0, 0x04(%r5)
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
b end
|
||||
|
||||
NoCard:
|
||||
li %r3, -3
|
||||
end:
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
21
asm/CARDProbe.S
Normal file
21
asm/CARDProbe.S
Normal file
@ -0,0 +1,21 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
|
||||
CARDProbe:
|
||||
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, 0
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
li %r3, 1
|
||||
end:
|
||||
|
||||
mtlr %r0
|
||||
blr
|
41
asm/CARDProbeEX.S
Normal file
41
asm/CARDProbeEX.S
Normal file
@ -0,0 +1,41 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 Channel
|
||||
# r4 MemSize (can be zero ptr)
|
||||
# r5 SecSize (can be zero ptr)
|
||||
|
||||
CARDProbeEX:
|
||||
|
||||
|
||||
mflr %r0
|
||||
cmpwi %r3, 0
|
||||
beq CARDPresent
|
||||
|
||||
li %r3, -3
|
||||
b end
|
||||
|
||||
CARDPresent:
|
||||
|
||||
cmpwi %r4, 0
|
||||
beq ZeroMemPtr
|
||||
|
||||
li %r3, 8
|
||||
stw %r3, 0(%r4)
|
||||
|
||||
ZeroMemPtr:
|
||||
|
||||
cmpwi %r5, 0
|
||||
beq ZeroSecPtr
|
||||
|
||||
li %r3, 0x2000
|
||||
stw %r3, 0(%r5)
|
||||
|
||||
ZeroSecPtr:
|
||||
|
||||
li %r3, 0
|
||||
|
||||
end:
|
||||
|
||||
mtlr %r0
|
||||
blr
|
82
asm/CARDRead.S
Normal file
82
asm/CARDRead.S
Normal file
@ -0,0 +1,82 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 file *
|
||||
# r4 buffer
|
||||
# r5 length
|
||||
# r6 offset
|
||||
# r7 cb
|
||||
|
||||
CardRead:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x28(%sp)
|
||||
stmw %r27, 0x14(%sp)
|
||||
|
||||
#Update fileinfo
|
||||
stw %r5, 0x0C(%r3)
|
||||
stw %r6, 0x08(%r3)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r7
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
|
||||
srwi %r7, %r5, 5
|
||||
mtctr %r7
|
||||
mr %r7, %r4
|
||||
invalidloop:
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
bdnz invalidloop
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC900
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
stw %r6, 0x2F6C(%r7)
|
||||
|
||||
lwz %r0, 0x04(%r3)
|
||||
stw %r0, 0x2F70(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
li %r3, 0
|
||||
mr %r4, %r3
|
||||
|
||||
lmw %r27, 0x14(%sp)
|
||||
lwz %r0, 0x2C(%sp)
|
||||
addi %sp, %sp, 0x28
|
||||
mtlr %r0
|
||||
blr
|
87
asm/CARDRename.S
Normal file
87
asm/CARDRename.S
Normal file
@ -0,0 +1,87 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 old
|
||||
# r5 new
|
||||
# r6 cb
|
||||
|
||||
CARDRename:
|
||||
|
||||
mflr %r8
|
||||
|
||||
cmpwi %r3, 0
|
||||
bne NoCard
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r6
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
dcbi %r0, %r7
|
||||
|
||||
|
||||
#cache workaround for the filename
|
||||
li %r3, 8
|
||||
mtctr %r3
|
||||
lis %r3, 0xC000
|
||||
invalidloopA:
|
||||
lwz %r0, 0(%r4)
|
||||
stw %r0, 0x17C0(%r3)
|
||||
addi %r4, %r4, 4
|
||||
addi %r3, %r3, 4
|
||||
bdnz invalidloopA
|
||||
|
||||
#cache workaround for the filename
|
||||
li %r3, 8
|
||||
mtctr %r3
|
||||
lis %r3, 0xC000
|
||||
invalidloopB:
|
||||
lwz %r0, 0(%r5)
|
||||
stw %r0, 0x17E0(%r3)
|
||||
addi %r5, %r5, 4
|
||||
addi %r3, %r3, 4
|
||||
bdnz invalidloopB
|
||||
|
||||
lis %r7, 0xC000
|
||||
|
||||
lis %r0, 0xCB00
|
||||
stw %r0, 0x2F60(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
li %r3, 0
|
||||
lwz %r4, 0x2F94(%r7)
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
lwz %r3, 0x2F94(%r7)
|
||||
b end
|
||||
|
||||
NoCard:
|
||||
li %r3, -3
|
||||
end:
|
||||
mr %r4, %r3
|
||||
|
||||
mtlr %r8
|
||||
blr
|
83
asm/CARDSetStats.S
Normal file
83
asm/CARDSetStats.S
Normal file
@ -0,0 +1,83 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 chan
|
||||
# r4 fileNo
|
||||
# r5 stat
|
||||
# r6 cb
|
||||
|
||||
CARDSetStat:
|
||||
|
||||
cmpwi %r3, 0
|
||||
beq DoCode
|
||||
li %r3, 0
|
||||
li %r4, -3
|
||||
blr
|
||||
|
||||
DoCode:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x10(%sp)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r6
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbst %r0, %r7
|
||||
|
||||
#stat
|
||||
mr %r7, %r5
|
||||
#0x00
|
||||
dcbst %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
#0x20
|
||||
dcbst %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
#0x40
|
||||
dcbst %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
#0x60
|
||||
dcbst %r0, %r7
|
||||
sc
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC400
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtctr %r12
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
bctrl
|
||||
|
||||
skip_cb:
|
||||
li %r3, 0
|
||||
mr %r4, %r3
|
||||
|
||||
lwz %r0, 0x14(%sp)
|
||||
addi %sp, %sp, 0x10
|
||||
mtlr %r0
|
||||
blr
|
82
asm/CARDWrite.S
Normal file
82
asm/CARDWrite.S
Normal file
@ -0,0 +1,82 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 file *
|
||||
# r4 buffer
|
||||
# r5 length
|
||||
# r6 offset
|
||||
# r7 cb
|
||||
|
||||
CardWrite:
|
||||
|
||||
mflr %r0
|
||||
stw %r0, 4(%sp)
|
||||
stwu %sp, -0x28(%sp)
|
||||
stmw %r27, 0x14(%sp)
|
||||
|
||||
#Update fileinfo
|
||||
stw %r5, 0x0C(%r3)
|
||||
stw %r6, 0x08(%r3)
|
||||
|
||||
#send cmd to DM
|
||||
|
||||
mr %r12, %r7
|
||||
|
||||
li %r0, 0
|
||||
lis %r7, 0xC000
|
||||
addi %r7, %r7, 0x2F60
|
||||
#IPC area
|
||||
dcbi %r0, %r7
|
||||
|
||||
srwi %r7, %r5, 5
|
||||
mtctr %r7
|
||||
mr %r7, %r4
|
||||
invalidloop:
|
||||
dcbst %r0, %r7
|
||||
addi %r7, %r7, 0x20
|
||||
bdnz invalidloop
|
||||
sc
|
||||
|
||||
lis %r7, 0xC000
|
||||
lis %r0, 0xC800
|
||||
|
||||
stw %r0, 0x2F60(%r7)
|
||||
|
||||
stw %r4, 0x2F64(%r7)
|
||||
stw %r5, 0x2F68(%r7)
|
||||
|
||||
stw %r6, 0x2F6C(%r7)
|
||||
|
||||
lwz %r0, 0x04(%r3)
|
||||
stw %r0, 0x2F70(%r7)
|
||||
|
||||
li %r0, 3
|
||||
stw %r0, 0x2F78(%r7)
|
||||
|
||||
ready_loop:
|
||||
lwz %r0, 0x2F78(%r7)
|
||||
cmpwi %r0, 3
|
||||
beq ready_loop
|
||||
|
||||
wait_loop:
|
||||
lwz %r0, 0x2F9C(%r7)
|
||||
andi. %r0, %r0, 0x14
|
||||
cmpwi %r0, 0
|
||||
beq wait_loop
|
||||
|
||||
cmpwi %r12, 0
|
||||
beq skip_cb
|
||||
mtlr %r12
|
||||
li %r3, 0
|
||||
li %r4, 0
|
||||
blrl
|
||||
|
||||
skip_cb:
|
||||
li %r3, 0
|
||||
mr %r4, %r3
|
||||
|
||||
lmw %r27, 0x14(%sp)
|
||||
lwz %r0, 0x2C(%sp)
|
||||
addi %sp, %sp, 0x28
|
||||
mtlr %r0
|
||||
blr
|
60
asm/DVDInquiryAsync.S
Normal file
60
asm/DVDInquiryAsync.S
Normal file
@ -0,0 +1,60 @@
|
||||
#include <asm.h>
|
||||
|
||||
# issue read command
|
||||
#
|
||||
# r3 dvdstruct
|
||||
# r4 dst
|
||||
# r5 cb
|
||||
|
||||
DVDInquiryAsync:
|
||||
|
||||
stwu %sp, -0x10(%sp)
|
||||
mflr %r0
|
||||
stw %r0, 8(%sp)
|
||||
|
||||
#update dvdstruct
|
||||
|
||||
li %r0, 0
|
||||
stw %r0, 0x00(%r3)
|
||||
stw %r0, 0x04(%r3)
|
||||
stw %r0, 0x0C(%r3)
|
||||
#offset
|
||||
stw %r0, 0x10(%r3)
|
||||
|
||||
li %r0, 2
|
||||
stw %r0, 0x08(%r3)
|
||||
|
||||
li %r0, 0x20
|
||||
#TransferSize
|
||||
stw %r0, 0x1C(%r3)
|
||||
stw %r0, 0x20(%r3)
|
||||
#size
|
||||
stw %r0, 0x14(%r3)
|
||||
|
||||
#ptr
|
||||
stw %r4, 0x18(%r3)
|
||||
#cb
|
||||
stw %r5, 0x28(%r3)
|
||||
|
||||
#Inquiry reply
|
||||
|
||||
li %r0, 0
|
||||
dcbi %r0, %r4
|
||||
|
||||
li %r0, 0x0000
|
||||
sth %r0, 0x02(%r4)
|
||||
|
||||
cmpwi %r5, 0
|
||||
beq skip_cb
|
||||
mtctr %r5
|
||||
mr %r4, %r3
|
||||
li %r3, 0x20
|
||||
bctrl
|
||||
|
||||
skip_cb:
|
||||
li %r3, 1
|
||||
|
||||
lwz %r0, 8(%sp)
|
||||
mtlr %r0
|
||||
addi %sp, %sp, 0x10
|
||||
blr
|
47
asm/DVDSeekAbsAsyncPrio.S
Normal file
47
asm/DVDSeekAbsAsyncPrio.S
Normal file
@ -0,0 +1,47 @@
|
||||
#include <asm.h>
|
||||
|
||||
# issue read command
|
||||
#
|
||||
# r3 dvdstruct
|
||||
# r4 off
|
||||
# r5 cb
|
||||
# r6 prio
|
||||
|
||||
DVDSeekAbsAsyncPrio:
|
||||
|
||||
stwu %sp, -0x10(%sp)
|
||||
mflr %r0
|
||||
stw %r0, 8(%sp)
|
||||
|
||||
#update dvdstruct
|
||||
|
||||
li %r0, 0
|
||||
stw %r0, 0x00(%r3)
|
||||
stw %r0, 0x04(%r3)
|
||||
stw %r0, 0x1C(%r3)
|
||||
li %r0, 2
|
||||
stw %r0, 0x08(%r3)
|
||||
|
||||
li %r0, 0
|
||||
stw %r0, 0x0C(%r3)
|
||||
|
||||
#off
|
||||
stw %r4, 0x10(%r3)
|
||||
#cb
|
||||
stw %r5, 0x28(%r3)
|
||||
|
||||
cmpwi %r5, 0
|
||||
beq skip_cb
|
||||
mtctr %r5
|
||||
mr %r4, %r3
|
||||
li %r3, 0
|
||||
bctrl
|
||||
|
||||
skip_cb:
|
||||
|
||||
li %r3, 1
|
||||
|
||||
lwz %r0, 8(%sp)
|
||||
mtlr %r0
|
||||
addi %sp, %sp, 0x10
|
||||
blr
|
9
asm/__CARDSync.S
Normal file
9
asm/__CARDSync.S
Normal file
@ -0,0 +1,9 @@
|
||||
#include <asm.h>
|
||||
|
||||
#
|
||||
# r3 *Async result
|
||||
|
||||
__CARDSync:
|
||||
|
||||
mr %r3, %r4
|
||||
blr
|
4
asm/make.cmd
Normal file
4
asm/make.cmd
Normal file
@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
for /R %%i IN (*.S) DO %devkitpro:~1,1%:\%devkitpro:~3%\devkitPPC\bin\powerpc-eabi-as.exe %%i -o %%~ni.elf
|
||||
for /R %%i IN (*.S) DO %devkitpro:~1,1%:\%devkitpro:~3%\devkitPPC\bin\powerpc-eabi-strip.exe -s %%~ni.elf -O binary -o %%~ni.bin
|
||||
for /R %%i in (*.bin) DO "..\tools\bin2h\bin2h.exe" %%~ni.bin
|
18
asm/padipc.S
Normal file
18
asm/padipc.S
Normal file
@ -0,0 +1,18 @@
|
||||
#include <asm.h>
|
||||
|
||||
|
||||
PADRead:
|
||||
|
||||
lis %r4, 0xCC00
|
||||
|
||||
lwz %r5, 0x6428(%r4)
|
||||
lwz %r0, 0x642C(%r4)
|
||||
|
||||
lwz %r0, 0x6404(%r4)
|
||||
lwz %r4, 0x6408(%r4)
|
||||
|
||||
lis %r4, 0xC000
|
||||
stw %r0, 0x12FC(%r4)
|
||||
stw %r5, 0x12F8(%r4)
|
||||
|
||||
blr
|
32
bsdtypes.h
Normal file
32
bsdtypes.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __BSDTYPES_H__
|
||||
#define __BSDTYPES_H__
|
||||
|
||||
#include "global.h"
|
||||
#include "errno.h"
|
||||
|
||||
typedef u32 u_int;
|
||||
//typedef u32 u_int32_t;
|
||||
typedef u16 u_int16_t;
|
||||
typedef u8 u_int8_t;
|
||||
typedef u8 u_char;
|
||||
|
||||
typedef u32 bus_space_tag_t;
|
||||
typedef u32 bus_space_handle_t;
|
||||
|
||||
struct device {
|
||||
char dv_xname[255];
|
||||
void *dummy;
|
||||
};
|
||||
|
||||
#define MIN(a, b) (((a)>(b))?(b):(a))
|
||||
|
||||
#define wakeup(...)
|
||||
|
||||
#define bzero(mem, size) memset8(mem, 0, size)
|
||||
|
||||
#define ISSET(var, mask) (((var) & (mask)) ? 1 : 0)
|
||||
#define SET(var, mask) ((var) |= (mask))
|
||||
|
||||
#endif
|
||||
|
||||
|
378
dip.c
Normal file
378
dip.c
Normal file
@ -0,0 +1,378 @@
|
||||
#include "dip.h"
|
||||
|
||||
u32 StreamBufferSize= 54*1024;
|
||||
u32 Streaming = 0;
|
||||
u32 StreamOffset = 0;
|
||||
u32 StreamDiscOffset= 0;
|
||||
s32 StreamSize = 0;
|
||||
u32 StreamRAMOffset = 0;
|
||||
u32 StreamTimer = 0;
|
||||
u32 StreamStopEnd = 0;
|
||||
u32 GameRun = 0;
|
||||
u32 DOLMinOff = 0;
|
||||
u32 DOLMaxOff = 0;
|
||||
u32 DOLSize = 0;
|
||||
u32 DOLOffset = 0;
|
||||
s32 ELFNumberOfSections = 0;
|
||||
u32 FSTMode = 0;
|
||||
u32 DiscChangeIRQ = 0;
|
||||
|
||||
extern DML_CFG *DMLCfg;
|
||||
|
||||
FIL GameFile;
|
||||
u32 read;
|
||||
u32 DiscRead=0;
|
||||
|
||||
char *getfilenamebyoffset(u32 offset)
|
||||
{
|
||||
u32 fst_offset = read32(0x38) & ~0x80000000;
|
||||
|
||||
u32 i;
|
||||
for (i = fst_offset + 12; i < 0x01800000; i+=12)
|
||||
{
|
||||
if (read8(i) == 0 && offset >= read32(i + 4) && offset < read32(i + 4) + read32(i + 8))
|
||||
{
|
||||
return (char *)(fst_offset + read32(fst_offset+8)*12 + (read32(i) & 0x00ffffff));
|
||||
}
|
||||
}
|
||||
return (char*)NULL;
|
||||
}
|
||||
|
||||
|
||||
void DIInit( void )
|
||||
{
|
||||
memset32( (void*)DI_BASE, 0xdeadbeef, 0x30 );
|
||||
memset32( (void*)(DI_SHADOW), 0, 0x30 );
|
||||
|
||||
write32( DI_SCONFIG, 0xFF );
|
||||
write32( DI_SCOVER, 0 );
|
||||
|
||||
write32( HW_TIMER, 0 );
|
||||
}
|
||||
u32 DIUpdateRegisters( void )
|
||||
{
|
||||
u32 read,i,j;
|
||||
static u32 PatchState = 0;
|
||||
static u32 DOLReadSize = 0;
|
||||
static u32 PSOHack = 0;
|
||||
|
||||
if( read32(DI_CONTROL) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SCONTROL, read32(DI_CONTROL) & 3 );
|
||||
|
||||
clear32( DI_SSTATUS, 0x14 );
|
||||
|
||||
write32( DI_CONTROL, 0xdeadbeef );
|
||||
|
||||
if( read32(DI_SCONTROL) & 1 )
|
||||
{
|
||||
if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) )
|
||||
set32( HW_GPIO_OUT, 1<<5 );
|
||||
|
||||
if( read32(DI_CMD_0) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SCMD_0, read32(DI_CMD_0) );
|
||||
write32( DI_CMD_0, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(DI_CMD_1) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SCMD_1, read32(DI_CMD_1) );
|
||||
write32( DI_CMD_1, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(DI_CMD_2) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SCMD_2, read32(DI_CMD_2) );
|
||||
write32( DI_CMD_2, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(DI_DMA_ADR) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SDMA_ADR, read32(DI_DMA_ADR) );
|
||||
write32( DI_DMA_ADR, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(DI_DMA_LEN) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SDMA_LEN, read32(DI_DMA_LEN) );
|
||||
write32( DI_DMA_LEN, 0xdeadbeef );
|
||||
}
|
||||
|
||||
if( read32(DI_IMM) != 0xdeadbeef )
|
||||
{
|
||||
write32( DI_SIMM, read32(DI_IMM) );
|
||||
write32( DI_IMM, 0xdeadbeef );
|
||||
}
|
||||
|
||||
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");
|
||||
case 0xA8:
|
||||
{
|
||||
u32 Buffer = P2C(read32(DI_SDMA_ADR));
|
||||
u32 Length = read32(DI_SCMD_2);
|
||||
u32 Offset = read32(DI_SCMD_1) << 2;
|
||||
|
||||
// dbgprintf("DIP:DVDRead%02X( 0x%08x, 0x%08x, 0x%08x )\n", read32(DI_SCMD_0) >> 24, Offset, Length, Buffer|0x80000000 );
|
||||
|
||||
// udelay(250);
|
||||
|
||||
if( FSTMode )
|
||||
{
|
||||
FSTRead( (char*)Buffer, Length, Offset );
|
||||
|
||||
} else {
|
||||
|
||||
if( GameFile.fptr != Offset )
|
||||
if( f_lseek( &GameFile, Offset ) != FR_OK )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("DIP:Failed to seek to 0x%08x\n", Offset );
|
||||
while(1);
|
||||
}
|
||||
if( f_read( &GameFile, (char*)Buffer, Length, &read ) != FR_OK )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("DIP:Failed to read from 0x%08x to 0x%08X\n", Offset, Buffer );
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
//if( ((read+31)&(~31)) != Length )
|
||||
//{
|
||||
// dbgprintf("DIP:DVDLowRead Offset:%08X Size:%08d Dst:%08X\n", Offset, Length, Buffer );
|
||||
// dbgprintf("DIP:Failed to read %d bytes, only got %d\n", Length, read );
|
||||
// break;
|
||||
//}
|
||||
|
||||
if( (u32)Buffer == 0x01300000 )
|
||||
{
|
||||
DoPatches( (char*)(0x01300000), Length, 0x80000000 );
|
||||
}
|
||||
|
||||
// PSO 1&2
|
||||
if( (read32(0) >> 8) == 0x47504F )
|
||||
{
|
||||
switch( Offset )
|
||||
{
|
||||
case 0x56B8E7E0: // AppSwitcher [EUR]
|
||||
case 0x56C49600: // [USA] v1.1
|
||||
case 0x56C4C980: // [USA] v1.0
|
||||
{
|
||||
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] v1.1
|
||||
case 0x56753EC0: // [USA] v1.0
|
||||
{
|
||||
PSOHack = 1;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if( PatchState == 0 )
|
||||
{
|
||||
if( Length == 0x100 || PSOHack )
|
||||
{
|
||||
if( read32( (u32)Buffer ) == 0x100 )
|
||||
{
|
||||
//quickly calc the size
|
||||
DOLSize = sizeof(dolhdr);
|
||||
dolhdr *dol = (dolhdr*)Buffer;
|
||||
|
||||
for( i=0; i < 7; ++i )
|
||||
DOLSize += dol->sizeText[i];
|
||||
for( i=0; i < 11; ++i )
|
||||
DOLSize += dol->sizeData[i];
|
||||
|
||||
DOLReadSize = Length;
|
||||
|
||||
DOLMinOff=0x81800000;
|
||||
DOLMaxOff=0;
|
||||
|
||||
for( i=0; i < 7; ++i )
|
||||
{
|
||||
if( dol->addressText[i] == 0 )
|
||||
continue;
|
||||
|
||||
if( DOLMinOff > dol->addressText[i])
|
||||
DOLMinOff = dol->addressText[i];
|
||||
|
||||
if( DOLMaxOff < dol->addressText[i] + dol->sizeText[i] )
|
||||
DOLMaxOff = dol->addressText[i] + dol->sizeText[i];
|
||||
}
|
||||
|
||||
for( i=0; i < 11; ++i )
|
||||
{
|
||||
if( dol->addressData[i] == 0 )
|
||||
continue;
|
||||
|
||||
if( DOLMinOff > dol->addressData[i])
|
||||
DOLMinOff = dol->addressData[i];
|
||||
|
||||
if( DOLMaxOff < dol->addressData[i] + dol->sizeData[i] )
|
||||
DOLMaxOff = dol->addressData[i] + dol->sizeData[i];
|
||||
}
|
||||
|
||||
DOLMinOff -= 0x80000000;
|
||||
DOLMaxOff -= 0x80000000;
|
||||
|
||||
if( PSOHack )
|
||||
{
|
||||
DOLMinOff = Buffer;
|
||||
DOLMaxOff = Buffer + DOLSize;
|
||||
}
|
||||
|
||||
dbgprintf("DIP:DOLSize:%d DOLMinOff:0x%08X DOLMaxOff:0x%08X\n", DOLSize, DOLMinOff, DOLMaxOff );
|
||||
|
||||
PatchState = 1;
|
||||
}
|
||||
|
||||
PSOHack = 0;
|
||||
|
||||
} else if( read32(Buffer) == 0x7F454C46 )
|
||||
{
|
||||
dbgprintf("DIP:Game is loading an ELF 0x%08x\n", Offset );
|
||||
|
||||
DOLOffset = Offset;
|
||||
DOLSize = 0;
|
||||
|
||||
if( Length > 0x1000 )
|
||||
{
|
||||
DOLReadSize = Length;
|
||||
DoPatches( (char*)(Buffer), Length, 0x80000000 );
|
||||
} else
|
||||
DOLReadSize = 0;
|
||||
|
||||
Elf32_Ehdr *ehdr = (Elf32_Ehdr*)Buffer;
|
||||
dbgprintf("DIP:ELF Programheader Entries:%u\n", ehdr->e_phnum );
|
||||
|
||||
for( i=0; i < ehdr->e_phnum; ++i )
|
||||
{
|
||||
Elf32_Phdr phdr;
|
||||
|
||||
if( FSTMode )
|
||||
{
|
||||
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 == 1 )
|
||||
{
|
||||
DOLReadSize += Length;
|
||||
//dbgprintf("DIP:DOL ize:%d DOL read:%d\n", DOLSize, DOLReadSize );
|
||||
if( DOLReadSize >= DOLSize )
|
||||
{
|
||||
DoPatches( (char*)(DOLMinOff), DOLMaxOff-DOLMinOff, 0x80000000 );
|
||||
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 );
|
||||
|
||||
while( read32(DI_SCONTROL) & 1 )
|
||||
clear32( DI_SCONTROL, 1 );
|
||||
|
||||
set32( DI_SSTATUS, 0x3A );
|
||||
|
||||
if( (read32(DI_SCMD_0) >> 24) == 0xA7 )
|
||||
{
|
||||
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;
|
||||
default:
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("DIP:Unknown CMD:%08X %08X %08X %08X %08X %08X\n", read32(DI_SCMD_0), read32(DI_SCMD_1), read32(DI_SCMD_2), read32(DI_SIMM), read32(DI_SDMA_ADR), read32(DI_SDMA_LEN) );
|
||||
while(1);
|
||||
} break;
|
||||
}
|
||||
|
||||
if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) )
|
||||
clear32( HW_GPIO_OUT, 1<<5 );
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
;//dbgprintf("DIP:DI_CONTROL:%08X:%08X\n", read32(DI_CONTROL), read32(DI_CONTROL) );
|
||||
}
|
||||
}
|
||||
|
||||
if( (u64)read32(HW_TIMER) >= 25 * 243000000LL / 128 )
|
||||
{
|
||||
USBStorage_Read_Sectors( (read32(HW_TIMER) << 3) & 0x000FFFFF, 1, (void*)0x1000 );
|
||||
|
||||
write32( HW_TIMER, 0 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
140
dip.h
Normal file
140
dip.h
Normal file
@ -0,0 +1,140 @@
|
||||
#ifndef _DIP_
|
||||
#define _DIP_
|
||||
|
||||
#include "global.h"
|
||||
#include "string.h"
|
||||
#include "alloc.h"
|
||||
#include "ff.h"
|
||||
#include "vsprintf.h"
|
||||
#include "HW.h"
|
||||
#include "dol.h"
|
||||
#include "Patches.h"
|
||||
#include "vsprintf.h"
|
||||
#include "Config.h"
|
||||
#include "DVD.h"
|
||||
#include "elf.h"
|
||||
#include "usbstorage.h"
|
||||
|
||||
enum opcodes
|
||||
{
|
||||
DVD_IDENTIFY = 0x12,
|
||||
DVD_READ_DISCID = 0x70,
|
||||
DVD_LOW_READ = 0x71,
|
||||
DVD_WAITFORCOVERCLOSE = 0x79,
|
||||
DVD_READ_PHYSICAL = 0x80,
|
||||
DVD_READ_COPYRIGHT = 0x81,
|
||||
DVD_READ_DISCKEY = 0x82,
|
||||
DVD_GETCOVER = 0x88,
|
||||
DVD_RESET = 0x8A,
|
||||
DVD_OPEN_PARTITION = 0x8B,
|
||||
DVD_CLOSE_PARTITION = 0x8C,
|
||||
DVD_READ_UNENCRYPTED = 0x8D,
|
||||
DVD_REPORTKEY = 0xA4,
|
||||
DVD_LOW_SEEK = 0xAB,
|
||||
DVD_READ = 0xD0,
|
||||
DVD_READ_CONFIG = 0xD1,
|
||||
DVD_READ_BCA = 0xDA,
|
||||
DVD_GET_ERROR = 0xE0,
|
||||
DVD_SET_MOTOR = 0xE3,
|
||||
|
||||
DVD_SELECT_GAME = 0x23,
|
||||
DVD_GET_GAMECOUNT = 0x24,
|
||||
DVD_EJECT_DISC = 0x27,
|
||||
DVD_INSERT_DISC = 0x28,
|
||||
DVD_READ_GAMEINFO = 0x30,
|
||||
};
|
||||
|
||||
enum GameRegion
|
||||
{
|
||||
JAP=0,
|
||||
USA,
|
||||
EUR,
|
||||
KOR,
|
||||
ASN,
|
||||
LTN,
|
||||
};
|
||||
|
||||
|
||||
#define DI_BASE 0x00002F00
|
||||
|
||||
#define DI_STATUS (DI_BASE+0x00)
|
||||
#define DI_COVER (DI_BASE+0x04)
|
||||
#define DI_CMD_0 (DI_BASE+0x08)
|
||||
#define DI_CMD_1 (DI_BASE+0x0C)
|
||||
#define DI_CMD_2 (DI_BASE+0x10)
|
||||
#define DI_DMA_ADR (DI_BASE+0x14)
|
||||
#define DI_DMA_LEN (DI_BASE+0x18)
|
||||
#define DI_CONTROL (DI_BASE+0x1C)
|
||||
#define DI_IMM (DI_BASE+0x20)
|
||||
#define DI_CONFIG (DI_BASE+0x24)
|
||||
|
||||
#define DI_SHADOW (DI_BASE + 0x30)
|
||||
|
||||
#define DI_SSTATUS (DI_SHADOW+0x00)
|
||||
#define DI_SCOVER (DI_SHADOW+0x04)
|
||||
#define DI_SCMD_0 (DI_SHADOW+0x08)
|
||||
#define DI_SCMD_1 (DI_SHADOW+0x0C)
|
||||
#define DI_SCMD_2 (DI_SHADOW+0x10)
|
||||
#define DI_SDMA_ADR (DI_SHADOW+0x14)
|
||||
#define DI_SDMA_LEN (DI_SHADOW+0x18)
|
||||
#define DI_SCONTROL (DI_SHADOW+0x1C)
|
||||
#define DI_SIMM (DI_SHADOW+0x20)
|
||||
#define DI_SCONFIG (DI_SHADOW+0x24)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 Type :8;
|
||||
u32 NameOffset :24;
|
||||
};
|
||||
u32 TypeName;
|
||||
};
|
||||
union
|
||||
{
|
||||
struct // File Entry
|
||||
{
|
||||
u32 FileOffset;
|
||||
u32 FileLength;
|
||||
};
|
||||
struct // Dir Entry
|
||||
{
|
||||
u32 ParentOffset;
|
||||
u32 NextOffset;
|
||||
};
|
||||
u32 entry[2];
|
||||
};
|
||||
} FEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 Offset;
|
||||
u32 Size;
|
||||
FIL File;
|
||||
} FileCache;
|
||||
|
||||
#define FILECACHE_MAX 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *data;
|
||||
u32 len;
|
||||
} vector;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 TMDSize;
|
||||
u32 TMDOffset;
|
||||
u32 CertChainSize;
|
||||
u32 CertChainOffset;
|
||||
u32 H3TableOffset;
|
||||
u32 DataOffset;
|
||||
u32 DataSize;
|
||||
} PartitionInfo;
|
||||
|
||||
void DIInit( void );
|
||||
u32 DIUpdateRegisters( void );
|
||||
|
||||
#endif
|
102
diskio.c
Normal file
102
diskio.c
Normal file
@ -0,0 +1,102 @@
|
||||
#include "diskio.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
|
||||
extern u32 IsInit;
|
||||
|
||||
DSTATUS disk_initialize( BYTE drv )
|
||||
{
|
||||
s32 r, s_cnt;
|
||||
u32 s_size;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
udelay( 50000 );
|
||||
|
||||
tiny_ehci_init();
|
||||
|
||||
int ret = -ENODEV;
|
||||
|
||||
do {
|
||||
|
||||
udelay( 4000 );
|
||||
ret = ehci_discover();
|
||||
|
||||
} while( ret == -ENODEV );
|
||||
|
||||
dbgprintf("ehci_discover():%d\n", ret );
|
||||
|
||||
r = USBStorage_Init();
|
||||
|
||||
if( r == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
s_cnt = USBStorage_Get_Capacity( &s_size );
|
||||
|
||||
dbgprintf( "DIP: Drive size: %dMB SectorSize:%d\n", s_cnt / 1024 * s_size / 1024, s_size);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
DSTATUS disk_status( BYTE drv )
|
||||
{
|
||||
(void)drv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRESULT disk_read( BYTE drv, BYTE *buff, DWORD sector, BYTE count )
|
||||
{
|
||||
u8 *buffer = (u8*)buff;
|
||||
//dbgprintf("disk_read( %d, %d, %p, %p)\n", sector, count, buff, buffer );
|
||||
|
||||
if( (u32)buff & 0xF0000000 )
|
||||
{
|
||||
buffer = (u8*)0x1000;
|
||||
u32 i=0;
|
||||
u32 Blocks = 3;
|
||||
while(1)
|
||||
{
|
||||
if( (count-i) < Blocks )
|
||||
Blocks = (count-i);
|
||||
|
||||
USBStorage_Read_Sectors( sector + i, Blocks, buffer );
|
||||
memcpy( buff + i * 512, buffer, Blocks * 512 );
|
||||
|
||||
i+=Blocks;
|
||||
|
||||
if( i >= count )
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
USBStorage_Read_Sectors( sector, count, buffer );
|
||||
dc_flushrange( buffer, count*512 );
|
||||
ahb_flush_from( AHB_SDHC );
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
// Write Sector(s)
|
||||
DRESULT disk_write( BYTE drv, const BYTE *buff, DWORD sector, BYTE count )
|
||||
{
|
||||
u8 *buffer = (u8*)buff;
|
||||
|
||||
if( (u32)buff & 0xF0000000 )
|
||||
{
|
||||
buffer = (u8*)0x1000;
|
||||
u32 i;
|
||||
for( i=0; i < count; ++i )
|
||||
{
|
||||
memcpy( buffer, (void*)buff + i * 512, 512 );
|
||||
USBStorage_Write_Sectors( sector + i, 1, buffer );
|
||||
}
|
||||
} else {
|
||||
|
||||
ahb_flush_to( AHB_SDHC );
|
||||
USBStorage_Write_Sectors( sector, count, buffer );
|
||||
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
70
diskio.h
Normal file
70
diskio.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file R0.07 (C)ChaN, 2009
|
||||
/-----------------------------------------------------------------------
|
||||
/ FatFs module is an open source project to implement FAT file system to small
|
||||
/ embedded systems. It is opened for education, research and development under
|
||||
/ license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is no warranty.
|
||||
/ * You can use, modify and/or redistribute it for personal, non-profit or
|
||||
/ commercial use without any restriction under your responsibility.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
// original source: http://elm-chan.org/fsw/ff/00index_e.html
|
||||
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Read-only mode */
|
||||
#define _USE_IOCTL 1
|
||||
|
||||
#include "integer.h"
|
||||
#include "string.h"
|
||||
#include "ehci.h"
|
||||
#include "alloc.h"
|
||||
#include "tiny_ehci_glue.h"
|
||||
#include "dip.h"
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
#endif
|
||||
#if _USE_IOCTL == 1
|
||||
DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||
#endif
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
#if _USE_IOCTL == 1
|
||||
/* Command code for disk_ioctl() */
|
||||
#define CTRL_SYNC 0 /* Mandatory for write functions */
|
||||
#endif
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
16
dol.h
Normal file
16
dol.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef _DOL_
|
||||
#define _DOL_
|
||||
|
||||
typedef struct {
|
||||
unsigned int offsetText[7];
|
||||
unsigned int offsetData[11];
|
||||
unsigned int addressText[7];
|
||||
unsigned int addressData[11];
|
||||
unsigned int sizeText[7];
|
||||
unsigned int sizeData[11];
|
||||
unsigned int addressBSS;
|
||||
unsigned int sizeBSS;
|
||||
unsigned int entrypoint;
|
||||
} dolhdr;
|
||||
|
||||
#endif
|
78
ehci-mem.c
Normal file
78
ehci-mem.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Original Copyright (c) 2001 by David Brownell
|
||||
*
|
||||
* 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; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* this file is part of ehci.c */
|
||||
|
||||
|
||||
static inline void ehci_qtd_init(struct ehci_qtd *qtd
|
||||
)
|
||||
{
|
||||
dma_addr_t dma = ehci_virt_to_dma(qtd);
|
||||
memset (qtd, 0, sizeof *qtd);
|
||||
qtd->qtd_dma = dma;
|
||||
qtd->hw_token = (QTD_STS_HALT);
|
||||
qtd->hw_next = EHCI_LIST_END();
|
||||
qtd->hw_alt_next = EHCI_LIST_END();
|
||||
}
|
||||
static inline struct ehci_qtd * ehci_qtd_alloc(void)
|
||||
{
|
||||
struct ehci_qtd *qtd ;
|
||||
//debug_printf("ehci_qtd used=%x\n",ehci->qtd_used);
|
||||
BUG_ON(ehci->qtd_used>=EHCI_MAX_QTD);
|
||||
qtd = ehci->qtds[ehci->qtd_used++];
|
||||
ehci_qtd_init(qtd);
|
||||
return qtd;
|
||||
}
|
||||
|
||||
int ehci_mem_init (void)
|
||||
{
|
||||
int i;
|
||||
u32 ptr = 0x1800000 - DEFAULT_I_TDPS * sizeof(__le32);
|
||||
|
||||
ehci->periodic = (u32*)ptr;
|
||||
ehci->periodic_dma = ehci_virt_to_dma(ehci->periodic);
|
||||
|
||||
for (i = 0; i < DEFAULT_I_TDPS; i++)
|
||||
ehci->periodic[i] = EHCI_LIST_END();
|
||||
|
||||
ehci_writel( ehci->periodic_dma, &ehci->regs->frame_list );
|
||||
|
||||
for(i=0;i<EHCI_MAX_QTD;i++)
|
||||
{
|
||||
ptr -= sizeof(struct ehci_qtd);
|
||||
ehci->qtds[i] = (struct ehci_qtd*)(ptr);
|
||||
}
|
||||
|
||||
ehci->qtd_used = 0;
|
||||
|
||||
ptr -= sizeof(struct ehci_qh);
|
||||
ehci->asyncqh = (struct ehci_qh*)ptr;
|
||||
|
||||
ehci->asyncqh->ehci = ehci;
|
||||
ehci->asyncqh->qh_dma = ehci_virt_to_dma(ehci->asyncqh);
|
||||
ehci->asyncqh->qtd_head = NULL;
|
||||
|
||||
ptr -= sizeof(struct ehci_qh);
|
||||
ehci->async = (struct ehci_qh*)ptr;
|
||||
|
||||
ehci->async->ehci = ehci;
|
||||
ehci->async->qh_dma = ehci_virt_to_dma(ehci->async);
|
||||
ehci->async->qtd_head = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
832
ehci.c
Normal file
832
ehci.c
Normal file
@ -0,0 +1,832 @@
|
||||
/* simplest usb-ehci driver which features:
|
||||
|
||||
control and bulk transfers only
|
||||
only one transfer pending
|
||||
driver is synchronous (waiting for the end of the transfer)
|
||||
endianess independant
|
||||
no uncached memory allocation needed
|
||||
|
||||
this driver is originally based on the GPL linux ehci-hcd driver
|
||||
|
||||
* Original Copyright (c) 2001 by David Brownell
|
||||
*
|
||||
* 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; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* magic numbers that can affect system performance */
|
||||
|
||||
u32 IsInit = 0;
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
|
||||
#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
|
||||
#define EHCI_TUNE_RL_TT 0
|
||||
#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
|
||||
#define EHCI_TUNE_MULT_TT 1
|
||||
#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
|
||||
extern int verbose;
|
||||
static void
|
||||
dbg_qtd (const char *label, struct ehci_qtd *qtd)
|
||||
{
|
||||
//ehci_dbg( "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
|
||||
// hc32_to_cpup( &qtd->hw_next),
|
||||
// hc32_to_cpup( &qtd->hw_alt_next),
|
||||
// hc32_to_cpup( &qtd->hw_token),
|
||||
// hc32_to_cpup( &qtd->hw_buf [0]));
|
||||
//if (qtd->hw_buf [1])
|
||||
// ehci_dbg( " p1=%08x p2=%08x p3=%08x p4=%08x\n",
|
||||
// hc32_to_cpup( &qtd->hw_buf[1]),
|
||||
// hc32_to_cpup( &qtd->hw_buf[2]),
|
||||
// hc32_to_cpup( &qtd->hw_buf[3]),
|
||||
// hc32_to_cpup( &qtd->hw_buf[4]));
|
||||
}
|
||||
|
||||
static void
|
||||
dbg_qh (const char *label, struct ehci_qh *qh)
|
||||
{
|
||||
//ehci_dbg ( "%s qh %p n%08x info %x %x qtd %x\n", label,
|
||||
// qh,
|
||||
// hc32_to_cpu(qh->hw_next),
|
||||
// hc32_to_cpu(qh->hw_info1),
|
||||
// hc32_to_cpu(qh->hw_info2),
|
||||
// hc32_to_cpu(qh->hw_current));
|
||||
//dbg_qtd ("overlay", (struct ehci_qtd *) &qh->hw_qtd_next);
|
||||
}
|
||||
|
||||
static void
|
||||
dbg_command (void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
u32 command=ehci_readl( &ehci->regs->command);
|
||||
u32 async=ehci_readl( &ehci->regs->async_next);
|
||||
|
||||
ehci_dbg ("async_next: %08x\n",async);
|
||||
ehci_dbg (
|
||||
"command %06x %s=%d ithresh=%d%s%s%s%s %s %s\n",
|
||||
command,
|
||||
(command & CMD_PARK) ? "park" : "(park)",
|
||||
CMD_PARK_CNT (command),
|
||||
(command >> 16) & 0x3f,
|
||||
(command & CMD_LRESET) ? " LReset" : "",
|
||||
(command & CMD_IAAD) ? " IAAD" : "",
|
||||
(command & CMD_ASE) ? " Async" : "",
|
||||
(command & CMD_PSE) ? " Periodic" : "",
|
||||
(command & CMD_RESET) ? " Reset" : "",
|
||||
(command & CMD_RUN) ? "RUN" : "HALT"
|
||||
);
|
||||
#endif
|
||||
}
|
||||
static void
|
||||
dbg_status (void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
u32 status=ehci_readl( &ehci->regs->status);
|
||||
ehci_dbg (
|
||||
"status %04x%s%s%s%s%s%s%s%s%s%s\n",
|
||||
status,
|
||||
(status & STS_ASS) ? " Async" : "",
|
||||
(status & STS_PSS) ? " Periodic" : "",
|
||||
(status & STS_RECL) ? " Recl" : "",
|
||||
(status & STS_HALT) ? " Halt" : "",
|
||||
(status & STS_IAA) ? " IAA" : "",
|
||||
(status & STS_FATAL) ? " FATAL" : "",
|
||||
(status & STS_FLR) ? " FLR" : "",
|
||||
(status & STS_PCD) ? " PCD" : "",
|
||||
(status & STS_ERR) ? " ERR" : "",
|
||||
(status & STS_INT) ? " INT" : ""
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void debug_qtds(void)
|
||||
{
|
||||
//struct ehci_qh *qh = ehci->async;
|
||||
//struct ehci_qtd *qtd;
|
||||
//dbg_qh ("qh",qh);
|
||||
//dbg_command ();
|
||||
//dbg_status ();
|
||||
//for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||
//{
|
||||
// ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||
// dbg_qtd("qtd",qtd);
|
||||
// ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd));
|
||||
//}
|
||||
|
||||
}
|
||||
void dump_qh(struct ehci_qh *qh)
|
||||
{
|
||||
//struct ehci_qtd *qtd;
|
||||
//dbg_command ();
|
||||
//dbg_status ();
|
||||
//ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh));
|
||||
//dbg_qh("qh",qh);
|
||||
//print_hex_dump_bytes("qh:",DUMP_PREFIX_OFFSET,(void*)qh,12*4);
|
||||
//for(qtd = qh->qtd_head; qtd; qtd = qtd->next){
|
||||
// u32 *buf;
|
||||
// ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||
// dbg_qtd("qtd",qtd);
|
||||
// print_hex_dump_bytes("qtd:",DUMP_PREFIX_OFFSET,(void*)qtd,8*4);
|
||||
// buf = (u32*)hc32_to_cpu(qtd->hw_buf[0]);
|
||||
// if(buf)
|
||||
// print_hex_dump_bytes("qtd buf:",DUMP_PREFIX_OFFSET,(void*)(buf),8*4);
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* handshake - spin reading hc until handshake completes or fails
|
||||
* @ptr: address of hc register to be read
|
||||
* @mask: bits to look at in result of read
|
||||
* @done: value of those bits when handshake succeeds
|
||||
* @usec: timeout in microseconds
|
||||
*
|
||||
* Returns negative errno, or zero on success
|
||||
*
|
||||
* Success happens when the "mask" bits have the specified value (hardware
|
||||
* handshake done). There are two failure modes: "usec" have passed (major
|
||||
* hardware flakeout), or the register reads as all-ones (hardware removed).
|
||||
*
|
||||
* That last failure should_only happen in cases like physical cardbus eject
|
||||
* before driver shutdown. But it also seems to be caused by bugs in cardbus
|
||||
* bridge shutdown: shutting down the bridge before the devices using it.
|
||||
*/
|
||||
static int handshake (void __iomem *ptr,
|
||||
u32 mask, u32 done, int usec)
|
||||
{
|
||||
u32 result;
|
||||
do {
|
||||
result = ehci_readl( ptr);
|
||||
if (result == ~(u32)0) /* card removed */
|
||||
return -ENODEV;
|
||||
result &= mask;
|
||||
if (result == done)
|
||||
return 0;
|
||||
udelay(1);
|
||||
usec--;
|
||||
} while (usec > 0);
|
||||
|
||||
ehci_dbg("EHCI:handshake timeout!!\n");
|
||||
dump_qh(ehci->async);
|
||||
dump_qh(ehci->asyncqh);
|
||||
//BUG();
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
#include "ehci-mem.c"
|
||||
/* one-time init, only for memory state */
|
||||
static int ehci_init(void)
|
||||
{
|
||||
int retval;
|
||||
if( (retval = ehci_mem_init()) < 0 )
|
||||
return retval;
|
||||
/*
|
||||
* dedicate a qh for the async ring head, since we couldn't unlink
|
||||
* a 'real' qh without stopping the async schedule [4.8]. use it
|
||||
* as the 'reclamation list head' too.
|
||||
* its dummy is used in hw_alt_next of many tds, to prevent the qh
|
||||
* from automatically advancing to the next td after short reads.
|
||||
*/
|
||||
ehci->async->hw_next = QH_NEXT( ehci->async->qh_dma);
|
||||
ehci->async->hw_info1 = cpu_to_hc32( QH_HEAD);
|
||||
ehci->async->hw_token = cpu_to_hc32( QTD_STS_HALT);
|
||||
ehci->async->hw_qtd_next = EHCI_LIST_END();
|
||||
ehci->async->hw_alt_next = EHCI_LIST_END();//QTD_NEXT( ehci->async->dummy->qtd_dma);
|
||||
|
||||
if( ehci->ctrl_buffer != NULL )
|
||||
USB_Free( ehci->ctrl_buffer );
|
||||
|
||||
ehci->ctrl_buffer = USB_Alloc(sizeof(usbctrlrequest));
|
||||
|
||||
ehci->command = 0;
|
||||
ehci_writel( 0x00800002, &ehci->regs->command);
|
||||
ehci_writel( ehci->periodic_dma, &ehci->regs->frame_list);
|
||||
ehci_writel( ehci->async->qh_dma, &ehci->regs->async_next);
|
||||
ehci_writel( 0x00010009, &ehci->regs->command);
|
||||
ehci_writel( 1, &ehci->regs->configured_flag);
|
||||
ehci_writel( 0x00010029, &ehci->regs->command);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fill a qtd, returning how much of the buffer we were able to queue up */
|
||||
static int qtd_fill( struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token, int maxpacket)
|
||||
{
|
||||
int i, count;
|
||||
u64 addr = buf;
|
||||
//ehci_dbg("fill qtd with dma %X len %X\n",buf,len);
|
||||
/* one buffer entry per 4K ... first might be short or unaligned */
|
||||
qtd->hw_buf[0] = cpu_to_hc32( (u32)addr);
|
||||
qtd->hw_buf_hi[0] = 0;
|
||||
count = 0x1000 - (buf & 0x0fff); /* rest of that page */
|
||||
if (likely (len < count)) /* ... iff needed */
|
||||
count = len;
|
||||
else {
|
||||
buf += 0x1000;
|
||||
buf &= ~0x0fff;
|
||||
|
||||
/* per-qtd limit: from 16K to 20K (best alignment) */
|
||||
for (i = 1; count < len && i < 5; i++) {
|
||||
addr = buf;
|
||||
qtd->hw_buf[i] = cpu_to_hc32( (u32)addr);
|
||||
qtd->hw_buf_hi[i] = cpu_to_hc32(
|
||||
(u32)(addr >> 32));
|
||||
buf += 0x1000;
|
||||
if ((count + 0x1000) < len)
|
||||
count += 0x1000;
|
||||
else
|
||||
count = len;
|
||||
}
|
||||
|
||||
/* short packets may only terminate transfers */
|
||||
if (count != len)
|
||||
count -= (count % maxpacket);
|
||||
}
|
||||
qtd->hw_token = cpu_to_hc32( (count << 16) | token);
|
||||
qtd->length = count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
|
||||
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
|
||||
// ... and packet size, for any kind of endpoint descriptor
|
||||
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
|
||||
|
||||
/*
|
||||
* reverse of qh_urb_transaction: free a list of TDs.
|
||||
* also count the actual transfer length.
|
||||
*
|
||||
*/
|
||||
static void qh_end_transfer (void)
|
||||
{
|
||||
struct ehci_qtd *qtd;
|
||||
struct ehci_qh *qh = ehci->asyncqh;
|
||||
u32 token;
|
||||
int error = 0;
|
||||
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||
{
|
||||
token = hc32_to_cpu( qtd->hw_token);
|
||||
if (likely (QTD_PID (token) != 2))
|
||||
qtd->urb->actual_length += qtd->length - QTD_LENGTH (token);
|
||||
|
||||
if (!(qtd->length ==0 && ((token & 0xff)==QTD_STS_HALT)) && (token & QTD_STS_HALT))
|
||||
{
|
||||
ehci_dbg("EHCI:qtd error!:");
|
||||
if (token & QTD_STS_BABBLE)
|
||||
{
|
||||
/* FIXME "must" disable babbling device's port too */
|
||||
ehci_dbg(" BABBLE");
|
||||
}
|
||||
if (token & QTD_STS_MMF)
|
||||
{
|
||||
/* fs/ls interrupt xfer missed the complete-split */
|
||||
ehci_dbg(" missed micro frame");
|
||||
}
|
||||
if (token & QTD_STS_DBE)
|
||||
{
|
||||
ehci_dbg(" databuffer error");
|
||||
}
|
||||
if (token & QTD_STS_XACT)
|
||||
{
|
||||
ehci_dbg(" wrong ack");
|
||||
}
|
||||
if (QTD_CERR (token)==0)
|
||||
ehci_dbg(" toomany errors");
|
||||
|
||||
ehci_dbg("\n");
|
||||
error = -1;
|
||||
}
|
||||
}
|
||||
if(error)
|
||||
{
|
||||
dump_qh(ehci->asyncqh);
|
||||
qtd->urb->actual_length = error;
|
||||
}
|
||||
ehci->qtd_used = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* create a list of filled qtds for this URB; won't link into qh.
|
||||
*/
|
||||
struct ehci_qtd *qh_urb_transaction (
|
||||
struct ehci_urb *urb
|
||||
) {
|
||||
struct ehci_qtd *qtd, *qtd_prev;
|
||||
struct ehci_qtd *head;
|
||||
dma_addr_t buf;
|
||||
int len, maxpacket;
|
||||
int is_input;
|
||||
u32 token;
|
||||
|
||||
/*
|
||||
* URBs map to sequences of QTDs: one logical transaction
|
||||
*/
|
||||
head = qtd = ehci_qtd_alloc ();
|
||||
qtd->urb = urb;
|
||||
|
||||
urb->actual_length = 0;
|
||||
token = QTD_STS_ACTIVE;
|
||||
token |= (EHCI_TUNE_CERR << 10);
|
||||
/* for split transactions, SplitXState initialized to zero */
|
||||
|
||||
len = urb->transfer_buffer_length;
|
||||
is_input = urb->input;
|
||||
if (urb->ep==0) {/* is control */
|
||||
/* SETUP pid */
|
||||
qtd_fill( qtd, urb->setup_dma, sizeof (usbctrlrequest), token | (2 /* "setup" */ << 8), 8);
|
||||
|
||||
/* ... and always at least one more pid */
|
||||
token ^= QTD_TOGGLE;
|
||||
qtd_prev = qtd;
|
||||
qtd = ehci_qtd_alloc ();
|
||||
qtd->urb = urb;
|
||||
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||
qtd_prev->next = qtd;
|
||||
|
||||
/* for zero length DATA stages, STATUS is always IN */
|
||||
if (len == 0)
|
||||
token |= (1 /* "in" */ << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* data transfer stage: buffer setup
|
||||
*/
|
||||
buf = urb->transfer_dma;
|
||||
|
||||
if (is_input)
|
||||
token |= (1 /* "in" */ << 8);
|
||||
/* else it's already initted to "out" pid (0 << 8) */
|
||||
|
||||
maxpacket = max_packet(urb->maxpacket);
|
||||
|
||||
/*
|
||||
* buffer gets wrapped in one or more qtds;
|
||||
* last one may be "short" (including zero len)
|
||||
* and may serve as a control status ack
|
||||
*/
|
||||
for (;;) {
|
||||
int this_qtd_len;
|
||||
|
||||
this_qtd_len = qtd_fill( qtd, buf, len, token, maxpacket);
|
||||
len -= this_qtd_len;
|
||||
buf += this_qtd_len;
|
||||
|
||||
/*
|
||||
* short reads advance to a "magic" dummy instead of the next
|
||||
* qtd ... that forces the queue to stop, for manual cleanup.
|
||||
* (this will usually be overridden later.)
|
||||
*/
|
||||
if (is_input)
|
||||
qtd->hw_alt_next = ehci->asyncqh->hw_alt_next;
|
||||
|
||||
/* qh makes control packets use qtd toggle; maybe switch it */
|
||||
if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
|
||||
token ^= QTD_TOGGLE;
|
||||
|
||||
if (likely (len <= 0))
|
||||
break;
|
||||
|
||||
qtd_prev = qtd;
|
||||
qtd = ehci_qtd_alloc ();
|
||||
qtd->urb = urb;
|
||||
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||
qtd_prev->next = qtd;
|
||||
}
|
||||
|
||||
qtd->hw_alt_next = EHCI_LIST_END();
|
||||
|
||||
/*
|
||||
* control requests may need a terminating data "status" ack;
|
||||
* bulk ones may need a terminating short packet (zero length).
|
||||
*/
|
||||
if (likely (urb->transfer_buffer_length != 0)) {
|
||||
int one_more = 0;
|
||||
|
||||
if (urb->ep==0) {
|
||||
one_more = 1;
|
||||
token ^= 0x0100; /* "in" <--> "out" */
|
||||
token |= QTD_TOGGLE; /* force DATA1 */
|
||||
} else if(!(urb->transfer_buffer_length % maxpacket)) {
|
||||
//one_more = 1;
|
||||
}
|
||||
if (one_more) {
|
||||
qtd_prev = qtd;
|
||||
qtd = ehci_qtd_alloc ();
|
||||
qtd->urb = urb;
|
||||
qtd_prev->hw_next = QTD_NEXT( qtd->qtd_dma);
|
||||
qtd_prev->next = qtd;
|
||||
|
||||
/* never any data in such packets */
|
||||
qtd_fill( qtd, 0, 0, token, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* by default, enable interrupt on urb completion */
|
||||
qtd->hw_token |= cpu_to_hc32( QTD_IOC);
|
||||
return head;
|
||||
}
|
||||
int ehci_do_urb ( struct ehci_device *dev, struct ehci_urb *urb)
|
||||
{
|
||||
struct ehci_qh *qh;
|
||||
struct ehci_qtd *qtd;
|
||||
u32 info1 = 0, info2 = 0;
|
||||
int is_input;
|
||||
int maxp = 0;
|
||||
int retval;
|
||||
|
||||
//ehci_dbg ("do urb %X %X ep %X\n",urb->setup_buffer,urb->transfer_buffer,urb->ep);
|
||||
if(urb->ep==0) //control message
|
||||
urb->setup_dma = ehci_dma_map_to(urb->setup_buffer,sizeof (usbctrlrequest));
|
||||
|
||||
if( urb->transfer_buffer_length )
|
||||
{
|
||||
if(urb->input)
|
||||
urb->transfer_dma = ehci_dma_map_to( urb->transfer_buffer, urb->transfer_buffer_length );
|
||||
else
|
||||
urb->transfer_dma = ehci_dma_map_from( urb->transfer_buffer, urb->transfer_buffer_length );
|
||||
}
|
||||
|
||||
qh = ehci->asyncqh;
|
||||
memset(qh,0,12*4);
|
||||
qtd = qh_urb_transaction( urb );
|
||||
qh->qtd_head = qtd;
|
||||
|
||||
info1 |= ((urb->ep)&0xf)<<8;
|
||||
info1 |= dev->id;
|
||||
is_input = urb->input;
|
||||
maxp = urb->maxpacket;
|
||||
|
||||
info1 |= (2 << 12); /* EPS "high" */
|
||||
if(urb->ep==0)// control
|
||||
{
|
||||
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||
info1 |= 64 << 16; /* usb2 fixed maxpacket */
|
||||
info1 |= 1 << 14; /* toggle from qtd */
|
||||
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||
} else {//bulk
|
||||
|
||||
info1 |= (EHCI_TUNE_RL_HS << 28);
|
||||
/* The USB spec says that high speed bulk endpoints
|
||||
* always use 512 byte maxpacket. But some device
|
||||
* vendors decided to ignore that, and MSFT is happy
|
||||
* to help them do so. So now people expect to use
|
||||
* such nonconformant devices with Linux too; sigh.
|
||||
*/
|
||||
info1 |= max_packet(maxp) << 16;
|
||||
info2 |= (EHCI_TUNE_MULT_HS << 30);
|
||||
}
|
||||
|
||||
//ehci_dbg("HW info: %08X\n",info1);
|
||||
qh->hw_info1 = cpu_to_hc32( info1);
|
||||
qh->hw_info2 = cpu_to_hc32( info2);
|
||||
|
||||
qh->hw_next = QH_NEXT( qh->qh_dma );
|
||||
qh->hw_qtd_next = QTD_NEXT( qtd->qtd_dma );
|
||||
qh->hw_alt_next = EHCI_LIST_END();
|
||||
|
||||
if( urb->ep != 0 )
|
||||
{
|
||||
if( get_toggle( dev, urb->ep ) )
|
||||
qh->hw_token |= cpu_to_hc32(QTD_TOGGLE);
|
||||
else
|
||||
qh->hw_token &= ~cpu_to_hc32(QTD_TOGGLE);
|
||||
|
||||
//ehci_dbg("toggle for ep %x: %d %x\n", urb->ep, get_toggle(dev,urb->ep), qh->hw_token );
|
||||
}
|
||||
|
||||
qh->hw_token &= cpu_to_hc32( QTD_TOGGLE | QTD_STS_PING);
|
||||
|
||||
qh->hw_next = QH_NEXT(ehci->async->qh_dma);
|
||||
|
||||
|
||||
ehci_dma_map_bidir(qh,sizeof(struct ehci_qh));
|
||||
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||
ehci_dma_map_bidir(qtd,sizeof(struct ehci_qtd));
|
||||
|
||||
// start (link qh)
|
||||
ehci->async->hw_next = QH_NEXT(qh->qh_dma);
|
||||
ehci_dma_map_bidir(ehci->async,sizeof(struct ehci_qh));
|
||||
|
||||
retval = handshake(&ehci->regs->status,STS_INT,STS_INT,1000*1000);
|
||||
|
||||
//print_hex_dump_bytes ("qh mem",0,(void*)qh,17*4);
|
||||
//retval = poll_transfer_end(1000*1000);
|
||||
ehci_dma_unmap_bidir(ehci->async->qh_dma,sizeof(struct ehci_qh));
|
||||
ehci_dma_unmap_bidir(qh->qh_dma,sizeof(struct ehci_qh));
|
||||
|
||||
for(qtd = qh->qtd_head; qtd; qtd = qtd->next)
|
||||
ehci_dma_unmap_bidir(qtd->qtd_dma,sizeof(struct ehci_qtd));
|
||||
|
||||
// stop (unlink qh)
|
||||
ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma);
|
||||
ehci_dma_map_bidir(ehci->async,sizeof(struct ehci_qh));
|
||||
ehci_dma_unmap_bidir(ehci->async->qh_dma,sizeof(struct ehci_qh));
|
||||
|
||||
// ack
|
||||
ehci_writel( STS_RECL|STS_IAA|STS_INT, &ehci->regs->status);
|
||||
|
||||
if(urb->ep!=0)
|
||||
{
|
||||
set_toggle(dev,urb->ep,(qh->hw_token & cpu_to_hc32(QTD_TOGGLE))?1:0);
|
||||
//ehci_dbg("toggle for ep %x: %d %d %x %X\n",urb->ep,get_toggle(dev,urb->ep),(qh->hw_token & cpu_to_hc32(QTD_TOGGLE)),qh->hw_token,dev->toggles);
|
||||
}
|
||||
|
||||
if( retval >= 0 )
|
||||
// wait hc really stopped
|
||||
retval = handshake(&ehci->regs->async_next,~0,ehci->async->qh_dma,1*1000);
|
||||
//release memory, and actualise urb->actual_length
|
||||
qh_end_transfer();
|
||||
|
||||
if(urb->transfer_buffer_length)
|
||||
{
|
||||
if(urb->input)
|
||||
ehci_dma_unmap_to(urb->transfer_dma,urb->transfer_buffer_length);
|
||||
else
|
||||
ehci_dma_unmap_from(urb->transfer_dma,urb->transfer_buffer_length);
|
||||
}
|
||||
|
||||
if( urb->ep == 0 ) //control message
|
||||
ehci_dma_unmap_to(urb->setup_dma,sizeof (usbctrlrequest));
|
||||
|
||||
if(retval==0)
|
||||
{
|
||||
return urb->actual_length;
|
||||
}
|
||||
ehci_dbg ( "EHCI:unsuccessfull urb %d!!\n", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
s32 ehci_control_message(struct ehci_device *dev,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *buf)
|
||||
{
|
||||
struct ehci_urb urb;
|
||||
int ret;
|
||||
usbctrlrequest *req = (void*)0x17C0;
|
||||
|
||||
if( verbose )
|
||||
ehci_dbg("control msg: rt%02X r%02X v%04X i%04X s%04x %p\n", bmRequestType, bmRequest, wValue, wIndex, wLength, buf );
|
||||
|
||||
u32 *_req = (u32*)req;
|
||||
|
||||
_req[0] = (bmRequestType<<24) | (bmRequest<<16) | swab16(wValue);
|
||||
_req[1] = (swab16(wIndex) << 16) | swab16(wLength);
|
||||
|
||||
urb.setup_buffer = req;
|
||||
urb.ep = 0;
|
||||
urb.input = (bmRequestType&USB_CTRLTYPE_DIR_DEVICE2HOST)!=0;
|
||||
urb.maxpacket = 64;
|
||||
urb.transfer_buffer_length = wLength;
|
||||
|
||||
if( urb.transfer_buffer_length )
|
||||
{
|
||||
if( ((u32)buf >> 28 ) == 0xF )
|
||||
{
|
||||
urb.transfer_buffer = USB_Alloc( wLength );
|
||||
|
||||
//dbgprintf("memcpy(%p,%p,%u)\n", urb.transfer_buffer, buf, wLength );
|
||||
memcpy( urb.transfer_buffer, buf, wLength );
|
||||
|
||||
ret = ehci_do_urb( dev, &urb );
|
||||
|
||||
memcpy( buf, urb.transfer_buffer, wLength );
|
||||
USB_Free( urb.transfer_buffer );
|
||||
|
||||
} else {
|
||||
urb.transfer_buffer = buf;
|
||||
ret = ehci_do_urb( dev, &urb );
|
||||
}
|
||||
|
||||
//hexdump( buf, wLength > 0x20 ? 0x20 : wLength );
|
||||
|
||||
} else {
|
||||
|
||||
urb.transfer_buffer = NULL;
|
||||
ret = ehci_do_urb( dev, &urb );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
s32 ehci_bulk_message(struct ehci_device *dev,u8 bEndpoint,u16 wLength,void *rpData)
|
||||
{
|
||||
struct ehci_urb urb;
|
||||
s32 ret;
|
||||
urb.setup_buffer = NULL;
|
||||
urb.ep = bEndpoint;
|
||||
urb.input = (bEndpoint&0x80)!=0;
|
||||
urb.maxpacket = 512;
|
||||
urb.transfer_buffer_length = wLength;
|
||||
urb.transfer_buffer = rpData;
|
||||
|
||||
if (verbose)
|
||||
ehci_dbg ( "bulk msg: ep:%02X size:%02X addr:%04X\n", bEndpoint, wLength, urb.transfer_buffer );
|
||||
|
||||
// hexdump( urb.transfer_buffer, urb.transfer_buffer_length );
|
||||
if( ((u32)rpData >> 28) == 0xF )
|
||||
{
|
||||
memcpy( (void*)0xFE0, rpData, wLength );
|
||||
|
||||
urb.transfer_buffer = (u8*)0xFE0;
|
||||
|
||||
ret = ehci_do_urb( dev, &urb );
|
||||
|
||||
memcpy( rpData, (void*)0xFE0, wLength );
|
||||
|
||||
} else {
|
||||
ret = ehci_do_urb( dev, &urb );
|
||||
}
|
||||
|
||||
// hexdump( urb.transfer_buffer, urb.transfer_buffer_length );
|
||||
|
||||
if (verbose)
|
||||
ehci_dbg ( "==>%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
int ehci_reset_port(int port)
|
||||
{
|
||||
u32 __iomem *status_reg = &ehci->regs->port_status[port];
|
||||
struct ehci_device *dev = &ehci->devices[port];
|
||||
|
||||
u32 status = ehci_readl(status_reg);
|
||||
int retval = 0;
|
||||
|
||||
dev->id = 0;
|
||||
|
||||
if( (PORT_OWNER&status) || !(PORT_CONNECT&status) )
|
||||
{
|
||||
int retries = 10;
|
||||
while( !(PORT_CONNECT&status) && retries > 0 )
|
||||
{
|
||||
msleep(1000); // sleep 1 second
|
||||
status = ehci_readl(status_reg);
|
||||
ehci_dbg ( "EHCI:port %d status at retry %d %X \n", port,retries,status);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if( retries <= 0 )
|
||||
{
|
||||
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) );
|
||||
return -ENODEV;// no USB2 device connected
|
||||
}
|
||||
}
|
||||
|
||||
ehci_dbg ( "EHCI:port %d has usb2 device connected! reset it...\n", port);
|
||||
|
||||
if( PORT_USB11(ehci_readl(status_reg)) )
|
||||
{
|
||||
ehci_dbg("EHCI:Device is USB1.1\n");
|
||||
}
|
||||
|
||||
status = ehci_readl(status_reg);
|
||||
status|= PORT_RESET;
|
||||
ehci_writel( status, status_reg );
|
||||
|
||||
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);
|
||||
return retval;
|
||||
}
|
||||
|
||||
ehci_dbg ( "EHCI:port %d reseted status:%04x...\n", port,ehci_readl(status_reg));
|
||||
msleep(100);
|
||||
|
||||
// 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 );
|
||||
if (retval < 0)
|
||||
{
|
||||
ehci_dbg("EHCI:unable to get device desc...\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = ehci_control_message( dev, USB_CTRLTYPE_DIR_HOST2DEVICE, USB_REQ_SETADDRESS,port+1,0,0,0);
|
||||
if (retval < 0)
|
||||
{
|
||||
ehci_dbg("EHCI:unable to set device addr...\n");
|
||||
return retval;
|
||||
}
|
||||
dev->toggles = 0;
|
||||
|
||||
dev->id = port+1;
|
||||
ehci_dbg ( "EHCI:device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||
return retval;
|
||||
}
|
||||
int ehci_reset_device(struct ehci_device *dev)
|
||||
{
|
||||
return ehci_reset_port(dev->port);
|
||||
}
|
||||
#include "usbstorage.h"
|
||||
int ehci_discover(void)
|
||||
{
|
||||
int i;
|
||||
int ret = 0 ;
|
||||
// precondition: the ehci should be halted
|
||||
for(i = 0;i<ehci->num_port; i++)
|
||||
{
|
||||
struct ehci_device *dev = &ehci->devices[i];
|
||||
dev->port = i;
|
||||
ret = ehci_reset_port(i);
|
||||
|
||||
if( ret != -ENODEV )
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/* wii: quickly release non ehci or not connected ports,
|
||||
as we can't kick OHCI drivers laters if we discover a device for them.
|
||||
*/
|
||||
int ehci_release_ports(void)
|
||||
{
|
||||
int i;
|
||||
u32 __iomem *status_reg = &ehci->regs->port_status[2];
|
||||
while(ehci_readl(&ehci->regs->port_status[2]) == 0x1000);// wait port 2 to init
|
||||
msleep(1);// wait another msec..
|
||||
for(i = 0;i<ehci->num_port; i++){
|
||||
status_reg = &ehci->regs->port_status[i];
|
||||
u32 status = ehci_readl(status_reg);
|
||||
if (i==2 || !(PORT_CONNECT&status) || PORT_USB11(status))
|
||||
ehci_writel( PORT_OWNER,status_reg); // release port.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehci_open_device(int vid,int pid,int fd)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<ehci->num_port;i++)
|
||||
{
|
||||
ehci_dbg("try device: %d\n",i);
|
||||
if(ehci->devices[i].fd == 0 &&
|
||||
le16_to_cpu(ehci->devices[i].desc.idVendor) == vid &&
|
||||
le16_to_cpu(ehci->devices[i].desc.idProduct) == pid)
|
||||
{
|
||||
ehci_dbg("found device: %x %x\n",vid,pid);
|
||||
ehci->devices[i].fd = fd;
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
return -6;
|
||||
}
|
||||
int ehci_close_device(struct ehci_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
dev->fd = 0;
|
||||
return 0;
|
||||
}
|
||||
void * ehci_fd_to_dev(int fd)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<ehci->num_port;i++)
|
||||
{
|
||||
struct ehci_device *dev = &ehci->devices[i];
|
||||
ehci_dbg ( "EHCI:device %d:fd:%d %X %X...\n", dev->id,dev->fd,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||
if(dev->fd == fd){
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
ehci_dbg("unkown fd! %d\n",fd);
|
||||
return 0;
|
||||
}
|
||||
#define g_ehci #error
|
||||
int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf)
|
||||
{
|
||||
int i,j = 0;
|
||||
for(i=0;i<ehci->num_port && j<maxdev ;i++)
|
||||
{
|
||||
struct ehci_device *dev = &ehci->devices[i];
|
||||
if(dev->id != 0){
|
||||
ehci_dbg ( "EHCI:device %d: %X %X...\n", dev->id,le16_to_cpu(dev->desc.idVendor),le16_to_cpu(dev->desc.idProduct));
|
||||
buf[j*4] = 0;
|
||||
buf[j*4+1] = 0;
|
||||
buf[j*4+2] = le16_to_cpu(dev->desc.idVendor);
|
||||
buf[j*4+3] = le16_to_cpu(dev->desc.idProduct);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
ehci_dbg("EHCI:found %d devices\n",j);
|
||||
*num = j;
|
||||
return 0;
|
||||
}
|
||||
#include "usb.c"
|
||||
#include "usbstorage.c"
|
282
ehci.h
Normal file
282
ehci.h
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Kwiirk
|
||||
* Original Copyright (c) 2001-2002 by David Brownell
|
||||
*
|
||||
* 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; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "ehci_types.h"
|
||||
|
||||
#ifndef __LINUX_EHCI_HCD_H
|
||||
#define __LINUX_EHCI_HCD_H
|
||||
/* definitions used for the EHCI driver */
|
||||
|
||||
/*
|
||||
* __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
|
||||
* __leXX (normally) or __beXX (given EHCI_BIG_ENDIAN_DESC), depending on
|
||||
* the host controller implementation.
|
||||
*
|
||||
* To facilitate the strongest possible byte-order checking from "sparse"
|
||||
* and so on, we use __leXX unless that's not practical.
|
||||
*/
|
||||
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
|
||||
typedef __u32 __bitwise __hc32;
|
||||
typedef __u16 __bitwise __hc16;
|
||||
#else
|
||||
#define __hc32 __le32
|
||||
#define __hc16 __le16
|
||||
#endif
|
||||
|
||||
|
||||
#define EHCI_MAX_ROOT_PORTS 4 /* see HCS_N_PORTS */
|
||||
#define EHCI_MAX_QTD 8
|
||||
#include "usb.h"
|
||||
|
||||
struct ehci_device{
|
||||
usb_devdesc desc;
|
||||
int id;
|
||||
int port;
|
||||
int fd;
|
||||
u32 toggles;
|
||||
};
|
||||
#define ep_bit(ep) (((ep)&0xf)+(((ep)>>7)?16:0))
|
||||
#define get_toggle(dev,ep) (((dev)->toggles>>ep_bit(ep))&1)
|
||||
#define set_toggle(dev,ep,v) (dev)->toggles = ((dev)->toggles &(~(1<<ep_bit(ep)))) | ((v)<<ep_bit(ep))
|
||||
|
||||
struct ehci_urb{
|
||||
void* setup_buffer;
|
||||
dma_addr_t setup_dma;
|
||||
|
||||
void* transfer_buffer;
|
||||
dma_addr_t transfer_dma;
|
||||
u32 transfer_buffer_length;
|
||||
u32 actual_length;
|
||||
|
||||
u8 ep;
|
||||
u8 input;
|
||||
u32 maxpacket;
|
||||
};
|
||||
struct ehci_hcd { /* one per controller */
|
||||
/* glue to PCI and HCD framework */
|
||||
void __iomem *_regs;
|
||||
struct ehci_caps __iomem *caps;
|
||||
struct ehci_regs __iomem *regs;
|
||||
struct ehci_dbg_port __iomem *debug;
|
||||
void *device;
|
||||
__u32 hcs_params; /* cached register copy */
|
||||
|
||||
/* async schedule support */
|
||||
struct ehci_qh *async; // the head never gets a qtd inside.
|
||||
struct ehci_qh *asyncqh;
|
||||
|
||||
struct ehci_qtd *qtds[EHCI_MAX_QTD];
|
||||
int qtd_used;
|
||||
unsigned long next_statechange;
|
||||
u32 command;
|
||||
|
||||
/* HW need periodic table initialised even if we dont use it @todo:is it really true? */
|
||||
#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
|
||||
__hc32 *periodic; /* hw periodic table */
|
||||
dma_addr_t periodic_dma;
|
||||
|
||||
u8 num_port;
|
||||
struct ehci_device devices[EHCI_MAX_ROOT_PORTS]; /* the attached device list per port */
|
||||
void *ctrl_buffer; /* pre allocated buffer for control messages */
|
||||
};
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#include "ehci_defs.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
#define QTD_NEXT( dma) cpu_to_hc32( (u32)dma)
|
||||
|
||||
/*
|
||||
* EHCI Specification 0.95 Section 3.5
|
||||
* QTD: describe data transfer components (buffer, direction, ...)
|
||||
* See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
|
||||
*
|
||||
* These are associated only with "QH" (Queue Head) structures,
|
||||
* used with control, bulk, and interrupt transfers.
|
||||
*/
|
||||
struct ehci_qtd {
|
||||
/* first part defined by EHCI spec */
|
||||
__hc32 hw_next; /* see EHCI 3.5.1 */
|
||||
__hc32 hw_alt_next; /* see EHCI 3.5.2 */
|
||||
__hc32 hw_token; /* see EHCI 3.5.3 */
|
||||
#define QTD_TOGGLE (1 << 31) /* data toggle */
|
||||
#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
|
||||
#define QTD_IOC (1 << 15) /* interrupt on complete */
|
||||
#define QTD_CERR(tok) (((tok)>>10) & 0x3)
|
||||
#define QTD_PID(tok) (((tok)>>8) & 0x3)
|
||||
#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
|
||||
#define QTD_STS_HALT (1 << 6) /* halted on error */
|
||||
#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
|
||||
#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
|
||||
#define QTD_STS_XACT (1 << 3) /* device gave illegal response */
|
||||
#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
|
||||
#define QTD_STS_STS (1 << 1) /* split transaction state */
|
||||
#define QTD_STS_PING (1 << 0) /* issue PING? */
|
||||
|
||||
#define ACTIVE_BIT(ehci) cpu_to_hc32( QTD_STS_ACTIVE)
|
||||
#define HALT_BIT(ehci) cpu_to_hc32( QTD_STS_HALT)
|
||||
#define STATUS_BIT(ehci) cpu_to_hc32( QTD_STS_STS)
|
||||
|
||||
__hc32 hw_buf [5]; /* see EHCI 3.5.4 */
|
||||
__hc32 hw_buf_hi [5]; /* Appendix B */
|
||||
|
||||
/* the rest is HCD-private */
|
||||
dma_addr_t qtd_dma; /* qtd address */
|
||||
struct ehci_qtd *next; /* sw qtd list */
|
||||
struct ehci_urb *urb; /* qtd's urb */
|
||||
size_t length; /* length of buffer */
|
||||
} __attribute__ ((aligned (32)));
|
||||
|
||||
/* mask NakCnt+T in qh->hw_alt_next */
|
||||
#define QTD_MASK(ehci) cpu_to_hc32 ( ~0x1f)
|
||||
|
||||
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* type tag from {qh,itd,sitd,fstn}->hw_next */
|
||||
#define Q_NEXT_TYPE(dma) ((dma) & cpu_to_hc32( 3 << 1))
|
||||
|
||||
/*
|
||||
* Now the following defines are not converted using the
|
||||
* __constant_cpu_to_le32() macro anymore, since we have to support
|
||||
* "dynamic" switching between be and le support, so that the driver
|
||||
* can be used on one system with SoC EHCI controller using big-endian
|
||||
* descriptors as well as a normal little-endian PCI EHCI controller.
|
||||
*/
|
||||
/* values for that type tag */
|
||||
#define Q_TYPE_ITD (0 << 1)
|
||||
#define Q_TYPE_QH (1 << 1)
|
||||
#define Q_TYPE_SITD (2 << 1)
|
||||
#define Q_TYPE_FSTN (3 << 1)
|
||||
|
||||
/* next async queue entry, or pointer to interrupt/periodic QH */
|
||||
#define QH_NEXT(dma) (cpu_to_hc32( (((u32)dma)&~0x01f)|Q_TYPE_QH))
|
||||
|
||||
/* for periodic/async schedules and qtd lists, mark end of list */
|
||||
#define EHCI_LIST_END() cpu_to_hc32( 1) /* "null pointer" to hw */
|
||||
|
||||
/*
|
||||
* Entries in periodic shadow table are pointers to one of four kinds
|
||||
* of data structure. That's dictated by the hardware; a type tag is
|
||||
* encoded in the low bits of the hardware's periodic schedule. Use
|
||||
* Q_NEXT_TYPE to get the tag.
|
||||
*
|
||||
* For entries in the async schedule, the type tag always says "qh".
|
||||
*/
|
||||
union ehci_shadow {
|
||||
struct ehci_qh *qh; /* Q_TYPE_QH */
|
||||
struct ehci_itd *itd; /* Q_TYPE_ITD */
|
||||
struct ehci_sitd *sitd; /* Q_TYPE_SITD */
|
||||
struct ehci_fstn *fstn; /* Q_TYPE_FSTN */
|
||||
__hc32 *hw_next; /* (all types) */
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* EHCI Specification 0.95 Section 3.6
|
||||
* QH: describes control/bulk/interrupt endpoints
|
||||
* See Fig 3-7 "Queue Head Structure Layout".
|
||||
*
|
||||
* These appear in both the async and (for interrupt) periodic schedules.
|
||||
*/
|
||||
|
||||
struct ehci_qh {
|
||||
/* first part defined by EHCI spec */
|
||||
__hc32 hw_next; /* see EHCI 3.6.1 */
|
||||
__hc32 hw_info1; /* see EHCI 3.6.2 */
|
||||
#define QH_HEAD 0x00008000
|
||||
__hc32 hw_info2; /* see EHCI 3.6.2 */
|
||||
#define QH_SMASK 0x000000ff
|
||||
#define QH_CMASK 0x0000ff00
|
||||
#define QH_HUBADDR 0x007f0000
|
||||
#define QH_HUBPORT 0x3f800000
|
||||
#define QH_MULT 0xc0000000
|
||||
__hc32 hw_current; /* qtd list - see EHCI 3.6.4 */
|
||||
|
||||
/* qtd overlay (hardware parts of a struct ehci_qtd) */
|
||||
__hc32 hw_qtd_next;
|
||||
__hc32 hw_alt_next;
|
||||
__hc32 hw_token;
|
||||
__hc32 hw_buf [5];
|
||||
__hc32 hw_buf_hi [5];
|
||||
|
||||
/* the rest is HCD-private */
|
||||
dma_addr_t qh_dma; /* address of qh */
|
||||
struct ehci_qtd *qtd_head; /* sw qtd list */
|
||||
|
||||
struct ehci_hcd *ehci;
|
||||
|
||||
#define NO_FRAME ((unsigned short)~0) /* pick new start */
|
||||
} __attribute__ ((aligned (32)));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* cpu to ehci */
|
||||
#define cpu_to_hc32(b) cpu_to_le32(b)
|
||||
#define hc32_to_cpu(b) le32_to_cpu(b)
|
||||
#define hc32_to_cpup(b) le32_to_cpu(*(b))
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* os specific functions */
|
||||
void*ehci_maligned(int size,int alignement,int crossing);
|
||||
dma_addr_t ehci_virt_to_dma(void *);
|
||||
dma_addr_t ehci_dma_map_to(void *buf,size_t len);
|
||||
dma_addr_t ehci_dma_map_from(void *buf,size_t len);
|
||||
dma_addr_t ehci_dma_map_bidir(void *buf,size_t len);
|
||||
void ehci_dma_unmap_to(dma_addr_t buf,size_t len);
|
||||
void ehci_dma_unmap_from(dma_addr_t buf,size_t len);
|
||||
void ehci_dma_unmap_bidir(dma_addr_t buf,size_t len);
|
||||
|
||||
|
||||
/* extern API */
|
||||
|
||||
s32 ehci_control_message(struct ehci_device *dev,u8 bmRequestType,u8 bmRequest,u16 wValue,u16 wIndex,u16 wLength,void *buf);
|
||||
s32 ehci_bulk_message(struct ehci_device *dev,u8 bEndpoint,u16 wLength,void *rpData);
|
||||
int ehci_discover(void);
|
||||
int ehci_get_device_list(u8 maxdev,u8 b0,u8*num,u16*buf);
|
||||
|
||||
extern struct ehci_hcd *ehci; /* @todo put ehci as a static global and remove ehci from APIs.. */
|
||||
extern int ehci_open_device(int vid,int pid,int fd);
|
||||
extern int ehci_close_device(struct ehci_device *dev);
|
||||
extern void * ehci_fd_to_dev(int fd);
|
||||
extern int ehci_release_ports(void);
|
||||
|
||||
/* UMS API */
|
||||
|
||||
s32 USBStorage_Init(void);
|
||||
s32 USBStorage_Get_Capacity(u32*sector_size);
|
||||
s32 USBStorage_Read_Sectors(u32 sector, u32 numSectors, void *buffer);
|
||||
s32 USBStorage_Read_Stress(u32 sector, u32 numSectors, void *buffer);
|
||||
s32 USBStorage_Write_Sectors(u32 sector, u32 numSectors, const void *buffer);
|
||||
|
||||
#ifndef DEBUG
|
||||
#define STUB_DEBUG_FILES
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* __LINUX_EHCI_HCD_H */
|
160
ehci_defs.h
Normal file
160
ehci_defs.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2002 by David Brownell
|
||||
*
|
||||
* 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; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_USB_EHCI_DEF_H
|
||||
#define __LINUX_USB_EHCI_DEF_H
|
||||
|
||||
/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
|
||||
|
||||
/* Section 2.2 Host Controller Capability Registers */
|
||||
struct ehci_caps {
|
||||
/* these fields are specified as 8 and 16 bit registers,
|
||||
* but some hosts can't perform 8 or 16 bit PCI accesses.
|
||||
*/
|
||||
u32 hc_capbase;
|
||||
#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */
|
||||
#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */
|
||||
u32 hcs_params; /* HCSPARAMS - offset 0x4 */
|
||||
#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */
|
||||
#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */
|
||||
#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */
|
||||
#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */
|
||||
#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */
|
||||
#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */
|
||||
#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
|
||||
|
||||
u32 hcc_params; /* HCCPARAMS - offset 0x8 */
|
||||
#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */
|
||||
#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */
|
||||
#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */
|
||||
#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
|
||||
#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
|
||||
#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */
|
||||
u8 portroute [8]; /* nibbles for routing - offset 0xC */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Section 2.3 Host Controller Operational Registers */
|
||||
struct ehci_regs {
|
||||
|
||||
/* USBCMD: offset 0x00 */
|
||||
u32 command;
|
||||
/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
|
||||
#define CMD_PARK (1<<11) /* enable "park" on async qh */
|
||||
#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
|
||||
#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */
|
||||
#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
|
||||
#define CMD_ASE (1<<5) /* async schedule enable */
|
||||
#define CMD_PSE (1<<4) /* periodic schedule enable */
|
||||
/* 3:2 is periodic frame list size */
|
||||
#define CMD_RESET (1<<1) /* reset HC not bus */
|
||||
#define CMD_RUN (1<<0) /* start/stop HC */
|
||||
|
||||
/* USBSTS: offset 0x04 */
|
||||
u32 status;
|
||||
#define STS_ASS (1<<15) /* Async Schedule Status */
|
||||
#define STS_PSS (1<<14) /* Periodic Schedule Status */
|
||||
#define STS_RECL (1<<13) /* Reclamation */
|
||||
#define STS_HALT (1<<12) /* Not running (any reason) */
|
||||
/* some bits reserved */
|
||||
/* these STS_* flags are also intr_enable bits (USBINTR) */
|
||||
#define STS_IAA (1<<5) /* Interrupted on async advance */
|
||||
#define STS_FATAL (1<<4) /* such as some PCI access errors */
|
||||
#define STS_FLR (1<<3) /* frame list rolled over */
|
||||
#define STS_PCD (1<<2) /* port change detect */
|
||||
#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
|
||||
#define STS_INT (1<<0) /* "normal" completion (short, ...) */
|
||||
|
||||
/* USBINTR: offset 0x08 */
|
||||
u32 intr_enable;
|
||||
|
||||
/* FRINDEX: offset 0x0C */
|
||||
u32 frame_index; /* current microframe number */
|
||||
/* CTRLDSSEGMENT: offset 0x10 */
|
||||
u32 segment; /* address bits 63:32 if needed */
|
||||
/* PERIODICLISTBASE: offset 0x14 */
|
||||
u32 frame_list; /* points to periodic list */
|
||||
/* ASYNCLISTADDR: offset 0x18 */
|
||||
u32 async_next; /* address of next async queue head */
|
||||
|
||||
u32 reserved [9];
|
||||
|
||||
/* CONFIGFLAG: offset 0x40 */
|
||||
u32 configured_flag;
|
||||
#define FLAG_CF (1<<0) /* true: we'll support "high speed" */
|
||||
|
||||
/* PORTSC: offset 0x44 */
|
||||
u32 port_status [0]; /* up to N_PORTS */
|
||||
/* 31:23 reserved */
|
||||
#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
|
||||
#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
|
||||
#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
|
||||
/* 19:16 for port testing */
|
||||
#define PORT_LED_OFF (0<<14)
|
||||
#define PORT_LED_AMBER (1<<14)
|
||||
#define PORT_LED_GREEN (2<<14)
|
||||
#define PORT_LED_MASK (3<<14)
|
||||
#define PORT_OWNER (1<<13) /* true: companion hc owns this port */
|
||||
#define PORT_POWER (1<<12) /* true: has power (see PPC) */
|
||||
#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */
|
||||
/* 11:10 for detecting lowspeed devices (reset vs release ownership) */
|
||||
/* 9 reserved */
|
||||
#define PORT_RESET (1<<8) /* reset port */
|
||||
#define PORT_SUSPEND (1<<7) /* suspend port */
|
||||
#define PORT_RESUME (1<<6) /* resume it */
|
||||
#define PORT_OCC (1<<5) /* over current change */
|
||||
#define PORT_OC (1<<4) /* over current active */
|
||||
#define PORT_PEC (1<<3) /* port enable change */
|
||||
#define PORT_PE (1<<2) /* port enable */
|
||||
#define PORT_CSC (1<<1) /* connect status change */
|
||||
#define PORT_CONNECT (1<<0) /* device connected */
|
||||
#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define USBMODE 0x68 /* USB Device mode */
|
||||
#define USBMODE_SDIS (1<<3) /* Stream disable */
|
||||
#define USBMODE_BE (1<<2) /* BE/LE endianness select */
|
||||
#define USBMODE_CM_HC (3<<0) /* host controller mode */
|
||||
#define USBMODE_CM_IDLE (0<<0) /* idle state */
|
||||
|
||||
/* Appendix C, Debug port ... intended for use with special "debug devices"
|
||||
* that can help if there's no serial console. (nonstandard enumeration.)
|
||||
*/
|
||||
struct ehci_dbg_port {
|
||||
u32 control;
|
||||
#define DBGP_OWNER (1<<30)
|
||||
#define DBGP_ENABLED (1<<28)
|
||||
#define DBGP_DONE (1<<16)
|
||||
#define DBGP_INUSE (1<<10)
|
||||
#define DBGP_ERRCODE(x) (((x)>>7)&0x07)
|
||||
# define DBGP_ERR_BAD 1
|
||||
# define DBGP_ERR_SIGNAL 2
|
||||
#define DBGP_ERROR (1<<6)
|
||||
#define DBGP_GO (1<<5)
|
||||
#define DBGP_OUT (1<<4)
|
||||
#define DBGP_LEN(x) (((x)>>0)&0x0f)
|
||||
u32 pids;
|
||||
#define DBGP_PID_GET(x) (((x)>>16)&0xff)
|
||||
#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok))
|
||||
u32 data03;
|
||||
u32 data47;
|
||||
u32 address;
|
||||
#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep))
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* __LINUX_USB_EHCI_DEF_H */
|
55
ehci_types.h
Normal file
55
ehci_types.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef __EHCI_TYPES_H__
|
||||
#define __EHCI_TYPES_H__
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/* linux kernel types needed by our code */
|
||||
#define __iomem
|
||||
|
||||
typedef unsigned long uint32_t;
|
||||
|
||||
#if 0
|
||||
typedef unsigned long u32;
|
||||
typedef signed long s32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
typedef char s8;
|
||||
typedef unsigned long long u64;
|
||||
#endif
|
||||
|
||||
#define __u32 u32
|
||||
#define __le32 u32
|
||||
#define dma_addr_t u32
|
||||
#define __GNUG__
|
||||
typedef u32 spinlock_t;
|
||||
typedef enum
|
||||
{
|
||||
GFP_KERNEL=1
|
||||
}gfp_t;
|
||||
struct timer_list
|
||||
{
|
||||
int time;
|
||||
};
|
||||
enum{
|
||||
ENODEV =1,
|
||||
ETIMEDOUT,
|
||||
EINVAL,
|
||||
ENOMEM,
|
||||
|
||||
};
|
||||
#define jiffies 0
|
||||
#define likely(x) (x)
|
||||
#define unlikely(x) (x)
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
#undef offsetof
|
||||
#ifdef __compiler_offsetof
|
||||
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
|
||||
#else
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
74
elf.h
Normal file
74
elf.h
Normal file
@ -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
|
7
elfloader/.deps/string.d
Normal file
7
elfloader/.deps/string.d
Normal file
@ -0,0 +1,7 @@
|
||||
string.o: string.c ../string.c ../string.h ../global.h
|
||||
|
||||
../string.c:
|
||||
|
||||
../string.h:
|
||||
|
||||
../global.h:
|
18
elfloader/.deps/stub.d
Normal file
18
elfloader/.deps/stub.d
Normal file
@ -0,0 +1,18 @@
|
||||
stub.o: stub.c types.h utils.h start.h hollywood.h string.h ../string.h \
|
||||
../global.h elf.h
|
||||
|
||||
types.h:
|
||||
|
||||
utils.h:
|
||||
|
||||
start.h:
|
||||
|
||||
hollywood.h:
|
||||
|
||||
string.h:
|
||||
|
||||
../string.h:
|
||||
|
||||
../global.h:
|
||||
|
||||
elf.h:
|
9
elfloader/.deps/utils.d
Normal file
9
elfloader/.deps/utils.d
Normal file
@ -0,0 +1,9 @@
|
||||
utils.o: utils.c types.h utils.h hollywood.h start.h
|
||||
|
||||
types.h:
|
||||
|
||||
utils.h:
|
||||
|
||||
hollywood.h:
|
||||
|
||||
start.h:
|
23
elfloader/Makefile
Normal file
23
elfloader/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
include starlet.mk
|
||||
|
||||
CFLAGS += -fpic -fno-builtin-memcpy
|
||||
LDSCRIPT = stub.ld
|
||||
LIBS = -lgcc
|
||||
|
||||
TARGET = elfloader.elf
|
||||
TARGET_BIN = elfloader.bin
|
||||
OBJS = start.o stub.o string.o utils.o
|
||||
|
||||
include common.mk
|
||||
|
||||
all: $(TARGET_BIN)
|
||||
|
||||
$(TARGET_BIN): $(TARGET)
|
||||
@echo " OBJCPY $@"
|
||||
@$(OBJCOPY) -O binary $< $@
|
||||
|
||||
clean: myclean
|
||||
|
||||
myclean:
|
||||
-rm -f $(TARGET_BIN)
|
||||
|
60
elfloader/common.mk
Normal file
60
elfloader/common.mk
Normal file
@ -0,0 +1,60 @@
|
||||
AR = $(PREFIX)ar
|
||||
AS = $(PREFIX)as
|
||||
CC = $(PREFIX)gcc
|
||||
CXX = $(PREFIX)g++
|
||||
LD = $(PREFIX)ld
|
||||
OBJCOPY = $(PREFIX)objcopy
|
||||
RANLIB = $(PREFIX)ranlib
|
||||
STRIP = $(PREFIX)strip
|
||||
|
||||
BIN2S = $(DEVKITPPC)/bin/bin2s
|
||||
|
||||
ifeq ($(NOMAPFILE),)
|
||||
LDFLAGS += -Wl,-Map,$(TARGET).map
|
||||
endif
|
||||
|
||||
ifneq ($(LDSCRIPT),)
|
||||
LDFLAGS += -Wl,-T$(LDSCRIPT)
|
||||
endif
|
||||
|
||||
DEPDIR = .deps
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
@echo " LINK $@"
|
||||
@$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||
|
||||
ifneq ($(LDSCRIPT),)
|
||||
$(TARGET): $(LDSCRIPT)
|
||||
endif
|
||||
|
||||
%.o: %.c
|
||||
@echo " COMPILE $<"
|
||||
@mkdir -p $(DEPDIR)
|
||||
@$(CC) $(CFLAGS) $(DEFINES) -Wp,-MMD,$(DEPDIR)/$(*F).d,-MQ,"$@",-MP -c $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
@echo " ASSEMBLE $<"
|
||||
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
@echo " ASSEMBLE $<"
|
||||
@$(CC) $(CFLAGS) $(DEFINES) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(DEPDIR)
|
||||
rm -f $(TARGET) $(TARGET).map $(OBJS)
|
||||
|
||||
define bin2o
|
||||
@echo " BIN2S $(notdir $<)"
|
||||
@$(BIN2S) -a 32 $< | $(AS) -o $(@)
|
||||
@echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(<F) | tr . _)`.h
|
||||
@echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(<F) | tr . _)`.h
|
||||
@echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(<F) | tr . _)`.h
|
||||
endef
|
||||
|
||||
-include $(DEPDIR)/*
|
||||
|
||||
.PHONY: clean
|
||||
|
66
elfloader/elf.h
Normal file
66
elfloader/elf.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: ELF structures
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#ifndef __ELF_H__
|
||||
#define __ELF_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
void *e_entry;
|
||||
u32 e_phoff;
|
||||
u32 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shtrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct {
|
||||
u32 p_type;
|
||||
u32 p_offset;
|
||||
void *p_vaddr;
|
||||
void *p_paddr;
|
||||
u32 p_filesz;
|
||||
u32 p_memsz;
|
||||
u32 p_flags;
|
||||
u32 p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
|
||||
#endif
|
||||
|
168
elfloader/elfloader.elf.map
Normal file
168
elfloader/elfloader.elf.map
Normal file
@ -0,0 +1,168 @@
|
||||
Archive member included because of file (symbol)
|
||||
|
||||
e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_udivsi3.o)
|
||||
utils.o (__aeabi_uidiv)
|
||||
e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_dvmd_tls.o)
|
||||
e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
|
||||
|
||||
Discarded input sections
|
||||
|
||||
.text 0x00000000 0x0 start.o
|
||||
.data 0x00000000 0x0 start.o
|
||||
.bss 0x00000000 0x0 start.o
|
||||
.text 0x00000000 0x0 stub.o
|
||||
.data 0x00000000 0x0 stub.o
|
||||
.bss 0x00000000 0x0 stub.o
|
||||
.text 0x00000000 0x0 string.o
|
||||
.data 0x00000000 0x0 string.o
|
||||
.bss 0x00000000 0x0 string.o
|
||||
.text.strnlen 0x00000000 0x2c string.o
|
||||
.text.strlen 0x00000000 0x20 string.o
|
||||
.text.strncpy 0x00000000 0x4c string.o
|
||||
.text.strcpy 0x00000000 0x18 string.o
|
||||
.text.strcmp 0x00000000 0x28 string.o
|
||||
.text.strncmp 0x00000000 0x48 string.o
|
||||
.text.memset 0x00000000 0x1c string.o
|
||||
.text.strchr 0x00000000 0x28 string.o
|
||||
.text 0x00000000 0x0 utils.o
|
||||
.data 0x00000000 0x0 utils.o
|
||||
.bss 0x00000000 0x0 utils.o
|
||||
.data 0x00000000 0x0 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_udivsi3.o)
|
||||
.bss 0x00000000 0x0 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_udivsi3.o)
|
||||
.data 0x00000000 0x0 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_dvmd_tls.o)
|
||||
.bss 0x00000000 0x0 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_dvmd_tls.o)
|
||||
|
||||
Memory Configuration
|
||||
|
||||
Name Origin Length Attributes
|
||||
*default* 0x00000000 0xffffffff
|
||||
|
||||
Linker script and memory map
|
||||
|
||||
0x00000000 __base_addr = 0x0
|
||||
0x00000000 . = __base_addr
|
||||
|
||||
.header 0x00000000 0x10
|
||||
0x00000000 __header = .
|
||||
0x00000000 0x4 LONG 0x10 __code_start
|
||||
0x00000004 0x4 LONG 0x4b0 __loader_size
|
||||
0x00000008 0x4 LONG 0x0
|
||||
0x0000000c 0x4 LONG 0x0
|
||||
0x00000010 . = ALIGN (0x10)
|
||||
0x00000010 __code_start = .
|
||||
|
||||
.init 0x00000010 0xc8
|
||||
*(.init)
|
||||
.init 0x00000010 0xc8 start.o
|
||||
0x00000010 _start
|
||||
0x000000bc debug_output
|
||||
0x000000d8 . = ALIGN (0x4)
|
||||
|
||||
.got 0x000000d8 0x0
|
||||
0x000000d8 __got_start = .
|
||||
*(.got.*)
|
||||
*(.got)
|
||||
0x000000d8 . = ALIGN (0x4)
|
||||
0x000000d8 __got_end = .
|
||||
|
||||
.text 0x000000d8 0x2d4
|
||||
*(.text.*)
|
||||
.text.disable_boot0
|
||||
0x000000d8 0x1c stub.o
|
||||
.text.mem_setswap
|
||||
0x000000f4 0x1c stub.o
|
||||
.text.loadelf 0x00000110 0x90 stub.o
|
||||
0x00000110 loadelf
|
||||
.text._main 0x000001a0 0x44 stub.o
|
||||
0x000001a0 _main
|
||||
.text.memcmp 0x000001e4 0x48 string.o
|
||||
0x000001e4 memcmp
|
||||
.text.udelay 0x0000022c 0x38 utils.o
|
||||
0x0000022c udelay
|
||||
.text.panic 0x00000264 0x30 utils.o
|
||||
0x00000264 panic
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7)
|
||||
.glue_7 0x00000000 0x0 linker stubs
|
||||
*(.glue_7t)
|
||||
.glue_7t 0x00000000 0x0 linker stubs
|
||||
0x00000294 . = ALIGN (0x4)
|
||||
.text 0x00000294 0x114 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_udivsi3.o)
|
||||
0x00000294 __aeabi_uidiv
|
||||
0x00000294 __udivsi3
|
||||
0x00000388 __aeabi_uidivmod
|
||||
.text 0x000003a8 0x4 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_dvmd_tls.o)
|
||||
0x000003a8 __aeabi_idiv0
|
||||
0x000003a8 __aeabi_ldiv0
|
||||
0x000003ac __text_end = .
|
||||
|
||||
.vfp11_veneer 0x000003ac 0x0
|
||||
.vfp11_veneer 0x00000000 0x0 linker stubs
|
||||
|
||||
.v4_bx 0x000003ac 0x0
|
||||
.v4_bx 0x00000000 0x0 linker stubs
|
||||
|
||||
.rodata 0x000003ac 0x8
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
.rodata.str1.1
|
||||
0x000003ac 0x8 stub.o
|
||||
*(.gnu.linkonce.r*)
|
||||
0x000003b4 . = ALIGN (0x4)
|
||||
|
||||
.data 0x000003b4 0x0
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
0x000003b4 . = ALIGN (0x4)
|
||||
|
||||
.bss 0x000003b4 0xc
|
||||
0x000003b4 __bss_start = .
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
0x000003c0 . = ALIGN (0x20)
|
||||
*fill* 0x000003b4 0xc 00
|
||||
0x000003c0 __bss_end = .
|
||||
0x000003c0 __stack_end = __bss_end
|
||||
0x000004c0 __stack_addr = (__bss_end + 0x100)
|
||||
0x000004c0 __end = __stack_addr
|
||||
0x000004b0 __loader_size = (__end - __code_start)
|
||||
[0x000003c0] PROVIDE (__stack_end, __stack_end)
|
||||
[0x000004c0] PROVIDE (__stack_addr, __stack_addr)
|
||||
[0x000000d8] PROVIDE (__got_start, __got_start)
|
||||
[0x000000d8] PROVIDE (__got_end, __got_end)
|
||||
[0x000003b4] PROVIDE (__bss_start, __bss_start)
|
||||
[0x000003c0] PROVIDE (__bss_end, __bss_end)
|
||||
LOAD start.o
|
||||
LOAD stub.o
|
||||
LOAD string.o
|
||||
LOAD utils.o
|
||||
LOAD e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a
|
||||
OUTPUT(elfloader.elf elf32-bigarm)
|
||||
|
||||
.ARM.attributes
|
||||
0x00000000 0x30
|
||||
.ARM.attributes
|
||||
0x00000000 0x24 start.o
|
||||
.ARM.attributes
|
||||
0x00000024 0x34 stub.o
|
||||
.ARM.attributes
|
||||
0x00000058 0x34 string.o
|
||||
.ARM.attributes
|
||||
0x0000008c 0x34 utils.o
|
||||
.ARM.attributes
|
||||
0x000000c0 0x1a e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_udivsi3.o)
|
||||
.ARM.attributes
|
||||
0x000000da 0x18 e:/devkitpro/devkitarm/bin/../lib/gcc/arm-eabi/4.6.1/be\libgcc.a(_dvmd_tls.o)
|
||||
|
||||
.comment 0x00000000 0x22
|
||||
.comment 0x00000000 0x22 stub.o
|
||||
0x23 (size before relaxing)
|
||||
.comment 0x00000000 0x23 string.o
|
||||
.comment 0x00000000 0x23 utils.o
|
31
elfloader/hollywood.h
Normal file
31
elfloader/hollywood.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: Hollywood register definitions
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#ifndef __HOLLYWOOD_H__
|
||||
#define __HOLLYWOOD_H__
|
||||
|
||||
#define HW_REG_BASE 0xd800000
|
||||
#define HW_TIMER (HW_REG_BASE + 0x010)
|
||||
#define HW_MEMMIRR (HW_REG_BASE + 0x060)
|
||||
#define HW_BOOT0 (HW_REG_BASE + 0x18c)
|
||||
|
||||
#endif
|
||||
|
12
elfloader/starlet.mk
Normal file
12
elfloader/starlet.mk
Normal file
@ -0,0 +1,12 @@
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Set DEVKITARM in your environment.")
|
||||
endif
|
||||
|
||||
PREFIX = $(DEVKITARM)/bin/arm-eabi-
|
||||
|
||||
CFLAGS = -mbig-endian -mcpu=arm926ej-s
|
||||
CFLAGS += -fomit-frame-pointer -ffunction-sections
|
||||
CFLAGS += -Wall -Wextra -Os -pipe
|
||||
ASFLAGS =
|
||||
LDFLAGS = -mbig-endian -n -nostartfiles -nodefaultlibs -Wl,-gc-sections
|
||||
|
113
elfloader/start.S
Normal file
113
elfloader/start.S
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: system startup
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
.arm
|
||||
|
||||
.extern _main
|
||||
.extern __got_start
|
||||
.extern __got_end
|
||||
.extern __bss_start
|
||||
.extern __bss_end
|
||||
.extern __stack_addr
|
||||
.extern delay
|
||||
.globl _start
|
||||
.globl debug_output
|
||||
|
||||
.section .init
|
||||
|
||||
_start:
|
||||
@ Get real address of _start
|
||||
sub r4, pc, #8
|
||||
@ Subtract offset to get the address that we were loaded at
|
||||
ldr r0, =_start
|
||||
sub r4, r4, r0
|
||||
@ Output 0x42 to the debug port
|
||||
mov r0, #0x42
|
||||
bl debug_output
|
||||
|
||||
@ Set up a stack
|
||||
ldr sp, =__stack_addr
|
||||
add sp, r4
|
||||
|
||||
@ Output 0x43 to the debug port
|
||||
mov r0, #0x43
|
||||
bl debug_output
|
||||
|
||||
@ relocate the GOT entries
|
||||
ldr r1, =__got_start
|
||||
add r1, r4
|
||||
ldr r2, =__got_end
|
||||
add r2, r4
|
||||
got_loop:
|
||||
@ check for the end
|
||||
cmp r1, r2
|
||||
beq done_got
|
||||
@ read the GOT entry
|
||||
ldr r3, [r1]
|
||||
@ add our base address
|
||||
add r3, r4
|
||||
str r3, [r1]
|
||||
@ move on
|
||||
add r1, r1, #4
|
||||
b got_loop
|
||||
|
||||
done_got:
|
||||
@ clear BSS
|
||||
ldr r1, =__bss_start
|
||||
add r1, r4
|
||||
ldr r2, =__bss_end
|
||||
add r2, r4
|
||||
mov r3, #0
|
||||
bss_loop:
|
||||
@ check for the end
|
||||
cmp r1, r2
|
||||
beq done_bss
|
||||
@ clear the word and move on
|
||||
str r3, [r1]
|
||||
add r1, r1, #4
|
||||
b bss_loop
|
||||
|
||||
done_bss:
|
||||
mov r0, #0x44
|
||||
bl debug_output
|
||||
@ take the plunge
|
||||
mov r0, r4
|
||||
bl _main
|
||||
@ _main returned! Go to whatever address it returned...
|
||||
mov r1, r0
|
||||
mov r0, r4
|
||||
mov pc, r1
|
||||
|
||||
.pool
|
||||
|
||||
debug_output:
|
||||
@ load address of port
|
||||
mov r3, #0xd800000
|
||||
@ load old value
|
||||
ldr r2, [r3, #0xe0]
|
||||
@ clear debug byte
|
||||
bic r2, r2, #0xFF0000
|
||||
@ insert new value
|
||||
and r0, r0, #0xFF
|
||||
orr r2, r2, r0, LSL #16
|
||||
@ store back
|
||||
str r2, [r3, #0xe0]
|
||||
mov pc, lr
|
30
elfloader/start.h
Normal file
30
elfloader/start.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: system startup
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#ifndef __START_H__
|
||||
#define __START_H__
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void debug_output(u8 byte);
|
||||
|
||||
#endif
|
||||
|
BIN
elfloader/start.o
Normal file
BIN
elfloader/start.o
Normal file
Binary file not shown.
1
elfloader/string.c
Normal file
1
elfloader/string.c
Normal file
@ -0,0 +1 @@
|
||||
#include "../string.c"
|
1
elfloader/string.h
Normal file
1
elfloader/string.h
Normal file
@ -0,0 +1 @@
|
||||
#include "../string.h"
|
BIN
elfloader/string.o
Normal file
BIN
elfloader/string.o
Normal file
Binary file not shown.
86
elfloader/stub.c
Normal file
86
elfloader/stub.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "start.h"
|
||||
#include "hollywood.h"
|
||||
#include "string.h"
|
||||
#include "elf.h"
|
||||
|
||||
typedef struct {
|
||||
u32 hdrsize;
|
||||
u32 loadersize;
|
||||
u32 elfsize;
|
||||
u32 argument;
|
||||
} ioshdr;
|
||||
|
||||
void *loadelf(const u8 *elf) {
|
||||
if(memcmp("\x7F" "ELF\x01\x02\x01",elf,7)) {
|
||||
panic(0xE3);
|
||||
}
|
||||
|
||||
Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf;
|
||||
if(ehdr->e_phoff == 0) {
|
||||
panic(0xE4);
|
||||
}
|
||||
int count = ehdr->e_phnum;
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr*)(elf + ehdr->e_phoff);
|
||||
while(count--)
|
||||
{
|
||||
if(phdr->p_type == PT_LOAD) {
|
||||
const void *src = elf + phdr->p_offset;
|
||||
memcpy(phdr->p_paddr, src, phdr->p_filesz);
|
||||
}
|
||||
phdr++;
|
||||
}
|
||||
return ehdr->e_entry;
|
||||
}
|
||||
|
||||
static inline void disable_boot0()
|
||||
{
|
||||
set32(HW_BOOT0, 0x1000);
|
||||
}
|
||||
|
||||
static inline void mem_setswap()
|
||||
{
|
||||
set32(HW_MEMMIRR, 0x20);
|
||||
}
|
||||
|
||||
void *_main(void *base)
|
||||
{
|
||||
ioshdr *hdr = (ioshdr*)base;
|
||||
u8 *elf;
|
||||
void *entry;
|
||||
|
||||
elf = (u8*) base;
|
||||
elf += hdr->hdrsize + hdr->loadersize;
|
||||
|
||||
debug_output(0xF1);
|
||||
mem_setswap(1);
|
||||
disable_boot0(1);
|
||||
|
||||
entry = loadelf(elf);
|
||||
debug_output(0xC1);
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
117
elfloader/stub.ld
Normal file
117
elfloader/stub.ld
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
elfloader - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-bigarm")
|
||||
OUTPUT_ARCH(arm)
|
||||
EXTERN(_start)
|
||||
ENTRY(_start)
|
||||
|
||||
__base_addr = 0;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = __base_addr;
|
||||
.header :
|
||||
{
|
||||
__header = .;
|
||||
/* Entry point (offset) */
|
||||
LONG(__code_start);
|
||||
/* Loader size */
|
||||
LONG(__loader_size);
|
||||
/* ELF size */
|
||||
LONG(0);
|
||||
/* Boot argument? */
|
||||
LONG(0);
|
||||
. = ALIGN(16);
|
||||
}
|
||||
|
||||
__code_start = .;
|
||||
|
||||
.init :
|
||||
{
|
||||
*(.init)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
.got :
|
||||
{
|
||||
__got_start = .;
|
||||
*(.got.*)
|
||||
*(.got)
|
||||
. = ALIGN(4);
|
||||
__got_end = . ;
|
||||
}
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text.*)
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
__text_end = . ;
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = . ;
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(32);
|
||||
__bss_end = . ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
__stack_end = (__bss_end);
|
||||
__stack_addr = (__bss_end + 0x100);
|
||||
|
||||
__end = __stack_addr ;
|
||||
__loader_size = __end - __code_start;
|
||||
|
||||
PROVIDE (__stack_end = __stack_end);
|
||||
PROVIDE (__stack_addr = __stack_addr);
|
||||
PROVIDE (__got_start = __got_start);
|
||||
PROVIDE (__got_end = __got_end);
|
||||
PROVIDE (__bss_start = __bss_start);
|
||||
PROVIDE (__bss_end = __bss_end);
|
||||
|
BIN
elfloader/stub.o
Normal file
BIN
elfloader/stub.o
Normal file
Binary file not shown.
50
elfloader/types.h
Normal file
50
elfloader/types.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: types
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
typedef signed long long s64;
|
||||
|
||||
typedef volatile unsigned char vu8;
|
||||
typedef volatile unsigned short vu16;
|
||||
typedef volatile unsigned int vu32;
|
||||
typedef volatile unsigned long long vu64;
|
||||
|
||||
typedef volatile signed char vs8;
|
||||
typedef volatile signed short vs16;
|
||||
typedef volatile signed int vs32;
|
||||
typedef volatile signed long long vs64;
|
||||
|
||||
typedef s32 size_t;
|
||||
|
||||
#define NULL ((void *)0)
|
||||
|
||||
#endif
|
||||
|
45
elfloader/utils.c
Normal file
45
elfloader/utils.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: random utilities
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "hollywood.h"
|
||||
#include "start.h"
|
||||
|
||||
void udelay(u32 d)
|
||||
{
|
||||
// should be good to max .2% error
|
||||
u32 ticks = d * 19 / 10;
|
||||
|
||||
write32(HW_TIMER, 0);
|
||||
while(read32(HW_TIMER) < ticks);
|
||||
}
|
||||
|
||||
void panic(u8 v)
|
||||
{
|
||||
while(1) {
|
||||
debug_output(v);
|
||||
udelay(500000);
|
||||
debug_output(0);
|
||||
udelay(500000);
|
||||
}
|
||||
}
|
||||
|
188
elfloader/utils.h
Normal file
188
elfloader/utils.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
mini - a Free Software replacement for the Nintendo/BroadOn IOS.
|
||||
|
||||
ELF loader: random utilities
|
||||
|
||||
Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#ifndef __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
|
||||
static inline u32 read32(u32 addr)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ("ldr\t%0, [%1]" : "=r" (data) : "r" (addr));
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline void write32(u32 addr, u32 data)
|
||||
{
|
||||
__asm__ volatile ("str\t%0, [%1]" : : "r" (data), "r" (addr));
|
||||
}
|
||||
|
||||
static inline u32 set32(u32 addr, u32 set)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile (
|
||||
"ldr\t%0, [%1]\n"
|
||||
"\torr\t%0, %2\n"
|
||||
"\tstr\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (set)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u32 clear32(u32 addr, u32 clear)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile (
|
||||
"ldr\t%0, [%1]\n"
|
||||
"\tbic\t%0, %2\n"
|
||||
"\tstr\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (clear)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static inline u32 mask32(u32 addr, u32 clear, u32 set)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile (
|
||||
"ldr\t%0, [%1]\n"
|
||||
"\tbic\t%0, %3\n"
|
||||
"\torr\t%0, %2\n"
|
||||
"\tstr\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (set), "r" (clear)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u16 read16(u32 addr)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ("ldrh\t%0, [%1]" : "=r" (data) : "r" (addr));
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline void write16(u32 addr, u16 data)
|
||||
{
|
||||
__asm__ volatile ("strh\t%0, [%1]" : : "r" (data), "r" (addr));
|
||||
}
|
||||
|
||||
static inline u16 set16(u32 addr, u16 set)
|
||||
{
|
||||
u16 data;
|
||||
__asm__ volatile (
|
||||
"ldrh\t%0, [%1]\n"
|
||||
"\torr\t%0, %2\n"
|
||||
"\tstrh\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (set)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u16 clear16(u32 addr, u16 clear)
|
||||
{
|
||||
u16 data;
|
||||
__asm__ volatile (
|
||||
"ldrh\t%0, [%1]\n"
|
||||
"\tbic\t%0, %2\n"
|
||||
"\tstrh\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (clear)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static inline u16 mask16(u32 addr, u16 clear, u16 set)
|
||||
{
|
||||
u16 data;
|
||||
__asm__ volatile (
|
||||
"ldrh\t%0, [%1]\n"
|
||||
"\tbic\t%0, %3\n"
|
||||
"\torr\t%0, %2\n"
|
||||
"\tstrh\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (set), "r" (clear)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u8 read8(u32 addr)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ("ldrb\t%0, [%1]" : "=r" (data) : "r" (addr));
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline void write8(u32 addr, u8 data)
|
||||
{
|
||||
__asm__ volatile ("strb\t%0, [%1]" : : "r" (data), "r" (addr));
|
||||
}
|
||||
|
||||
static inline u8 set8(u32 addr, u8 set)
|
||||
{
|
||||
u8 data;
|
||||
__asm__ volatile (
|
||||
"ldrb\t%0, [%1]\n"
|
||||
"\torr\t%0, %2\n"
|
||||
"\tstrb\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (set)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u8 clear8(u32 addr, u8 clear)
|
||||
{
|
||||
u8 data;
|
||||
__asm__ volatile (
|
||||
"ldrb\t%0, [%1]\n"
|
||||
"\tbic\t%0, %2\n"
|
||||
"\tstrb\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (clear)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
static inline u8 mask8(u32 addr, u8 clear, u8 set)
|
||||
{
|
||||
u8 data;
|
||||
__asm__ volatile (
|
||||
"ldrb\t%0, [%1]\n"
|
||||
"\tbic\t%0, %3\n"
|
||||
"\torr\t%0, %2\n"
|
||||
"\tstrb\t%0, [%1]"
|
||||
: "=&r" (data)
|
||||
: "r" (addr), "r" (set), "r" (clear)
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
void udelay(u32 d);
|
||||
void panic(u8 v);
|
||||
|
||||
#endif
|
||||
|
BIN
elfloader/utils.o
Normal file
BIN
elfloader/utils.o
Normal file
Binary file not shown.
335
ff.h
Normal file
335
ff.h
Normal file
@ -0,0 +1,335 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.08b (C)ChaN, 2011
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2011, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 8237 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1,2) */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector (FAT32) */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE pad1;
|
||||
DWORD fptr; /* File read/write pointer (0 on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
|
||||
#endif
|
||||
#if _FS_SHARE
|
||||
UINT lockid; /* File lock ID (index of file semaphore table) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Acces denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
int f_putc (TCHAR, FIL*); /* Put a character to the file */
|
||||
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT); /* Allocate memory block */
|
||||
void ff_memfree (void*); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek function */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
189
ffconf.h
Normal file
189
ffconf.h
Normal file
@ -0,0 +1,189 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08b (C)ChaN, 2011
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8237 /* Revision ID */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 437
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 1 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _FS_RPATH 1 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
||||
/ 2: f_getcwd() is available in addition to 1.
|
||||
/
|
||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for on-board flash memory, floppy disk and optical disk.
|
||||
/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
|
||||
/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
|
||||
/ should be added to the disk_ioctl functio. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size. */
|
||||
|
||||
|
||||
/* A header file that defines sync object types on the O/S, such as
|
||||
/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
|
||||
/
|
||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
||||
/ function must be added to the project. */
|
||||
|
||||
|
||||
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
|
||||
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
|
||||
defines how many files can be opened simultaneously. */
|
||||
|
||||
|
||||
#endif /* _FFCONFIG */
|
62
global.h
Normal file
62
global.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef __GLOBAL_H__
|
||||
#define __GLOBAL_H__
|
||||
|
||||
#define UINT_MAX ((unsigned int)0xffffffff)
|
||||
|
||||
#define CARD_DEBUG 1
|
||||
|
||||
#define CHEATHOOK 1
|
||||
//#define DEBUGGER 1
|
||||
//#define DEBUGGERWAIT 1
|
||||
//#define ACTIVITYLED 1
|
||||
//#define CARDMODE 1
|
||||
//#define CARDDEBUG 1
|
||||
#define REALNAND 1
|
||||
#define PADHOOK 1
|
||||
|
||||
#define CONFIG_VERSION 0x00000002
|
||||
#define DM_VERSION 0x0002000B
|
||||
|
||||
#define DI_SUCCESS 1
|
||||
#define DI_ERROR 2
|
||||
#define DI_FATAL 64
|
||||
|
||||
//#define DEBUG 0
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef int bool;
|
||||
typedef unsigned int sec_t;
|
||||
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
typedef signed long long s64;
|
||||
|
||||
typedef volatile unsigned char vu8;
|
||||
typedef volatile unsigned short vu16;
|
||||
typedef volatile unsigned int vu32;
|
||||
typedef volatile unsigned long long vu64;
|
||||
|
||||
typedef volatile signed char vs8;
|
||||
typedef volatile signed short vs16;
|
||||
typedef volatile signed int vs32;
|
||||
typedef volatile signed long long vs64;
|
||||
|
||||
typedef s32 size_t;
|
||||
|
||||
typedef u32 u_int32_t;
|
||||
|
||||
typedef s32(*ipccallback)(s32 result,void *usrdata);
|
||||
|
||||
#define NULL ((void *)0)
|
||||
|
||||
#define ALIGNED(x) __attribute__((aligned(x)))
|
||||
|
||||
#endif
|
||||
|
180
hollywood.h
Normal file
180
hollywood.h
Normal file
@ -0,0 +1,180 @@
|
||||
#ifndef __HOLLYWOOD_H__
|
||||
#define __HOLLYWOOD_H__
|
||||
|
||||
/* Hollywood Registers */
|
||||
|
||||
#define HW_PPC_REG_BASE 0xd000000
|
||||
#define HW_REG_BASE 0xd800000
|
||||
|
||||
#define IPC_CTRL_Y1 0x01
|
||||
#define IPC_CTRL_X2 0x02
|
||||
#define IPC_CTRL_X1 0x04
|
||||
#define IPC_CTRL_Y2 0x08
|
||||
|
||||
#define IPC_CTRL_IX1 0x10
|
||||
#define IPC_CTRL_IX2 0x20
|
||||
|
||||
// Our definitions for this IPC interface
|
||||
#define IPC_CTRL_OUT IPC_CTRL_Y1
|
||||
#define IPC_CTRL_IN IPC_CTRL_X1
|
||||
#define IPC_CTRL_IRQ_IN IPC_CTRL_IX1
|
||||
|
||||
// reset both flags (X* for ARM and Y* for PPC)
|
||||
#define IPC_CTRL_RESET 0x06
|
||||
|
||||
// The PPC can only see the first three IPC registers
|
||||
#define HW_IPC_PPCMSG (HW_REG_BASE + 0x000)
|
||||
#define HW_IPC_PPCCTRL (HW_REG_BASE + 0x004)
|
||||
#define HW_IPC_ARMMSG (HW_REG_BASE + 0x008)
|
||||
#define HW_IPC_ARMCTRL (HW_REG_BASE + 0x00c)
|
||||
|
||||
#define HW_TIMER (HW_REG_BASE + 0x010)
|
||||
#define HW_ALARM (HW_REG_BASE + 0x014)
|
||||
|
||||
#define HW_PPCIRQFLAG (HW_REG_BASE + 0x030)
|
||||
#define HW_PPCIRQMASK (HW_REG_BASE + 0x034)
|
||||
|
||||
#define HW_ARMIRQFLAG (HW_REG_BASE + 0x038)
|
||||
#define HW_ARMIRQMASK (HW_REG_BASE + 0x03c)
|
||||
|
||||
#define HW_MEMMIRR (HW_REG_BASE + 0x060)
|
||||
|
||||
// something to do with PPCBOOT
|
||||
// and legacy DI it seems ?!?
|
||||
#define HW_EXICTRL (HW_REG_BASE + 0x070)
|
||||
#define EXICTRL_ENABLE_EXI 1
|
||||
|
||||
// PPC side of GPIO1 (Starlet can access this too)
|
||||
// Output state
|
||||
#define HW_GPIO1BOUT (HW_REG_BASE + 0x0c0)
|
||||
// Direction (1=output)
|
||||
#define HW_GPIO1BDIR (HW_REG_BASE + 0x0c4)
|
||||
// Input state
|
||||
#define HW_GPIO1BIN (HW_REG_BASE + 0x0c8)
|
||||
// Interrupt level
|
||||
#define HW_GPIO1BINTLVL (HW_REG_BASE + 0x0cc)
|
||||
// Interrupt flags (write 1 to clear)
|
||||
#define HW_GPIO1BINTFLAG (HW_REG_BASE + 0x0d0)
|
||||
// Interrupt propagation enable
|
||||
// Do these interrupts go anywhere???
|
||||
#define HW_GPIO1BINTENABLE (HW_REG_BASE + 0x0d4)
|
||||
//??? seems to be a mirror of inputs at some point... power-up state?
|
||||
#define HW_GPIO1BINMIR (HW_REG_BASE + 0x0d8)
|
||||
// 0xFFFFFF by default, if cleared disables respective outputs. Top bits non-settable.
|
||||
#define HW_GPIO1ENABLE (HW_REG_BASE + 0x0dc)
|
||||
|
||||
#define HW_GPIO1_SLOT 0x000020
|
||||
#define HW_GPIO1_DEBUG 0xFF0000
|
||||
#define HW_GPIO1_DEBUG_SH 16
|
||||
|
||||
// Starlet side of GPIO1
|
||||
// Output state
|
||||
#define HW_GPIO1OUT (HW_REG_BASE + 0x0e0)
|
||||
// Direction (1=output)
|
||||
#define HW_GPIO1DIR (HW_REG_BASE + 0x0e4)
|
||||
// Input state
|
||||
#define HW_GPIO1IN (HW_REG_BASE + 0x0e8)
|
||||
// Interrupt level
|
||||
#define HW_GPIO1INTLVL (HW_REG_BASE + 0x0ec)
|
||||
// Interrupt flags (write 1 to clear)
|
||||
#define HW_GPIO1INTFLAG (HW_REG_BASE + 0x0f0)
|
||||
// Interrupt propagation enable (interrupts go to main interrupt 0x800)
|
||||
#define HW_GPIO1INTENABLE (HW_REG_BASE + 0x0f4)
|
||||
//??? seems to be a mirror of inputs at some point... power-up state?
|
||||
#define HW_GPIO1INMIR (HW_REG_BASE + 0x0f8)
|
||||
// Owner of each GPIO bit. If 1, GPIO1B registers assume control. If 0, GPIO1 registers assume control.
|
||||
#define HW_GPIO1OWNER (HW_REG_BASE + 0x0fc)
|
||||
|
||||
// ????
|
||||
#define HW_DIFLAGS (HW_REG_BASE + 0x180)
|
||||
#define DIFLAGS_BOOT_CODE 0x100000
|
||||
|
||||
// maybe a GPIO???
|
||||
#define HW_CLOCKS (HW_REG_BASE + 0x190)
|
||||
#define HW_RESETS (HW_REG_BASE + 0x194)
|
||||
|
||||
#define HW_GPIO2OUT (HW_REG_BASE + 0x1c8)
|
||||
#define HW_GPIO2DIR (HW_REG_BASE + 0x1cc)
|
||||
#define HW_GPIO2IN (HW_REG_BASE + 0x1d0)
|
||||
|
||||
#define HW_OTPCMD (HW_REG_BASE + 0x1ec)
|
||||
#define HW_OTPDATA (HW_REG_BASE + 0x1f0)
|
||||
#define HW_VERSION (HW_REG_BASE + 0x214)
|
||||
|
||||
/* NAND Registers */
|
||||
|
||||
#define NAND_REG_BASE 0xd010000
|
||||
|
||||
#define NAND_CMD (NAND_REG_BASE + 0x000)
|
||||
#define NAND_STATUS NAND_CMD
|
||||
#define NAND_CONF (NAND_REG_BASE + 0x004)
|
||||
#define NAND_ADDR0 (NAND_REG_BASE + 0x008)
|
||||
#define NAND_ADDR1 (NAND_REG_BASE + 0x00c)
|
||||
#define NAND_DATA (NAND_REG_BASE + 0x010)
|
||||
#define NAND_ECC (NAND_REG_BASE + 0x014)
|
||||
#define NAND_UNK1 (NAND_REG_BASE + 0x018)
|
||||
#define NAND_UNK2 (NAND_REG_BASE + 0x01c)
|
||||
|
||||
/* AES Registers */
|
||||
|
||||
#define AES_REG_BASE 0xd020000
|
||||
|
||||
#define AES_CMD (AES_REG_BASE + 0x000)
|
||||
#define AES_SRC (AES_REG_BASE + 0x004)
|
||||
#define AES_DEST (AES_REG_BASE + 0x008)
|
||||
#define AES_KEY (AES_REG_BASE + 0x00c)
|
||||
#define AES_IV (AES_REG_BASE + 0x010)
|
||||
|
||||
/* SHA-1 Registers */
|
||||
|
||||
#define SHA_REG_BASE 0xd030000
|
||||
|
||||
#define SHA_CMD (SHA_REG_BASE + 0x000)
|
||||
#define SHA_SRC (SHA_REG_BASE + 0x004)
|
||||
#define SHA_H0 (SHA_REG_BASE + 0x008)
|
||||
#define SHA_H1 (SHA_REG_BASE + 0x00c)
|
||||
#define SHA_H2 (SHA_REG_BASE + 0x010)
|
||||
#define SHA_H3 (SHA_REG_BASE + 0x014)
|
||||
#define SHA_H4 (SHA_REG_BASE + 0x018)
|
||||
|
||||
/* SD Host Controller Registers */
|
||||
|
||||
#define SDHC_REG_BASE 0xd070000
|
||||
|
||||
/* EXI Registers */
|
||||
|
||||
#define EXI_REG_BASE 0xd806800
|
||||
#define EXI0_REG_BASE (EXI_REG_BASE+0x000)
|
||||
#define EXI1_REG_BASE (EXI_REG_BASE+0x014)
|
||||
#define EXI2_REG_BASE (EXI_REG_BASE+0x028)
|
||||
|
||||
#define EXI0_CSR (EXI0_REG_BASE+0x000)
|
||||
#define EXI0_MAR (EXI0_REG_BASE+0x004)
|
||||
#define EXI0_LENGTH (EXI0_REG_BASE+0x008)
|
||||
#define EXI0_CR (EXI0_REG_BASE+0x00c)
|
||||
#define EXI0_DATA (EXI0_REG_BASE+0x010)
|
||||
|
||||
#define EXI1_CSR (EXI1_REG_BASE+0x000)
|
||||
#define EXI1_MAR (EXI1_REG_BASE+0x004)
|
||||
#define EXI1_LENGTH (EXI1_REG_BASE+0x008)
|
||||
#define EXI1_CR (EXI1_REG_BASE+0x00c)
|
||||
#define EXI1_DATA (EXI1_REG_BASE+0x010)
|
||||
|
||||
#define EXI2_CSR (EXI2_REG_BASE+0x000)
|
||||
#define EXI2_MAR (EXI2_REG_BASE+0x004)
|
||||
#define EXI2_LENGTH (EXI2_REG_BASE+0x008)
|
||||
#define EXI2_CR (EXI2_REG_BASE+0x00c)
|
||||
#define EXI2_DATA (EXI2_REG_BASE+0x010)
|
||||
|
||||
#define EXI_BOOT_BASE (EXI_REG_BASE+0x040)
|
||||
|
||||
/* MEMORY CONTROLLER Registers */
|
||||
|
||||
#define MEM_REG_BASE 0xd8b4000
|
||||
#define MEM_PROT (MEM_REG_BASE+0x20a)
|
||||
#define MEM_PROT_START (MEM_REG_BASE+0x20c)
|
||||
#define MEM_PROT_END (MEM_REG_BASE+0x20e)
|
||||
#define MEM_FLUSHREQ (MEM_REG_BASE+0x228)
|
||||
#define MEM_FLUSHACK (MEM_REG_BASE+0x22a)
|
||||
|
||||
#endif
|
37
integer.h
Normal file
37
integer.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
#define _INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
81
iosmodule.ld
Normal file
81
iosmodule.ld
Normal file
@ -0,0 +1,81 @@
|
||||
OUTPUT_FORMAT("elf32-bigarm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
__stack_size = 0x4000;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
sram : ORIGIN = 0xFFFF0000, LENGTH = 0x10000
|
||||
stack : ORIGIN = 0xFFFE0000, LENGTH = 0x4000
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
sram PT_LOAD AT ( 0xFFFF0000 ) ;
|
||||
stack PT_LOAD AT ( 0xFFFE0000 ) ;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.init :
|
||||
{
|
||||
*(.init)
|
||||
. = ALIGN(4);
|
||||
} >sram :sram
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text*)
|
||||
*(.text.*)
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4);
|
||||
} >sram :sram
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
. = ALIGN(4);
|
||||
} >sram :sram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(4);
|
||||
} >sram :sram
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start = . ;
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = . ;
|
||||
} >sram :sram
|
||||
|
||||
|
||||
.stack :
|
||||
{
|
||||
__stack_end = .;
|
||||
. = . +__stack_size;
|
||||
. = ALIGN(4);
|
||||
__stack_addr = .;
|
||||
} >stack :stack
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.ARM.exidx*)
|
||||
*(.ARM.extab*)
|
||||
}
|
||||
}
|
325
main.c
Normal file
325
main.c
Normal file
@ -0,0 +1,325 @@
|
||||
/*
|
||||
|
||||
DIOS MIOS - Gamecube USB loader for Nintendo Wii
|
||||
|
||||
Copyright (C) 2010-2012 crediar
|
||||
|
||||
*/
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
#include "alloc.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "dol.h"
|
||||
#include "GCPad.h"
|
||||
#include "HW.h"
|
||||
#include "Patches.h"
|
||||
#include "Config.h"
|
||||
#include "Card.h"
|
||||
#include "DVD.h"
|
||||
#include "Drive.h"
|
||||
#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);
|
||||
return;
|
||||
}
|
||||
void SWI( u32 a, u32 b )
|
||||
{
|
||||
//dbgprintf("SWI:%X,%X\n", a, b );
|
||||
return;
|
||||
}
|
||||
void PrefetchAbort( void )
|
||||
{
|
||||
EXIControl(1);
|
||||
dbgprintf("PrefetchAbort\n");
|
||||
while(1);
|
||||
return;
|
||||
}
|
||||
void DataAbort( u32 a, u32 b, u32 c, u32 d, u32 e, u32 f, u32 g, u32 h )
|
||||
{
|
||||
u32 val;
|
||||
|
||||
__asm("mov %0,lr": "=r" (val) );
|
||||
|
||||
*(vu32*)0xD800070 |= 1;
|
||||
|
||||
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) )
|
||||
{
|
||||
set32( HW_EXICTRL, 1 );
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 0x20; i+=4 )
|
||||
dbgprintf("0x%08X:0x%08X\t0x%08X\n", i, read32( CARD_BASE + i ), read32( CARD_SHADOW + i ) );
|
||||
dbgprintf("\n");
|
||||
for( i = 0; i < 0x30; i+=4 )
|
||||
dbgprintf("0x%08X:0x%08X\t0x%08X\n", i, read32( 0x00002F00 + i ), read32( 0x00002F30 + i ) );
|
||||
dbgprintf("\n");
|
||||
|
||||
for( i = 0; i < 0x30; i+=4 )
|
||||
dbgprintf("0x%08X:0x%08X\t0x%08X\n", 0x0D806000 + i, read32( 0x0D806000 + i ), read32( 0x0D006000 + i ) );
|
||||
|
||||
dbgprintf("DVD:Error:%08X\n", DVDLowGetError() );
|
||||
|
||||
udelay(10000);
|
||||
|
||||
set32( HW_GPIO_ENABLE, GPIO_POWER );
|
||||
set32( HW_GPIO_OUT, GPIO_POWER );
|
||||
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
//Clear IRQ Flags
|
||||
write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) );
|
||||
write32( HW_GPIO_INTFLAG, read32(HW_GPIO_INTFLAG) );
|
||||
|
||||
return;
|
||||
}
|
||||
void FIQHandler( void )
|
||||
{
|
||||
//dbgprintf("FIQHandler\n");
|
||||
return;
|
||||
}
|
||||
void DebugPoke( u8 Value )
|
||||
{
|
||||
clear32( 0xD8000E0, 0xFF0000 );
|
||||
set32( 0xD8000E0, Value<<16 );
|
||||
}
|
||||
void SysReset( void )
|
||||
{
|
||||
write32( HW_RESETS, (read32( HW_RESETS ) | 0x20 ) & (~1) );
|
||||
}
|
||||
void SysShutdown( void )
|
||||
{
|
||||
set32( HW_GPIO_ENABLE, GPIO_POWER );
|
||||
set32( HW_GPIO_OUT, GPIO_POWER );
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
u32 fail;
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
udelay(800);
|
||||
|
||||
#ifndef REALNAND
|
||||
PPCReset();
|
||||
clear32( HW_RESETS, 0x48000 );
|
||||
clear32( 0xD800184, 0x438E );
|
||||
|
||||
ChangeClock();
|
||||
|
||||
DRAMInit(1,0);
|
||||
|
||||
set32( HW_RESETS, 0x48000 );
|
||||
set32( 0xD800184, 0x438E );
|
||||
|
||||
UNKInit( 1, 1 );
|
||||
#endif
|
||||
|
||||
set32( 0xD800038, IRQ_RESET|IRQ_GPIO1 );
|
||||
set32( 0xD80003C, IRQ_RESET|IRQ_GPIO1 );
|
||||
udelay(200);
|
||||
|
||||
u32 SP[2];
|
||||
GetRevision( SP+1, SP );
|
||||
if( SP[1] == 0 )
|
||||
{
|
||||
write32( HW_MEMIRR, 0x67 );
|
||||
} else {
|
||||
write32( HW_MEMIRR, 0x27 );
|
||||
}
|
||||
|
||||
MIOSInit();
|
||||
|
||||
#ifdef DEBUG
|
||||
dbgprintf("DIOS-MIOS [DEBUG] v%d.%d\n", DM_VERSION>>16, DM_VERSION & 0xFFFF );
|
||||
#else
|
||||
#ifdef REALNAND
|
||||
dbgprintf("DIOS-MIOS v%d.%db\n", DM_VERSION>>16, DM_VERSION & 0xFFFF );
|
||||
#else
|
||||
dbgprintf("DIOS-MIOS v%d.%da\n", DM_VERSION>>16, DM_VERSION & 0xFFFF );
|
||||
#endif
|
||||
#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("MEMInitLow()...\n");
|
||||
MEMInitLow();
|
||||
|
||||
// EHCI
|
||||
|
||||
*(vu32*)0x0D0400A4 = 0x00004026;
|
||||
*(vu32*)0x0D0400B0 = 0x0002422E;
|
||||
*(vu32*)0x0D0400B4 = 0x03802E14;
|
||||
|
||||
// DDR control
|
||||
|
||||
*(vu16*)0x0D8B4034 = 0x0000;
|
||||
*(vu16*)0x0D8B403C = 0x0000;
|
||||
*(vu16*)0x0D8B4034 = 0x0000;
|
||||
*(vu16*)0x0D8B403C = 0x0000;
|
||||
*(vu16*)0x0D8B4040 = 0x0000;
|
||||
*(vu16*)0x0D8B4044 = 0x0000;
|
||||
*(vu16*)0x0D8B4048 = 0x0000;
|
||||
*(vu16*)0x0D8B404C = 0x0000;
|
||||
*(vu16*)0x0D8B4050 = 0x0000;
|
||||
*(vu16*)0x0D8B4054 = 0x13EB;
|
||||
*(vu16*)0x0D8B4058 = 0x09B5;
|
||||
*(vu16*)0x0D8B4060 = 0x0000;
|
||||
*(vu16*)0x0D8B4064 = 0x0000;
|
||||
*(vu16*)0x0D8B420C = 0x3620;
|
||||
*(vu16*)0x0D8B4220 = 0xF000;
|
||||
|
||||
udelay(8000);
|
||||
|
||||
HeapInit( (u8*)0x13600000 );
|
||||
|
||||
set32( HW_EXICTRL, 1 );
|
||||
|
||||
DVDInit();
|
||||
|
||||
ConfigInit( (DML_CFG*)0x01200000 );
|
||||
|
||||
ConfigSetConfig( DML_CFG_BOOT_DISC2 );
|
||||
|
||||
if( !ConfigGetConfig(DML_CFG_BOOT_DISC) )
|
||||
{
|
||||
if( DVDSelectGame() == DI_SUCCESS )
|
||||
{
|
||||
if( ConfigGetConfig(DML_CFG_NMM) )
|
||||
CardInit();
|
||||
} else {
|
||||
dbgprintf("Loading disc\n");
|
||||
|
||||
((DML_CFG*)0x01200000)->Version = CONFIG_VERSION;
|
||||
((DML_CFG*)0x01200000)->Magicbytes = 0xD1050CF6;
|
||||
((DML_CFG*)0x01200000)->VideoMode = DML_VID_DML_AUTO;
|
||||
((DML_CFG*)0x01200000)->Config = DML_CFG_BOOT_DISC;
|
||||
}
|
||||
}
|
||||
|
||||
DIInit();
|
||||
|
||||
//Switch mem2 to ARAM
|
||||
DRAMCTRLWrite( 0x49, 0x0E );
|
||||
udelay(2);
|
||||
|
||||
DRAMCTRLWrite( 0x49, 0x0F );
|
||||
udelay(2);
|
||||
|
||||
HeapInit( (u8*)0xFFFE5000 );
|
||||
|
||||
write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) );
|
||||
write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) );
|
||||
|
||||
set32( HW_PPCIRQMASK, (1<<31) );
|
||||
set32( HW_IPC_PPCCTRL, 0x30 );
|
||||
|
||||
write32( 0x0D806008, 0 );
|
||||
|
||||
EXIControl(0);
|
||||
|
||||
write32( 0x1860, 0xdeadbeef ); // Clear OSReport area
|
||||
write32( 0x30F8, 0 ); // Tell PPC side to start
|
||||
|
||||
ahb_flush_to( AHB_PPC );
|
||||
|
||||
u32 PADLock = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
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 ) )
|
||||
{
|
||||
SysReset();
|
||||
}
|
||||
if( (((read32(0x12FC) >> 16) & 0x234) == 0x234 ) )
|
||||
{
|
||||
SysShutdown();
|
||||
}
|
||||
|
||||
//Baten Kaitos save hax
|
||||
if( read32(0) == 0x474B4245 )
|
||||
{
|
||||
if( read32( 0x0073E640 ) == 0xFFFFFFFF )
|
||||
{
|
||||
write32( 0x0073E640, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//if( read32(0x1860) != 0xdeadbeef )
|
||||
//{
|
||||
// if( read32(0x1860) != 0 )
|
||||
// {
|
||||
// dbgprintf( (char*)(P2C(read32(0x1860))),
|
||||
// (char*)(P2C(read32(0x1864))),
|
||||
// (char*)(P2C(read32(0x1868))),
|
||||
// (char*)(P2C(read32(0x186C))),
|
||||
// (char*)(P2C(read32(0x1870))),
|
||||
// (char*)(P2C(read32(0x1864)))
|
||||
// );
|
||||
// }
|
||||
|
||||
// write32(0x1860, 0xdeadbeef);
|
||||
//}
|
||||
SMenuAddFramebuffer();
|
||||
|
||||
DIUpdateRegisters();
|
||||
|
||||
if( ConfigGetConfig(DML_CFG_NMM) )
|
||||
CARDUpdateRegisters();
|
||||
|
||||
ahb_flush_to( AHB_PPC ); //flush to ppc
|
||||
}
|
||||
}
|
251
memory.c
Normal file
251
memory.c
Normal file
@ -0,0 +1,251 @@
|
||||
#include "memory.h"
|
||||
|
||||
void _dc_inval_entries(void *start, int count);
|
||||
void _dc_flush_entries(const void *start, int count);
|
||||
void _dc_flush(void);
|
||||
void _ic_inval(void);
|
||||
void _drain_write_buffer(void);
|
||||
u32 irq_kill(void);
|
||||
void irq_restore(u32 cookie);
|
||||
|
||||
#define LINESIZE 0x20
|
||||
#define CACHESIZE 0x4000
|
||||
|
||||
|
||||
#define CR_MMU (1 << 0)
|
||||
#define CR_DCACHE (1 << 2)
|
||||
#define CR_ICACHE (1 << 12)
|
||||
|
||||
// TODO: move to hollywood.h once we figure out WTF
|
||||
#define HW_100 (HW_REG_BASE + 0x100)
|
||||
#define HW_104 (HW_REG_BASE + 0x104)
|
||||
#define HW_108 (HW_REG_BASE + 0x108)
|
||||
#define HW_10c (HW_REG_BASE + 0x10c)
|
||||
#define HW_110 (HW_REG_BASE + 0x110)
|
||||
#define HW_114 (HW_REG_BASE + 0x114)
|
||||
#define HW_118 (HW_REG_BASE + 0x118)
|
||||
#define HW_11c (HW_REG_BASE + 0x11c)
|
||||
#define HW_120 (HW_REG_BASE + 0x120)
|
||||
#define HW_124 (HW_REG_BASE + 0x124)
|
||||
#define HW_130 (HW_REG_BASE + 0x130)
|
||||
#define HW_134 (HW_REG_BASE + 0x134)
|
||||
#define HW_138 (HW_REG_BASE + 0x138)
|
||||
#define HW_188 (HW_REG_BASE + 0x188)
|
||||
#define HW_18C (HW_REG_BASE + 0x18c)
|
||||
|
||||
// what is this thing doing anyway?
|
||||
// and why only on reads?
|
||||
u32 _mc_read32(u32 addr)
|
||||
{
|
||||
u32 data;
|
||||
u32 tmp130 = 0;
|
||||
// this seems to be a bug workaround
|
||||
if(!(read32(HW_VERSION) & 0xF0))
|
||||
{
|
||||
tmp130 = read32(HW_130);
|
||||
write32(HW_130, tmp130 | 0x400);
|
||||
// Dummy reads?
|
||||
read32(HW_138);
|
||||
read32(HW_138);
|
||||
read32(HW_138);
|
||||
read32(HW_138);
|
||||
}
|
||||
data = read32(addr);
|
||||
read32(HW_VERSION); //???
|
||||
|
||||
if(!(read32(HW_VERSION) & 0xF0))
|
||||
write32(HW_130, tmp130);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// this is ripped from IOS, because no one can figure out just WTF this thing is doing
|
||||
void _ahb_flush_to(enum AHBDEV dev) {
|
||||
u32 mask = 10;
|
||||
switch(dev) {
|
||||
case AHB_STARLET: mask = 0x8000; break;
|
||||
case AHB_PPC: mask = 0x4000; break;
|
||||
//case 2: mask = 0x0001; break;
|
||||
case AHB_NAND: mask = 0x0002; break;
|
||||
case AHB_AES: mask = 0x0004; break;
|
||||
case AHB_SHA1: mask = 0x0008; break;
|
||||
case AHB_EHCI: mask = 0x0010; break;
|
||||
//case 7: mask = 0x0020; break;
|
||||
//case 8: mask = 0x0040; break;
|
||||
case AHB_SDHC: mask = 0x0080; break;
|
||||
//case 10: mask = 0x0100; break;
|
||||
//case 11: mask = 0x1000; break;
|
||||
//case 12: mask = 0x0000; break;
|
||||
default:
|
||||
dbgprintf("ahb_invalidate(%d): Invalid device\n", dev);
|
||||
return;
|
||||
}
|
||||
//NOTE: 0xd8b000x, not 0xd8b400x!
|
||||
u32 val = _mc_read32(0xd8b0008);
|
||||
if(!(val & mask)) {
|
||||
switch(dev) {
|
||||
// 2 to 10 in IOS, add more
|
||||
case AHB_NAND:
|
||||
case AHB_AES:
|
||||
case AHB_SHA1:
|
||||
case AHB_EHCI:
|
||||
case AHB_SDHC:
|
||||
while((read32(HW_18C) & 0xF) == 9)
|
||||
set32(HW_188, 0x10000);
|
||||
clear32(HW_188, 0x10000);
|
||||
set32(HW_188, 0x2000000);
|
||||
mask32(HW_124, 0x7c0, 0x280);
|
||||
set32(HW_134, 0x400);
|
||||
while((read32(HW_18C) & 0xF) != 9);
|
||||
set32(HW_100, 0x400);
|
||||
set32(HW_104, 0x400);
|
||||
set32(HW_108, 0x400);
|
||||
set32(HW_10c, 0x400);
|
||||
set32(HW_110, 0x400);
|
||||
set32(HW_114, 0x400);
|
||||
set32(HW_118, 0x400);
|
||||
set32(HW_11c, 0x400);
|
||||
set32(HW_120, 0x400);
|
||||
write32(0xd8b0008, _mc_read32(0xd8b0008) & (~mask));
|
||||
write32(0xd8b0008, _mc_read32(0xd8b0008) | mask);
|
||||
clear32(HW_134, 0x400);
|
||||
clear32(HW_100, 0x400);
|
||||
clear32(HW_104, 0x400);
|
||||
clear32(HW_108, 0x400);
|
||||
clear32(HW_10c, 0x400);
|
||||
clear32(HW_110, 0x400);
|
||||
clear32(HW_114, 0x400);
|
||||
clear32(HW_118, 0x400);
|
||||
clear32(HW_11c, 0x400);
|
||||
clear32(HW_120, 0x400);
|
||||
clear32(HW_188, 0x2000000);
|
||||
mask32(HW_124, 0x7c0, 0xc0);
|
||||
//0, 1, 11 in IOS, add more
|
||||
case AHB_STARLET:
|
||||
case AHB_PPC:
|
||||
write32(0xd8b0008, val & (~mask));
|
||||
// wtfux
|
||||
write32(0xd8b0008, val | mask);
|
||||
write32(0xd8b0008, val | mask);
|
||||
write32(0xd8b0008, val | mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invalidate device and then starlet
|
||||
void ahb_flush_to(enum AHBDEV type)
|
||||
{
|
||||
u32 cookie = irq_kill();
|
||||
_ahb_flush_to(type);
|
||||
if(type != AHB_STARLET)
|
||||
_ahb_flush_to(AHB_STARLET);
|
||||
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
// flush device and also invalidate memory
|
||||
void ahb_flush_from(enum AHBDEV dev)
|
||||
{
|
||||
u32 cookie = irq_kill();
|
||||
u16 req = 0;
|
||||
u16 ack;
|
||||
int i;
|
||||
|
||||
switch(dev)
|
||||
{
|
||||
case AHB_STARLET:
|
||||
case AHB_PPC:
|
||||
req = 1;
|
||||
break;
|
||||
case AHB_AES:
|
||||
case AHB_SHA1:
|
||||
req = 2;
|
||||
break;
|
||||
case AHB_NAND:
|
||||
case AHB_SDHC:
|
||||
req = 8;
|
||||
break;
|
||||
case AHB_EHCI:
|
||||
req = 4;
|
||||
break;
|
||||
default:
|
||||
dbgprintf("ahb_flush(%d): Invalid device\n", dev);
|
||||
goto done;
|
||||
}
|
||||
|
||||
write16(MEM_FLUSHREQ, req);
|
||||
|
||||
for(i=0;i<1000000;i++) {
|
||||
ack = read16(MEM_FLUSHACK);
|
||||
_ahb_flush_to(AHB_STARLET);
|
||||
if(ack == req)
|
||||
break;
|
||||
}
|
||||
write16(MEM_FLUSHREQ, 0);
|
||||
if(i>=1000000) {
|
||||
dbgprintf("ahb_flush(%d): Flush (0x%x) did not ack!\n", dev, req);
|
||||
}
|
||||
done:
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
void dc_flushrange(const void *start, u32 size)
|
||||
{
|
||||
u32 cookie = irq_kill();
|
||||
if(size > 0x4000) {
|
||||
_dc_flush();
|
||||
} else {
|
||||
void *end = ALIGN_FORWARD(((u8*)start) + size, LINESIZE);
|
||||
start = ALIGN_BACKWARD(start, LINESIZE);
|
||||
_dc_flush_entries(start, (end - start) / LINESIZE);
|
||||
}
|
||||
_drain_write_buffer();
|
||||
ahb_flush_from(AHB_PPC);
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
void dc_invalidaterange(void *start, u32 size)
|
||||
{
|
||||
u32 cookie = irq_kill();
|
||||
void *end = ALIGN_FORWARD(((u8*)start) + size, LINESIZE);
|
||||
start = ALIGN_BACKWARD(start, LINESIZE);
|
||||
_dc_inval_entries(start, (end - start) / LINESIZE);
|
||||
ahb_flush_to(AHB_STARLET);
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
void dc_flushall(void)
|
||||
{
|
||||
u32 cookie = irq_kill();
|
||||
_dc_flush();
|
||||
_drain_write_buffer();
|
||||
ahb_flush_from(AHB_PPC);
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
void ic_invalidateall(void)
|
||||
{
|
||||
u32 cookie = irq_kill();
|
||||
_ic_inval();
|
||||
ahb_flush_to(AHB_STARLET);
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
u32 dma_addr(void *p)
|
||||
{
|
||||
u32 addr = (u32)p;
|
||||
|
||||
switch(addr>>20) {
|
||||
case 0xfff:
|
||||
case 0x0d4:
|
||||
case 0x0dc:
|
||||
if(read32(HW_MEMMIRR) & 0x20) {
|
||||
addr ^= 0x10000;
|
||||
}
|
||||
addr &= 0x0001FFFF;
|
||||
addr |= 0x0d400000;
|
||||
break;
|
||||
}
|
||||
dbgprintf("DMA to %p: address %08x\n", p, addr);
|
||||
return addr;
|
||||
}
|
107
memory.h
Normal file
107
memory.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef __MEMORY_H__
|
||||
#define __MEMORY_H__
|
||||
|
||||
#include "string.h"
|
||||
#include "global.h"
|
||||
#include "utils.h"
|
||||
#include "hollywood.h"
|
||||
#include "vsprintf.h"
|
||||
|
||||
#define ALIGN_FORWARD(x,align) \
|
||||
((typeof(x))((((u32)(x)) + (align) - 1) & (~(align-1))))
|
||||
|
||||
#define ALIGN_BACKWARD(x,align) \
|
||||
((typeof(x))(((u32)(x)) & (~(align-1))))
|
||||
|
||||
enum AHBDEV {
|
||||
AHB_STARLET = 0, //or MEM2 or some controller or bus or ??
|
||||
AHB_PPC = 1, //ppc or something else???
|
||||
AHB_NAND = 3,
|
||||
AHB_AES = 4,
|
||||
AHB_SHA1 = 5,
|
||||
AHB_EHCI = 6,
|
||||
AHB_SDHC = 9,
|
||||
};
|
||||
|
||||
void dc_flushrange(const void *start, u32 size);
|
||||
void dc_invalidaterange(void *start, u32 size);
|
||||
void dc_flushall(void);
|
||||
void ic_invalidateall(void);
|
||||
void ahb_flush_from(enum AHBDEV dev);
|
||||
void ahb_flush_to(enum AHBDEV dev);
|
||||
u32 dma_addr(void *p);
|
||||
|
||||
static inline u32 get_cr(void)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ( "mrc\tp15, 0, %0, c1, c0, 0" : "=r" (data) );
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u32 get_ttbr(void)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ( "mrc\tp15, 0, %0, c2, c0, 0" : "=r" (data) );
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u32 get_dacr(void)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ( "mrc\tp15, 0, %0, c3, c0, 0" : "=r" (data) );
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline void set_cr(u32 data)
|
||||
{
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c1, c0, 0" :: "r" (data) );
|
||||
}
|
||||
|
||||
static inline void set_ttbr(u32 data)
|
||||
{
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c2, c0, 0" :: "r" (data) );
|
||||
}
|
||||
|
||||
static inline void set_dacr(u32 data)
|
||||
{
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c3, c0, 0" :: "r" (data) );
|
||||
}
|
||||
|
||||
static inline u32 get_dfsr(void)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ( "mrc\tp15, 0, %0, c5, c0, 0" : "=r" (data) );
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u32 get_ifsr(void)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ( "mrc\tp15, 0, %0, c5, c0, 1" : "=r" (data) );
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline u32 get_far(void)
|
||||
{
|
||||
u32 data;
|
||||
__asm__ volatile ( "mrc\tp15, 0, %0, c6, c0, 0" : "=r" (data) );
|
||||
return data;
|
||||
}
|
||||
|
||||
void _ahb_flush_to(enum AHBDEV dev);
|
||||
|
||||
static inline void dc_inval_block_fast(void *block)
|
||||
{
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c7, c6, 1" :: "r" (block) );
|
||||
_ahb_flush_to(AHB_STARLET); //TODO: check if really needed and if not, remove
|
||||
}
|
||||
|
||||
static inline void dc_flush_block_fast(void *block)
|
||||
{
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c7, c10, 1" :: "r" (block) );
|
||||
__asm__ volatile ( "mcr\tp15, 0, %0, c7, c10, 4" :: "r" (0) );
|
||||
ahb_flush_from(AHB_PPC); //TODO: check if really needed and if not, remove
|
||||
}
|
||||
|
||||
#endif
|
||||
|
70
memory_asm.S
Normal file
70
memory_asm.S
Normal file
@ -0,0 +1,70 @@
|
||||
#define CPSR_IRQDIS 0x80
|
||||
#define CPSR_FIQDIS 0x40
|
||||
|
||||
.arm
|
||||
|
||||
.globl _dc_inval_entries
|
||||
.globl _dc_flush_entries
|
||||
.globl _dc_flush
|
||||
.globl _dc_inval
|
||||
.globl _ic_inval
|
||||
.globl _drain_write_buffer
|
||||
.globl _tlb_inval
|
||||
.globl irq_kill
|
||||
.globl irq_restore
|
||||
|
||||
.text
|
||||
|
||||
irq_kill:
|
||||
mrs r1, cpsr
|
||||
and r0, r1, #(CPSR_IRQDIS|CPSR_FIQDIS)
|
||||
orr r1, r1, #(CPSR_IRQDIS|CPSR_FIQDIS)
|
||||
msr cpsr_c, r1
|
||||
bx lr
|
||||
|
||||
irq_restore:
|
||||
mrs r1, cpsr
|
||||
bic r1, r1, #(CPSR_IRQDIS|CPSR_FIQDIS)
|
||||
orr r1, r1, r0
|
||||
msr cpsr_c, r1
|
||||
bx lr
|
||||
|
||||
_dc_inval_entries:
|
||||
mcr p15, 0, r0, c7, c6, 1
|
||||
add r0, #0x20
|
||||
subs r1, #1
|
||||
bne _dc_inval_entries
|
||||
bx lr
|
||||
|
||||
_dc_flush_entries:
|
||||
mcr p15, 0, r0, c7, c10, 1
|
||||
add r0, #0x20
|
||||
subs r1, #1
|
||||
bne _dc_flush_entries
|
||||
bx lr
|
||||
|
||||
_dc_flush:
|
||||
mrc p15, 0, pc, c7, c10, 3
|
||||
bne _dc_flush
|
||||
bx lr
|
||||
|
||||
_dc_inval:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c6, 0
|
||||
bx lr
|
||||
|
||||
_ic_inval:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0
|
||||
bx lr
|
||||
|
||||
_drain_write_buffer:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
bx lr
|
||||
|
||||
_tlb_inval:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c8, c7
|
||||
bx lr
|
||||
|
213
start.s
Normal file
213
start.s
Normal file
@ -0,0 +1,213 @@
|
||||
.global _start
|
||||
.global start
|
||||
|
||||
.global udelay
|
||||
|
||||
.global RegWrite
|
||||
.global RegRead
|
||||
|
||||
.global DRAMWrite
|
||||
.global DRAMRead
|
||||
|
||||
.global DRAMCTRLRead
|
||||
.global DRAMCTRLWrite
|
||||
|
||||
.extern main
|
||||
.extern Syscall
|
||||
.extern SWI
|
||||
.extern PrefetchAbort
|
||||
.extern DataAbort
|
||||
.extern IRQHandler
|
||||
.extern FIQHandler
|
||||
.arm
|
||||
|
||||
.section ".init"
|
||||
_start:
|
||||
ldr pc, =start
|
||||
ldr pc, =Syscall
|
||||
ldr pc, =SWI
|
||||
ldr pc, =PrefetchAbort
|
||||
ldr pc, =DataAbort
|
||||
ldr pc, =0
|
||||
ldr pc, =IRQHandler
|
||||
movs pc, lr
|
||||
|
||||
start:
|
||||
mov r0, #0
|
||||
ldr r1, =0xd80003c
|
||||
str r0, [r1]
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0,c7,c5
|
||||
mcr p15, 0, r0,c7,c6
|
||||
|
||||
mrc p15, 0, r0,c1,c0
|
||||
bic r0, r0, #4
|
||||
bic r0, r0, #0x1000
|
||||
mcr p15, 0, r0,c1,c0
|
||||
|
||||
ldr r0,=__bss_start
|
||||
ldr r1,=__bss_end
|
||||
mov r2,#0
|
||||
mov r3,#4
|
||||
clearbss:
|
||||
cmp r0, r1
|
||||
bcs clearbss_end
|
||||
str r2, [r0], r3
|
||||
b clearbss
|
||||
|
||||
clearbss_end:
|
||||
|
||||
msr CPSR_c, #211
|
||||
ldr sp, =0xFFFF7E60
|
||||
msr CPSR_c, #210
|
||||
ldr sp, =0xFFFF7E60
|
||||
msr CPSR_c, #209
|
||||
ldr sp, =0xFFFF7E60
|
||||
msr CPSR_c, #215
|
||||
ldr sp, =0xFFFF7E60
|
||||
msr CPSR_c, #219
|
||||
ldr sp, =0xFFFF7E60
|
||||
msr CPSR_c, #31
|
||||
ldr sp, =0xFFFE4000
|
||||
|
||||
#enable IRQs
|
||||
|
||||
mrs r1, cpsr
|
||||
bic r1, r1, #0xC0
|
||||
msr cpsr_c, r1
|
||||
|
||||
mov lr, pc
|
||||
ldr pc, =main
|
||||
|
||||
RegWrite:
|
||||
ldr r3,=0xd8b4000
|
||||
lsl r0, r0, #1
|
||||
add r0, r0, r3
|
||||
strh r1, [r0]
|
||||
bx lr
|
||||
|
||||
RegRead:
|
||||
ldr r3,=0xd8b4000
|
||||
lsl r0, r0, #1
|
||||
add r0, r0, r3
|
||||
ldrh r0, [r0]
|
||||
lsl r0, r0, #0x10
|
||||
lsr r0, r0, #0x10
|
||||
bx lr
|
||||
|
||||
DRAMWrite:
|
||||
push {r4,lr}
|
||||
add r3, r0, #0
|
||||
add r4, r1, #0
|
||||
mov r0, #0x3a
|
||||
add r1, r3, #0
|
||||
bl RegWrite
|
||||
|
||||
mov r0, #0x3a
|
||||
bl RegRead
|
||||
|
||||
mov r0, #0x3b
|
||||
add r1, r4, #0
|
||||
bl RegWrite
|
||||
|
||||
pop {r4}
|
||||
pop {r0}
|
||||
bx r0
|
||||
|
||||
DRAMRead:
|
||||
push {lr}
|
||||
add r1, r0, #0
|
||||
mov r0, #0x3a
|
||||
bl RegWrite
|
||||
|
||||
mov r0, #0x3a
|
||||
bl RegRead
|
||||
|
||||
mov r0, #0x3b
|
||||
bl RegRead
|
||||
|
||||
pop {r1}
|
||||
bx r1
|
||||
|
||||
DRAMCTRLWrite:
|
||||
push {r4,r5,lr}
|
||||
ldr r4, =0x163
|
||||
add r3, r0, #0
|
||||
add r5, r1, #0
|
||||
add r0, r4, #0
|
||||
add r1, r3, #0
|
||||
bl DRAMWrite
|
||||
|
||||
add r0, r4, #0
|
||||
bl DRAMRead
|
||||
|
||||
mov r0, #0xb1
|
||||
add r1, r5, #0
|
||||
lsl r0, r0, #1
|
||||
bl DRAMWrite
|
||||
|
||||
pop {r4,r5}
|
||||
pop {r0}
|
||||
bx r0
|
||||
|
||||
DRAMCTRLRead:
|
||||
push {r4,lr}
|
||||
ldr r4, =0x163
|
||||
add r1, r0, #0
|
||||
add r0, r4, #0
|
||||
bl DRAMWrite
|
||||
|
||||
add r0, r4, #0
|
||||
bl DRAMRead
|
||||
|
||||
ldr r0, =0x162
|
||||
bl DRAMRead
|
||||
|
||||
pop {r4}
|
||||
pop {r1}
|
||||
bx r1
|
||||
|
||||
udelay:
|
||||
|
||||
push {lr}
|
||||
|
||||
lsr r3, r0, #2
|
||||
add r3, r3, r0
|
||||
lsr r2, r0, #6
|
||||
|
||||
add r0, r3, r2
|
||||
cmp r0, #1
|
||||
bhi loc_ffff20e8
|
||||
|
||||
mov r0, #2
|
||||
|
||||
loc_ffff20e8:
|
||||
ldr r1, =0xd800010
|
||||
ldr r3, [r1]
|
||||
add r2, r3, r0
|
||||
cmp r2, r3
|
||||
bls loc_ffff211c
|
||||
|
||||
loc_ffff20f2:
|
||||
ldr r3, [r1]
|
||||
cmp r3, r2
|
||||
bcc loc_ffff20f2
|
||||
|
||||
loc_ffff20f8:
|
||||
pop {r0}
|
||||
bx r0
|
||||
|
||||
loc_ffff211c:
|
||||
add r3, r1, #0
|
||||
|
||||
loc_ffff211e:
|
||||
ldr r0, [r3]
|
||||
cmp r0, #0
|
||||
blt loc_ffff211e
|
||||
|
||||
cmp r0, r2
|
||||
bcc loc_ffff211e
|
||||
b loc_ffff20f8
|
||||
|
||||
.end
|
125
string.c
Normal file
125
string.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* linux/lib/string.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
|
||||
size_t strnlen(const char *s, size_t count)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; count-- && *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *sc;
|
||||
|
||||
for (sc = s; *sc != '\0'; ++sc)
|
||||
/* nothing */;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
char *strncpy(char *dst, const char *src, size_t n)
|
||||
{
|
||||
char *ret = dst;
|
||||
|
||||
while (n && (*dst++ = *src++))
|
||||
n--;
|
||||
|
||||
while (n--)
|
||||
*dst++ = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src)
|
||||
{
|
||||
char *ret = dst;
|
||||
|
||||
while ((*dst++ = *src++))
|
||||
;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int strcmp(const char *p, const char *q)
|
||||
{
|
||||
for (;;) {
|
||||
unsigned char a, b;
|
||||
a = *p++;
|
||||
b = *q++;
|
||||
if (a == 0 || a != b)
|
||||
return a - b;
|
||||
}
|
||||
}
|
||||
|
||||
int strncmp(const char *p, const char *q, size_t n)
|
||||
{
|
||||
while (n-- != 0) {
|
||||
unsigned char a, b;
|
||||
a = *p++;
|
||||
b = *q++;
|
||||
if (a == 0 || a != b)
|
||||
return a - b;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void *memset(void *dst, int x, size_t n)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
for (p = dst; n; n--)
|
||||
*p++ = x;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
//
|
||||
//void udelay(u32 d)
|
||||
//{
|
||||
// // should be good to max .2% error
|
||||
// u32 ticks = d * 19 / 10;
|
||||
//
|
||||
// if(ticks < 2)
|
||||
// ticks = 2;
|
||||
//
|
||||
// u32 now = *(vu32*)0x0D800010;
|
||||
//
|
||||
// u32 then = now + ticks;
|
||||
//
|
||||
// if(then < now) {
|
||||
// while(*(vu32*)0x0D800010 >= now);
|
||||
// now = *(vu32*)0x0D800010;
|
||||
// }
|
||||
//
|
||||
// while(now < then) {
|
||||
// now = *(vu32*)0x0D800010;
|
||||
// }
|
||||
//}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
unsigned char *us1 = (unsigned char *) s1;
|
||||
unsigned char *us2 = (unsigned char *) s2;
|
||||
while (n-- != 0) {
|
||||
if (*us1 != *us2)
|
||||
return (*us1 < *us2) ? -1 : +1;
|
||||
us1++;
|
||||
us2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
do {
|
||||
if(*s == c)
|
||||
return (char *)s;
|
||||
} while(*s++ != 0);
|
||||
return NULL;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user