Completed support for various MemoryCard sizes (16, 32, 64 megs cards).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3084 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-05-26 19:45:33 +00:00
parent 2a5a0b36c8
commit 74a4ecd559
10 changed files with 115 additions and 28 deletions

View File

@ -1013,6 +1013,17 @@ typedef struct _PS2E_ComponentAPI_GS
} PS2E_ComponentAPI_GS;
// --------------------------------------------------------------------------------------
// PS2E_McdSizeInfo
// --------------------------------------------------------------------------------------
struct PS2E_McdSizeInfo
{
u16 SectorSize; // Size of each sector, in bytes. (only 512 and 1024 are valid)
u16 EraseBlockSizeInSectors; // Size of the erase block, in sectors (max is 16)
u32 McdSizeInSectors; // Total size of the card, in sectors (no upper limit)
};
// --------------------------------------------------------------------------------------
// PS2E_ComponentAPI_Mcd
// --------------------------------------------------------------------------------------
@ -1037,6 +1048,16 @@ typedef struct _PS2E_ComponentAPI_Mcd
//
BOOL (PS2E_CALLBACK* McdIsPresent)( PS2E_THISPTR thisptr, uint port, uint slot );
// McdGetSectorSize (can be NULL)
// Requests memorycard formatting information from the Mcd provider. See the description of
// PS2E_McdSizeInfo for details on each field. If the Mcd provider supports only standard 8MB
// carts, then this function can be NULL.
//
// Returns:
// Assigned values for memorycard sector size and sector count in 'outways.'
//
void (PS2E_CALLBACK* McdGetSizeInfo)( PS2E_THISPTR thisptr, uint port, uint slot, PS2E_McdSizeInfo* outways );
// McdRead
// Requests that a block of data be loaded from the memorycard into the specified dest
// buffer (which is allocated by the caller). Bytes read should match the requested

View File

@ -36,6 +36,12 @@ bool SysPluginBindings::McdIsPresent( uint port, uint slot )
return !!Mcd->McdIsPresent( (PS2E_THISPTR) Mcd, port, slot );
}
void SysPluginBindings::McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo& outways )
{
if( Mcd->McdGetSizeInfo )
Mcd->McdGetSizeInfo( (PS2E_THISPTR) Mcd, port, slot, &outways );
}
void SysPluginBindings::McdRead( uint port, uint slot, u8 *dest, u32 adr, int size )
{
Mcd->McdRead( (PS2E_THISPTR) Mcd, port, slot, dest, adr, size );

View File

@ -214,6 +214,7 @@ public:
}
bool McdIsPresent( uint port, uint slot );
void McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo& outways );
void McdRead( uint port, uint slot, u8 *dest, u32 adr, int size );
void McdSave( uint port, uint slot, const u8 *src, u32 adr, int size );
void McdEraseBlock( uint port, uint slot, u32 adr );

View File

@ -23,8 +23,9 @@ _sio sio;
static const u8 cardh[4] = { 0xFF, 0xFF, 0x5a, 0x5d };
// Memory Card Specs : Sector size etc.
static const mc_command_0x26_tag mc_command_0x26= {'+', 512, 16, 0x4000, 0x52, 0x5A};
// Memory Card Specs for standard Sony 8mb carts:
// Flags (magic sio '+' thingie!), Sector size, eraseBlockSize (in pages), card size (in pages), xor checksum (superblock?), terminator (unused?).
static const mc_command_0x26_tag mc_sizeinfo_8mb= {'+', 512, 16, 0x4000, 0x52, 0x5A};
// Ejection timeout management belongs in the MemoryCardFile plugin, except the plugin
// interface is not yet complete.
@ -78,13 +79,15 @@ static void _EraseMCDBlock(u32 adr)
static u8 sio_xor( const u8 *buf, uint length )
{
u8 i, x;
for (x=0, i=0; i<length; i++) x ^= buf[i];
return x;
}
for (x=0, i=0; i<length; i++) x ^= buf[i];
return x & 0xFF;
/*u8 x = 0;
for( uint i=0; i<length; ++i) { x ^= buf[i]; }
return x;*/
template< typename T >
static void apply_xor( u8& dest, const T& src )
{
u8* buf = (u8*)&src;
for (uint x=0; x<sizeof(src); x++) dest ^= buf[x];
}
void sioInit()
@ -220,13 +223,47 @@ void SIO_CommandWrite(u8 value,int way) {
case 0x25:
MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break;
case 0x26:
{
const uint port = sio.GetMemcardIndex();
const uint slot = sio.activeMemcardSlot[port];
mc_command_0x26_tag cmd = mc_sizeinfo_8mb;
PS2E_McdSizeInfo info;
info.SectorSize = cmd.sectorSize;
info.EraseBlockSizeInSectors = cmd.eraseBlocks;
info.McdSizeInSectors = cmd.mcdSizeInSectors;
SysPlugins.McdGetSizeInfo( port, slot, info );
pxAssumeDev( cmd.mcdSizeInSectors >= mc_sizeinfo_8mb.mcdSizeInSectors,
"Mcd plugin returned an invalid memorycard size: Cards smaller than 8MB are not supported." );
cmd.sectorSize = info.SectorSize;
cmd.eraseBlocks = info.EraseBlockSizeInSectors;
cmd.mcdSizeInSectors = info.McdSizeInSectors;
// Recalculate the xor summation
// This uses a trick of removing the known xor values for a default 8mb memorycard (for which the XOR
// was calculated), and replacing it with our new values.
apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.sectorSize );
apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.eraseBlocks );
apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.mcdSizeInSectors );
apply_xor( cmd.mc_xor, cmd.sectorSize );
apply_xor( cmd.mc_xor, cmd.eraseBlocks );
apply_xor( cmd.mc_xor, cmd.mcdSizeInSectors );
sio.bufcount = 12; sio.mcdst = 99; sio2.packet.recvVal3 = 0x83;
memset8<0xff>(sio.buf);
memcpy(&sio.buf[2], &mc_command_0x26, sizeof(mc_command_0x26));
memcpy_fast(&sio.buf[2], &cmd, sizeof(cmd));
sio.buf[12]=sio.terminator;
MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value);
break;
}
break;
case 0x27:
case 0x28:
case 0xBF:
@ -239,8 +276,6 @@ void SIO_CommandWrite(u8 value,int way) {
case 0x42: // WRITE
case 0x43: // READ
case 0x82:
// fixme: THEORY! Clearing either sio.sector or sio.lastsector when loading from
// savestate may safely invalidate games' memorycard caches! -- air
if(value==0x82 && sio.lastsector==sio.sector) sio.mode = 2;
if(value==0x42) sio.mode = 0;
if(value==0x43) sio.lastsector = sio.sector; // Reading

View File

@ -87,7 +87,7 @@ static bool HandlePluginError( Exception::BaseException& ex )
// TODO: Send a message to the panel to select the failed plugin.
return AppOpenModalDialog<Dialogs::SysConfigDialog>() != wxID_CANCEL;
return AppOpenModalDialog<Dialogs::ComponentsConfigDialog>() != wxID_CANCEL;
}
class PluginErrorEvent : public pxExceptionEvent

View File

@ -61,11 +61,12 @@ public:
void Open();
void Close();
s32 IsPresent ( uint slot );
s32 Read ( uint slot, u8 *dest, u32 adr, int size );
s32 Save ( uint slot, const u8 *src, u32 adr, int size );
s32 EraseBlock ( uint slot, u32 adr );
u64 GetCRC ( uint slot );
s32 IsPresent ( uint slot );
void GetSizeInfo( uint slot, PS2E_McdSizeInfo& outways );
s32 Read ( uint slot, u8 *dest, u32 adr, int size );
s32 Save ( uint slot, const u8 *src, u32 adr, int size );
s32 EraseBlock ( uint slot, u32 adr );
u64 GetCRC ( uint slot );
protected:
bool Seek( wxFFile& f, u32 adr );
@ -253,6 +254,17 @@ s32 FileMemoryCard::IsPresent( uint slot )
return m_file[slot].IsOpened();
}
void FileMemoryCard::GetSizeInfo( uint slot, PS2E_McdSizeInfo& outways )
{
outways.SectorSize = 512;
outways.EraseBlockSizeInSectors = 16;
if( pxAssert( m_file[slot].IsOpened() ) )
outways.McdSizeInSectors = m_file[slot].Length() / (outways.SectorSize + outways.EraseBlockSizeInSectors);
else
outways.McdSizeInSectors = 0x4000;
}
s32 FileMemoryCard::Read( uint slot, u8 *dest, u32 adr, int size )
{
wxFFile& mcfp( m_file[slot] );
@ -359,6 +371,11 @@ static s32 PS2E_CALLBACK FileMcd_IsPresent( PS2E_THISPTR thisptr, uint port, uin
return thisptr->impl.IsPresent( FileMcd_ConvertToSlot( port, slot ) );
}
static void PS2E_CALLBACK FileMcd_GetSizeInfo( PS2E_THISPTR thisptr, uint port, uint slot, PS2E_McdSizeInfo* outways )
{
thisptr->impl.GetSizeInfo( FileMcd_ConvertToSlot( port, slot ), *outways );
}
static s32 PS2E_CALLBACK FileMcd_Read( PS2E_THISPTR thisptr, uint port, uint slot, u8 *dest, u32 adr, int size )
{
return thisptr->impl.Read( FileMcd_ConvertToSlot( port, slot ), dest, adr, size );
@ -387,6 +404,7 @@ Component_FileMcd::Component_FileMcd()
api.Base.EmuClose = FileMcd_EmuClose;
api.McdIsPresent = FileMcd_IsPresent;
api.McdGetSizeInfo = FileMcd_GetSizeInfo;
api.McdRead = FileMcd_Read;
api.McdSave = FileMcd_Save;
api.McdEraseBlock = FileMcd_EraseBlock;

View File

@ -547,6 +547,8 @@ void Panels::MemoryCardListPanel_Simple::DoRefresh()
void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
{
ScopedCoreThreadClose closed_core;
const int sel = m_listview->GetFirstSelected();
if( wxNOT_FOUND == sel ) return;
const uint slot = sel;
@ -574,9 +576,13 @@ void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
}
}
else
Dialogs::CreateMemoryCardDialog( this, slot, m_FolderPicker->GetPath() ).ShowModal();
{
wxWindowID result = Dialogs::CreateMemoryCardDialog( this, slot, m_FolderPicker->GetPath() ).ShowModal();
m_Cards[slot].IsEnabled = (result != wxID_CANCEL);
}
RefreshSelections();
closed_core.AllowResume();
}
/*void Panels::MemoryCardListPanel_Simple::OnSwapPorts(wxCommandEvent& evt)

View File

@ -119,7 +119,7 @@ wxListItemAttr* MemoryCardListView_Simple::OnGetItemAttr(long item) const
m_ItemAttr = wxListItemAttr(); // Wipe it clean!
if( !it.IsEnabled )
if( !it.IsPresent )
m_ItemAttr.SetTextColour( *wxLIGHT_GREY );
if( m_TargetedItem == item )

View File

@ -225,10 +225,10 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
DefEnableSizer += m_check_Enable | StdSpace().Align( wxALIGN_RIGHT );
*eeSliderPanel += m_slider_eecycle | sliderFlags;
*eeSliderPanel += m_msg_eecycle;
*eeSliderPanel += m_msg_eecycle | sliderFlags;
*vuSliderPanel += m_slider_vustealer | sliderFlags;
*vuSliderPanel += m_msg_vustealer;
*vuSliderPanel += m_msg_vustealer | sliderFlags;
*vuHacksPanel += m_check_vuFlagHack;
*vuHacksPanel += m_check_vuMinMax;

View File

@ -45,12 +45,12 @@ static const int
#pragma pack(1)
#endif
struct mc_command_0x26_tag{
u8 field_151; //+02 flags
u16 sectorSize; //+03 divide to it
u16 field_2C; //+05 divide to it
u32 mc_size; //+07
u8 mc_xor; //+0b don't forget to recalculate it!!!
u8 Z; //+0c
u8 field_151; //+02 flags
u16 sectorSize; //+03 Size of each sector(page), in bytes.
u16 eraseBlocks; //+05 Number of sectors in the erase block
u32 mcdSizeInSectors; //+07 card size in sectors (pages).
u8 mc_xor; //+0b XOR Checksum of the superblock? (minus format ident and version?)
u8 Z; //+0c terminator? Appears to be overwritten/unused.
#ifdef _MSC_VER
};
#pragma pack()