mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
2a5a0b36c8
commit
74a4ecd559
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue