GCMemcard: As far as I can tell, the directory and BAT blocks aren't really main and backup, but just two blocks that store data are written to alternately. So store them as an std::array of 2 blocks instead of an explicit 'backup' block.
This commit is contained in:
parent
0aaf24b9cc
commit
7ff65db3b2
|
@ -99,25 +99,25 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mcdFile.ReadBytes(&m_directory_block, BLOCK_SIZE))
|
if (!mcdFile.ReadBytes(&m_directory_blocks[0], BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
PanicAlertT("Failed to read directory correctly\n(0x2000-0x3FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mcdFile.ReadBytes(&m_directory_backup_block, BLOCK_SIZE))
|
if (!mcdFile.ReadBytes(&m_directory_blocks[1], BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
PanicAlertT("Failed to read directory backup correctly\n(0x4000-0x5FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mcdFile.ReadBytes(&m_bat_block, BLOCK_SIZE))
|
if (!mcdFile.ReadBytes(&m_bat_blocks[0], BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
PanicAlertT("Failed to read block allocation table correctly\n(0x6000-0x7FFF)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mcdFile.ReadBytes(&m_bat_backup_block, BLOCK_SIZE))
|
if (!mcdFile.ReadBytes(&m_bat_blocks[1], BLOCK_SIZE))
|
||||||
{
|
{
|
||||||
PanicAlertT("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
PanicAlertT("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)");
|
||||||
return;
|
return;
|
||||||
|
@ -144,8 +144,8 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// backup is correct, restore
|
// backup is correct, restore
|
||||||
m_directory_block = m_directory_backup_block;
|
m_directory_blocks[0] = m_directory_blocks[1];
|
||||||
m_bat_block = m_bat_backup_block;
|
m_bat_blocks[0] = m_bat_blocks[1];
|
||||||
|
|
||||||
// update checksums
|
// update checksums
|
||||||
csums = TestChecksums();
|
csums = TestChecksums();
|
||||||
|
@ -163,8 +163,8 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// backup is correct, restore
|
// backup is correct, restore
|
||||||
m_directory_block = m_directory_backup_block;
|
m_directory_blocks[0] = m_directory_blocks[1];
|
||||||
m_bat_block = m_bat_backup_block;
|
m_bat_blocks[0] = m_bat_blocks[1];
|
||||||
|
|
||||||
// update checksums
|
// update checksums
|
||||||
csums = TestChecksums();
|
csums = TestChecksums();
|
||||||
|
@ -209,25 +209,25 @@ GCMemcard::GCMemcard(const std::string& filename, bool forceCreation, bool shift
|
||||||
|
|
||||||
void GCMemcard::InitDirBatPointers()
|
void GCMemcard::InitDirBatPointers()
|
||||||
{
|
{
|
||||||
if (m_directory_block.m_update_counter > m_directory_backup_block.m_update_counter)
|
if (m_directory_blocks[0].m_update_counter > m_directory_blocks[1].m_update_counter)
|
||||||
{
|
{
|
||||||
m_current_directory_block = &m_directory_block;
|
m_current_directory_block = &m_directory_blocks[0];
|
||||||
m_previous_directory_block = &m_directory_backup_block;
|
m_previous_directory_block = &m_directory_blocks[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_current_directory_block = &m_directory_backup_block;
|
m_current_directory_block = &m_directory_blocks[1];
|
||||||
m_previous_directory_block = &m_directory_block;
|
m_previous_directory_block = &m_directory_blocks[0];
|
||||||
}
|
}
|
||||||
if (m_bat_block.m_update_counter > m_bat_backup_block.m_update_counter)
|
if (m_bat_blocks[0].m_update_counter > m_bat_blocks[1].m_update_counter)
|
||||||
{
|
{
|
||||||
m_current_bat_block = &m_bat_block;
|
m_current_bat_block = &m_bat_blocks[0];
|
||||||
m_previous_bat_block = &m_bat_backup_block;
|
m_previous_bat_block = &m_bat_blocks[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_current_bat_block = &m_bat_backup_block;
|
m_current_bat_block = &m_bat_blocks[1];
|
||||||
m_previous_bat_block = &m_bat_block;
|
m_previous_bat_block = &m_bat_blocks[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,10 +242,10 @@ bool GCMemcard::Save()
|
||||||
mcdFile.Seek(0, SEEK_SET);
|
mcdFile.Seek(0, SEEK_SET);
|
||||||
|
|
||||||
mcdFile.WriteBytes(&m_header_block, BLOCK_SIZE);
|
mcdFile.WriteBytes(&m_header_block, BLOCK_SIZE);
|
||||||
mcdFile.WriteBytes(&m_directory_block, BLOCK_SIZE);
|
mcdFile.WriteBytes(&m_directory_blocks[0], BLOCK_SIZE);
|
||||||
mcdFile.WriteBytes(&m_directory_backup_block, BLOCK_SIZE);
|
mcdFile.WriteBytes(&m_directory_blocks[1], BLOCK_SIZE);
|
||||||
mcdFile.WriteBytes(&m_bat_block, BLOCK_SIZE);
|
mcdFile.WriteBytes(&m_bat_blocks[0], BLOCK_SIZE);
|
||||||
mcdFile.WriteBytes(&m_bat_backup_block, BLOCK_SIZE);
|
mcdFile.WriteBytes(&m_bat_blocks[1], BLOCK_SIZE);
|
||||||
for (unsigned int i = 0; i < m_size_blocks - MC_FST_BLOCKS; ++i)
|
for (unsigned int i = 0; i < m_size_blocks - MC_FST_BLOCKS; ++i)
|
||||||
{
|
{
|
||||||
mcdFile.WriteBytes(m_data_blocks[i].block, BLOCK_SIZE);
|
mcdFile.WriteBytes(m_data_blocks[i].block, BLOCK_SIZE);
|
||||||
|
@ -286,21 +286,22 @@ u32 GCMemcard::TestChecksums() const
|
||||||
if ((m_header_block.m_checksum != csum) || (m_header_block.m_checksum_inv != csum_inv))
|
if ((m_header_block.m_checksum != csum) || (m_header_block.m_checksum_inv != csum_inv))
|
||||||
results |= 1;
|
results |= 1;
|
||||||
|
|
||||||
calc_checksumsBE((u16*)&m_directory_block, 0xFFE, &csum, &csum_inv);
|
calc_checksumsBE((u16*)&m_directory_blocks[0], 0xFFE, &csum, &csum_inv);
|
||||||
if ((m_directory_block.m_checksum != csum) || (m_directory_block.m_checksum_inv != csum_inv))
|
if ((m_directory_blocks[0].m_checksum != csum) ||
|
||||||
|
(m_directory_blocks[0].m_checksum_inv != csum_inv))
|
||||||
results |= 2;
|
results |= 2;
|
||||||
|
|
||||||
calc_checksumsBE((u16*)&m_directory_backup_block, 0xFFE, &csum, &csum_inv);
|
calc_checksumsBE((u16*)&m_directory_blocks[1], 0xFFE, &csum, &csum_inv);
|
||||||
if ((m_directory_backup_block.m_checksum != csum) ||
|
if ((m_directory_blocks[1].m_checksum != csum) ||
|
||||||
(m_directory_backup_block.m_checksum_inv != csum_inv))
|
(m_directory_blocks[1].m_checksum_inv != csum_inv))
|
||||||
results |= 4;
|
results |= 4;
|
||||||
|
|
||||||
calc_checksumsBE((u16*)(((u8*)&m_bat_block) + 4), 0xFFE, &csum, &csum_inv);
|
calc_checksumsBE((u16*)(((u8*)&m_bat_blocks[0]) + 4), 0xFFE, &csum, &csum_inv);
|
||||||
if ((m_bat_block.m_checksum != csum) || (m_bat_block.m_checksum_inv != csum_inv))
|
if ((m_bat_blocks[0].m_checksum != csum) || (m_bat_blocks[0].m_checksum_inv != csum_inv))
|
||||||
results |= 8;
|
results |= 8;
|
||||||
|
|
||||||
calc_checksumsBE((u16*)(((u8*)&m_bat_backup_block) + 4), 0xFFE, &csum, &csum_inv);
|
calc_checksumsBE((u16*)(((u8*)&m_bat_blocks[1]) + 4), 0xFFE, &csum, &csum_inv);
|
||||||
if ((m_bat_backup_block.m_checksum != csum) || (m_bat_backup_block.m_checksum_inv != csum_inv))
|
if ((m_bat_blocks[1].m_checksum != csum) || (m_bat_blocks[1].m_checksum_inv != csum_inv))
|
||||||
results |= 16;
|
results |= 16;
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
|
@ -313,14 +314,14 @@ bool GCMemcard::FixChecksums()
|
||||||
|
|
||||||
calc_checksumsBE((u16*)&m_header_block, 0xFE, &m_header_block.m_checksum,
|
calc_checksumsBE((u16*)&m_header_block, 0xFE, &m_header_block.m_checksum,
|
||||||
&m_header_block.m_checksum_inv);
|
&m_header_block.m_checksum_inv);
|
||||||
calc_checksumsBE((u16*)&m_directory_block, 0xFFE, &m_directory_block.m_checksum,
|
calc_checksumsBE((u16*)&m_directory_blocks[0], 0xFFE, &m_directory_blocks[0].m_checksum,
|
||||||
&m_directory_block.m_checksum_inv);
|
&m_directory_blocks[0].m_checksum_inv);
|
||||||
calc_checksumsBE((u16*)&m_directory_backup_block, 0xFFE, &m_directory_backup_block.m_checksum,
|
calc_checksumsBE((u16*)&m_directory_blocks[1], 0xFFE, &m_directory_blocks[1].m_checksum,
|
||||||
&m_directory_backup_block.m_checksum_inv);
|
&m_directory_blocks[1].m_checksum_inv);
|
||||||
calc_checksumsBE((u16*)&m_bat_block + 2, 0xFFE, &m_bat_block.m_checksum,
|
calc_checksumsBE((u16*)&m_bat_blocks[0] + 2, 0xFFE, &m_bat_blocks[0].m_checksum,
|
||||||
&m_bat_block.m_checksum_inv);
|
&m_bat_blocks[0].m_checksum_inv);
|
||||||
calc_checksumsBE((u16*)&m_bat_backup_block + 2, 0xFFE, &m_bat_backup_block.m_checksum,
|
calc_checksumsBE((u16*)&m_bat_blocks[1] + 2, 0xFFE, &m_bat_blocks[1].m_checksum,
|
||||||
&m_bat_backup_block.m_checksum_inv);
|
&m_bat_blocks[1].m_checksum_inv);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -701,15 +702,15 @@ u32 GCMemcard::ImportFile(const DEntry& direntry, std::vector<GCMBlock>& saveBlo
|
||||||
}
|
}
|
||||||
UpdatedDir.m_update_counter = UpdatedDir.m_update_counter + 1;
|
UpdatedDir.m_update_counter = UpdatedDir.m_update_counter + 1;
|
||||||
*m_previous_directory_block = UpdatedDir;
|
*m_previous_directory_block = UpdatedDir;
|
||||||
if (m_previous_directory_block == &m_directory_block)
|
if (m_previous_directory_block == &m_directory_blocks[0])
|
||||||
{
|
{
|
||||||
m_current_directory_block = &m_directory_block;
|
m_current_directory_block = &m_directory_blocks[0];
|
||||||
m_previous_directory_block = &m_directory_backup_block;
|
m_previous_directory_block = &m_directory_blocks[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_current_directory_block = &m_directory_backup_block;
|
m_current_directory_block = &m_directory_blocks[1];
|
||||||
m_previous_directory_block = &m_directory_block;
|
m_previous_directory_block = &m_directory_blocks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int fileBlocks = direntry.m_block_count;
|
int fileBlocks = direntry.m_block_count;
|
||||||
|
@ -737,15 +738,15 @@ u32 GCMemcard::ImportFile(const DEntry& direntry, std::vector<GCMBlock>& saveBlo
|
||||||
UpdatedBat.m_free_blocks = UpdatedBat.m_free_blocks - fileBlocks;
|
UpdatedBat.m_free_blocks = UpdatedBat.m_free_blocks - fileBlocks;
|
||||||
UpdatedBat.m_update_counter = UpdatedBat.m_update_counter + 1;
|
UpdatedBat.m_update_counter = UpdatedBat.m_update_counter + 1;
|
||||||
*m_previous_bat_block = UpdatedBat;
|
*m_previous_bat_block = UpdatedBat;
|
||||||
if (m_previous_bat_block == &m_bat_block)
|
if (m_previous_bat_block == &m_bat_blocks[0])
|
||||||
{
|
{
|
||||||
m_current_bat_block = &m_bat_block;
|
m_current_bat_block = &m_bat_blocks[0];
|
||||||
m_previous_bat_block = &m_bat_backup_block;
|
m_previous_bat_block = &m_bat_blocks[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_current_bat_block = &m_bat_backup_block;
|
m_current_bat_block = &m_bat_blocks[1];
|
||||||
m_previous_bat_block = &m_bat_block;
|
m_previous_bat_block = &m_bat_blocks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
FixChecksums();
|
FixChecksums();
|
||||||
|
@ -768,15 +769,15 @@ u32 GCMemcard::RemoveFile(u8 index) // index in the directory array
|
||||||
return DELETE_FAIL;
|
return DELETE_FAIL;
|
||||||
UpdatedBat.m_update_counter = UpdatedBat.m_update_counter + 1;
|
UpdatedBat.m_update_counter = UpdatedBat.m_update_counter + 1;
|
||||||
*m_previous_bat_block = UpdatedBat;
|
*m_previous_bat_block = UpdatedBat;
|
||||||
if (m_previous_bat_block == &m_bat_block)
|
if (m_previous_bat_block == &m_bat_blocks[0])
|
||||||
{
|
{
|
||||||
m_current_bat_block = &m_bat_block;
|
m_current_bat_block = &m_bat_blocks[0];
|
||||||
m_previous_bat_block = &m_bat_backup_block;
|
m_previous_bat_block = &m_bat_blocks[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_current_bat_block = &m_bat_backup_block;
|
m_current_bat_block = &m_bat_blocks[1];
|
||||||
m_previous_bat_block = &m_bat_block;
|
m_previous_bat_block = &m_bat_blocks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory UpdatedDir = *m_current_directory_block;
|
Directory UpdatedDir = *m_current_directory_block;
|
||||||
|
@ -804,15 +805,15 @@ u32 GCMemcard::RemoveFile(u8 index) // index in the directory array
|
||||||
memset(&(UpdatedDir.m_dir_entries[index]), 0xFF, DENTRY_SIZE);
|
memset(&(UpdatedDir.m_dir_entries[index]), 0xFF, DENTRY_SIZE);
|
||||||
UpdatedDir.m_update_counter = UpdatedDir.m_update_counter + 1;
|
UpdatedDir.m_update_counter = UpdatedDir.m_update_counter + 1;
|
||||||
*m_previous_directory_block = UpdatedDir;
|
*m_previous_directory_block = UpdatedDir;
|
||||||
if (m_previous_directory_block == &m_directory_block)
|
if (m_previous_directory_block == &m_directory_blocks[0])
|
||||||
{
|
{
|
||||||
m_current_directory_block = &m_directory_block;
|
m_current_directory_block = &m_directory_blocks[0];
|
||||||
m_previous_directory_block = &m_directory_backup_block;
|
m_previous_directory_block = &m_directory_blocks[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_current_directory_block = &m_directory_backup_block;
|
m_current_directory_block = &m_directory_blocks[1];
|
||||||
m_previous_directory_block = &m_directory_block;
|
m_previous_directory_block = &m_directory_blocks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
FixChecksums();
|
FixChecksums();
|
||||||
|
@ -1289,14 +1290,14 @@ bool GCMemcard::Format(u8* card_data, bool shift_jis, u16 SizeMb)
|
||||||
bool GCMemcard::Format(bool shift_jis, u16 SizeMb)
|
bool GCMemcard::Format(bool shift_jis, u16 SizeMb)
|
||||||
{
|
{
|
||||||
memset(&m_header_block, 0xFF, BLOCK_SIZE);
|
memset(&m_header_block, 0xFF, BLOCK_SIZE);
|
||||||
memset(&m_directory_block, 0xFF, BLOCK_SIZE);
|
memset(&m_directory_blocks[0], 0xFF, BLOCK_SIZE);
|
||||||
memset(&m_directory_backup_block, 0xFF, BLOCK_SIZE);
|
memset(&m_directory_blocks[1], 0xFF, BLOCK_SIZE);
|
||||||
memset(&m_bat_block, 0, BLOCK_SIZE);
|
memset(&m_bat_blocks[0], 0, BLOCK_SIZE);
|
||||||
memset(&m_bat_backup_block, 0, BLOCK_SIZE);
|
memset(&m_bat_blocks[1], 0, BLOCK_SIZE);
|
||||||
|
|
||||||
m_header_block = Header(SLOT_A, SizeMb, shift_jis);
|
m_header_block = Header(SLOT_A, SizeMb, shift_jis);
|
||||||
m_directory_block = m_directory_backup_block = Directory();
|
m_directory_blocks[0] = m_directory_blocks[1] = Directory();
|
||||||
m_bat_block = m_bat_backup_block = BlockAlloc(SizeMb);
|
m_bat_blocks[0] = m_bat_blocks[1] = BlockAlloc(SizeMb);
|
||||||
|
|
||||||
m_size_mb = SizeMb;
|
m_size_mb = SizeMb;
|
||||||
m_size_blocks = (u32)m_size_mb * MBIT_TO_BLOCKS;
|
m_size_blocks = (u32)m_size_mb * MBIT_TO_BLOCKS;
|
||||||
|
|
|
@ -330,10 +330,8 @@ private:
|
||||||
u16 m_size_mb;
|
u16 m_size_mb;
|
||||||
|
|
||||||
Header m_header_block;
|
Header m_header_block;
|
||||||
Directory m_directory_block;
|
std::array<Directory, 2> m_directory_blocks;
|
||||||
Directory m_directory_backup_block;
|
std::array<BlockAlloc, 2> m_bat_blocks;
|
||||||
BlockAlloc m_bat_block;
|
|
||||||
BlockAlloc m_bat_backup_block;
|
|
||||||
std::vector<GCMBlock> m_data_blocks;
|
std::vector<GCMBlock> m_data_blocks;
|
||||||
|
|
||||||
Directory* m_current_directory_block;
|
Directory* m_current_directory_block;
|
||||||
|
|
Loading…
Reference in New Issue