Memcard: Add ECC bytes when converting an ECC-less file card to a folder

MMCE cards such as MemCard PRO and SD2PSX store pages without ECC, so the
source is expanded to raw pages and rejected if it is not a whole number.
This commit is contained in:
shawly
2026-10-07 14:10:14 -04:00
committed by Ty
parent 161a6cd219
commit eb3823ac95
3 changed files with 42 additions and 1 deletions
@@ -118,6 +118,16 @@ bool MemoryCardConvertWorker::ConvertToFolder(const std::string& srcFileName, co
}
std::vector<u8> sourceBuffer = sourceBufferOpt.value();
// MemCard PRO, SD2PSX and other MMCE cards have no ECC bytes
FileMcd_InsertECC(sourceBuffer);
if ((sourceBuffer.size() % FolderMemoryCard::PageSizeRaw) != 0)
{
Console.Error("%s(%s, %s, %d) File Memory Card is not a whole number of pages!", __FUNCTION__, srcFileName.c_str(), destFolderName.c_str(), type);
return false;
}
// Set progress bar to the literal number of bytes in the memcard.
// Plus two because there is a lag period after the Save calls complete
// where the progress bar stalls out; this lets us stop the progress bar
+31 -1
View File
@@ -40,7 +40,7 @@ bool FileMcd_Open = false;
// https://sourceforge.net/p/mymc-opl/code/ci/master/tree/ps2mc_ecc.py
// Public domain license
static u32 CalculateECC(u8* buf)
static u32 CalculateECC(const u8* buf)
{
const u8 parity_table[256] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1,
0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
@@ -889,6 +889,36 @@ bool FileMcd_IsMemoryCardFormatted(std::FILE* fp)
std::memcmp(data, formatted_psx, sizeof(formatted_psx) - 1) == 0);
}
static bool IsNoECCSize(s64 size)
{
return (size == _8mb || size == _16mb || size == _32mb || size == _64mb);
}
bool FileMcd_InsertECC(std::vector<u8>& buffer)
{
if (!IsNoECCSize(static_cast<s64>(buffer.size())))
return false;
const size_t pages = buffer.size() / FolderMemoryCard::PageSize;
std::vector<u8> raw(pages * FolderMemoryCard::PageSizeRaw, 0xff);
for (size_t page = 0; page < pages; page++)
{
const u8* src = &buffer[page * FolderMemoryCard::PageSize];
u8* dst = &raw[page * FolderMemoryCard::PageSizeRaw];
std::memcpy(dst, src, FolderMemoryCard::PageSize);
for (int j = 0; j < 4; j++)
{
const u32 checksum = CalculateECC(&src[j * 128]);
std::memcpy(&dst[FolderMemoryCard::PageSize + (j * 3)], &checksum, 3);
}
}
buffer = std::move(raw);
return true;
}
std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards)
{
std::vector<FILESYSTEM_FIND_DATA> files;
+1
View File
@@ -57,6 +57,7 @@ std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_card
std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view name);
bool FileMcd_IsMemoryCardFormatted(const std::string& path);
bool FileMcd_IsMemoryCardFormatted(std::FILE* fp);
bool FileMcd_InsertECC(std::vector<u8>& buffer);
bool FileMcd_CreateNewCard(const std::string_view name, MemoryCardType type, MemoryCardFileType file_type);
bool FileMcd_RenameCard(const std::string_view name, const std::string_view new_name);
bool FileMcd_DeleteCard(const std::string_view name);