diosmios/Card.c

917 lines
21 KiB
C

#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 );
}
}