From 86950e7cceb33c676ba6093ba20f4d08ae794195 Mon Sep 17 00:00:00 2001 From: LPFaint99 Date: Thu, 15 Sep 2011 14:08:27 -0700 Subject: [PATCH 1/3] fix gcmemcard format broken by 5f9591cf9d0a0c9f87832dad58faa079d4ca7d24 small cleanup to format, now works for slot a and b and any memcard size --- .../DolphinWX/Src/MemoryCards/GCMemcard.cpp | 74 ++++++++++--------- .../DolphinWX/Src/MemoryCards/GCMemcard.h | 4 +- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp index df79e001f2..8e4ba674e2 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp @@ -61,7 +61,10 @@ void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height) } } -GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) : m_valid(false), m_fileName(filename) +GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) + : m_valid(false) + , m_fileName(filename) + , mc_data(NULL) { File::IOFile mcdFile(m_fileName, "r+b"); if (!mcdFile.IsOpen()) @@ -71,10 +74,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) : m_va return; } Format(forceCreation ? sjis : !AskYesNoT("Format as ascii (NTSC\\PAL)?\nChoose no for sjis (NTSC-J)")); - if (!mcdFile.Open(m_fileName, "r+b")) - { - return; - } + return; } else { @@ -1157,20 +1157,15 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) return frames; } -bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly) +bool GCMemcard::Format(bool sjis, int slot, u16 SizeMb) { // Currently only formats cards for slot A - const u32 data_size = BLOCK_SIZE * (SizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS); - + m_sizeMb = SizeMb; + mc_data_size = BLOCK_SIZE * (m_sizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS); + SRAM m_SRAM; - if (New) - { - mc_data_size = data_size; - mc_data = new u8[mc_data_size]; - } - // Only Format 16MB memcards for now - if ((SizeMb != MemCard2043Mb) || (data_size != mc_data_size)) return false; + File::IOFile pStream(File::GetUserPath(F_GCSRAM_IDX), "rb"); if (pStream) @@ -1199,28 +1194,39 @@ bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly) hdr.fmtTime.low = time & 0xFFFFFFFF; *(u32*)&(hdr.SramBias) = m_SRAM.counter_bias; *(u32*)&(hdr.SramLang) = m_SRAM.lang; - *(u32*)&(hdr.Unk2) = Common::swap32(1); // = _viReg[55]; static vu16* const _viReg = (u16*)0xCC002000; - // TODO: find out why memcard cares if component cable used for now set to one like main app + // TODO: determine the purpose of Unk2 1 works for slot A, 0 works for both slot A and slot B + *(u32*)&(hdr.Unk2) = 0; // = _viReg[55]; static vu16* const _viReg = (u16*)0xCC002000; *(u16*)&(hdr.deviceID) = 0; - *(u16*)&(hdr.SizeMb) = Common::swap16(SizeMb); + *(u16*)&(hdr.SizeMb) = Common::swap16(m_sizeMb); *(u16*)&(hdr.Encoding) = Common::swap16(sjis ? 1 : 0); - if (!hdrOnly) - { - memset(&dir, 0xFF, BLOCK_SIZE); - memset(&dir_backup, 0xFF, BLOCK_SIZE); - *(u16*)&dir.UpdateCounter = 0; - *(u16*)&dir_backup.UpdateCounter = Common::swap16(1); - memset(&bat, 0, BLOCK_SIZE); - memset(&bat_backup, 0, BLOCK_SIZE); - *(u16*)&bat.UpdateCounter = 0; - *(u16*)&bat_backup.UpdateCounter = Common::swap16(1); - *(u16*)&bat.FreeBlocks = *(u16*)&bat_backup.FreeBlocks = Common::swap16(SizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS); - *(u16*)&bat.LastAllocated = *(u16*)&bat_backup.LastAllocated = Common::swap16(4); - memset(mc_data, 0xFF, mc_data_size); - } + memset(&dir, 0xFF, BLOCK_SIZE); + memset(&dir_backup, 0xFF, BLOCK_SIZE); + *(u16*)&dir.UpdateCounter = 0; + *(u16*)&dir_backup.UpdateCounter = Common::swap16(1); + + maxBlock = (u32)m_sizeMb * MBIT_TO_BLOCKS; + + memset(&bat, 0, BLOCK_SIZE); + memset(&bat_backup, 0, BLOCK_SIZE); + *(u16*)&bat.UpdateCounter = 0; + *(u16*)&bat_backup.UpdateCounter = Common::swap16(1); + *(u16*)&bat.FreeBlocks = *(u16*)&bat_backup.FreeBlocks = Common::swap16(maxBlock - MC_FST_BLOCKS); + *(u16*)&bat.LastAllocated = *(u16*)&bat_backup.LastAllocated = Common::swap16(4); + + if (mc_data) + { + delete mc_data; + mc_data = NULL; + } + mc_data = new u8[mc_data_size]; + if (!mc_data) + return false; + + memset(mc_data, 0xFF, mc_data_size); + m_valid = true; + FixChecksums(); - Save(); - return true; + return Save(); } diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h index 07ce5656f8..48d0a09b5e 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h @@ -67,7 +67,7 @@ enum CI8, }; -class GCMemcard +class GCMemcard : NonCopyable { private: friend class CMemcardManagerDebug; @@ -175,7 +175,7 @@ public: bool IsValid() { return m_valid; } bool IsAsciiEncoding(); bool Save(); - bool Format(bool sjis = false, bool New = true, int slot = 0, u16 SizeMb = MemCard2043Mb, bool hdrOnly = false); + bool Format(bool sjis = false, int slot = 0, u16 SizeMb = MemCard2043Mb); void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2); u32 TestChecksums(); From 8d91f1e0c1bda8c91e3d4cea1b3c0709950809d0 Mon Sep 17 00:00:00 2001 From: LPFaint99 Date: Thu, 22 Sep 2011 00:05:32 -0700 Subject: [PATCH 2/3] EXI_Memcard: HLE memcard Formatting, GCMemcard: Add static format function, cleanup checksums code --- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp | 9 +- .../DolphinWX/Src/MemoryCards/GCMemcard.cpp | 246 ++++++++---------- .../DolphinWX/Src/MemoryCards/GCMemcard.h | 36 +-- 3 files changed, 134 insertions(+), 157 deletions(-) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index 341a14bec6..dcf6cfb0e0 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -26,6 +26,7 @@ #include "EXI_Device.h" #include "EXI_DeviceMemoryCard.h" #include "Sram.h" +#include "../../DolphinWx/Src/MemoryCards/GCMemcard.h" #define MC_STATUS_BUSY 0x80 #define MC_STATUS_UNLOCKED 0x40 @@ -34,6 +35,7 @@ #define MC_STATUS_PROGRAMEERROR 0x08 #define MC_STATUS_READY 0x01 #define SIZE_TO_Mb (1024 * 8 * 16) +#define MC_HDR_SIZE 0xA000 static CEXIMemoryCard *cards[2]; @@ -84,7 +86,6 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF INFO_LOG(EXPANSIONINTERFACE, "Reading memory card %s", m_strFilename.c_str()); pFile.ReadBytes(memory_card_content, memory_card_size); - SetCardFlashID(memory_card_content, card_index); } else @@ -94,11 +95,11 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF memory_card_size = nintendo_card_id * SIZE_TO_Mb; memory_card_content = new u8[memory_card_size]; - memset(memory_card_content, 0xFF, memory_card_size); - + GCMemcard::Format(memory_card_content, m_strFilename.find(".JAP.raw") != std::string::npos, nintendo_card_id); + memset(memory_card_content+MC_HDR_SIZE, 0xFF, memory_card_size-MC_HDR_SIZE); WARN_LOG(EXPANSIONINTERFACE, "No memory card found. Will create new."); - Flush(); } + SetCardFlashID(memory_card_content, card_index); } void innerFlush(FlushData* data) diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp index 8e4ba674e2..2471e76599 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp @@ -227,7 +227,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) bool GCMemcard::IsAsciiEncoding() { - return hdr.Encoding[1] == 0; + return hdr.Encoding == 0; } bool GCMemcard::Save() @@ -245,51 +245,49 @@ bool GCMemcard::Save() return mcdFile.Close(); } -void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2) +void GCMemcard::calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum) { - *c1 = 0;*c2 = 0; - for (u32 i = 0; i < num; ++i) + *csum = *inv_csum = 0; + + for (u32 i = 0; i < length; ++i) { //weird warnings here - *c1 += Common::swap16(buf[i]); - *c2 += Common::swap16((u16)(buf[i] ^ 0xffff)); + *csum += BE16(buf[i]); + *inv_csum += BE16((u16)(buf[i] ^ 0xffff)); } - if (*c1 == 0xffff) + *csum = BE16(*csum); + *inv_csum = BE16(*inv_csum); + if (*csum == 0xffff) { - *c1 = 0; + *csum = 0; } - if (*c2 == 0xffff) + if (*inv_csum == 0xffff) { - *c2 = 0; + *inv_csum = 0; } } u32 GCMemcard::TestChecksums() { - u16 csum1=0, - csum2=0; + u16 csum=0, + csum_inv=0; u32 results = 0; - calc_checksumsBE((u16*)&hdr, 0xFE , &csum1, &csum2); - if (BE16(hdr.CheckSum1) != csum1) results |= 1; - if (BE16(hdr.CheckSum2) != csum2) results |= 1; + calc_checksumsBE((u16*)&hdr, 0xFE , &csum, &csum_inv); + if ((hdr.Checksum != csum) || (hdr.Checksum_Inv != csum_inv)) results |= 1; - calc_checksumsBE((u16*)&dir, 0xFFE, &csum1, &csum2); - if (BE16(dir.CheckSum1) != csum1) results |= 2; - if (BE16(dir.CheckSum2) != csum2) results |= 2; + calc_checksumsBE((u16*)&dir, 0xFFE, &csum, &csum_inv); + if ((dir.Checksum != csum) || (dir.Checksum_Inv != csum_inv)) results |= 2; - calc_checksumsBE((u16*)&dir_backup, 0xFFE, &csum1, &csum2); - if (BE16(dir_backup.CheckSum1) != csum1) results |= 4; - if (BE16(dir_backup.CheckSum2) != csum2) results |= 4; + calc_checksumsBE((u16*)&dir_backup, 0xFFE, &csum, &csum_inv); + if ((dir_backup.Checksum != csum) || (dir_backup.Checksum_Inv != csum_inv)) results |= 4; - calc_checksumsBE((u16*)(((u8*)&bat)+4), 0xFFE, &csum1, &csum2); - if (BE16(bat.CheckSum1) != csum1) results |= 8; - if (BE16(bat.CheckSum2) != csum2) results |= 8; + calc_checksumsBE((u16*)(((u8*)&bat)+4), 0xFFE, &csum, &csum_inv); + if ((bat.Checksum != csum) || (bat.Checksum_Inv != csum_inv)) results |= 8; - calc_checksumsBE((u16*)(((u8*)&bat_backup)+4), 0xFFE, &csum1, &csum2); - if (BE16(bat_backup.CheckSum1) != csum1) results |= 16; - if (BE16(bat_backup.CheckSum2) != csum2) results |= 16; + calc_checksumsBE((u16*)(((u8*)&bat_backup)+4), 0xFFE, &csum, &csum_inv); + if ((bat_backup.Checksum != csum) || (bat_backup.Checksum_Inv != csum_inv)) results |= 16; return results; } @@ -298,39 +296,12 @@ bool GCMemcard::FixChecksums() { if (!m_valid) return false; - - u16 csum1=0, - csum2=0; - - calc_checksumsBE((u16*)&hdr, 0xFE, &csum1, &csum2); - hdr.CheckSum1[0] = u8(csum1 >> 8); - hdr.CheckSum1[1] = u8(csum1); - hdr.CheckSum2[0] = u8(csum2 >> 8); - hdr.CheckSum2[1] = u8(csum2); - - calc_checksumsBE((u16*)&dir, 0xFFE, &csum1, &csum2); - dir.CheckSum1[0] = u8(csum1 >> 8); - dir.CheckSum1[1] = u8(csum1); - dir.CheckSum2[0] = u8(csum2 >> 8); - dir.CheckSum2[1] = u8(csum2); - - calc_checksumsBE((u16*)&dir_backup, 0xFFE, &csum1, &csum2); - dir_backup.CheckSum1[0] = u8(csum1 >> 8); - dir_backup.CheckSum1[1] = u8(csum1); - dir_backup.CheckSum2[0] = u8(csum2 >> 8); - dir_backup.CheckSum2[1] = u8(csum2); - - calc_checksumsBE((u16*)(((u8*)&bat)+4), 0xFFE, &csum1, &csum2); - bat.CheckSum1[0] = u8(csum1 >> 8); - bat.CheckSum1[1] = u8(csum1); - bat.CheckSum2[0] = u8(csum2 >> 8); - bat.CheckSum2[1] = u8(csum2); - - calc_checksumsBE((u16*)(((u8*)&bat_backup)+4), 0xFFE, &csum1, &csum2); - bat_backup.CheckSum1[0] = u8(csum1 >> 8); - bat_backup.CheckSum1[1] = u8(csum1); - bat_backup.CheckSum2[0] = u8(csum2 >> 8); - bat_backup.CheckSum2[1] = u8(csum2); + + calc_checksumsBE((u16*)&hdr, 0xFE, &hdr.Checksum, &hdr.Checksum_Inv); + calc_checksumsBE((u16*)&dir, 0xFFE, &dir.Checksum, &dir.Checksum_Inv); + calc_checksumsBE((u16*)&dir_backup, 0xFFE, &dir_backup.Checksum, &dir_backup.Checksum_Inv); + calc_checksumsBE((u16*)&bat+2, 0xFFE, &bat.Checksum, &bat.Checksum_Inv); + calc_checksumsBE((u16*)&bat_backup+2, 0xFFE, &bat_backup.Checksum, &bat_backup.Checksum_Inv); return true; } @@ -620,8 +591,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove) { index = i; dir.Dir[i] = direntry; - dir.Dir[i].FirstBlock[0] = u8(firstFree1 >> 8); - dir.Dir[i].FirstBlock[1] = u8(firstFree1); + *(u16*)&dir.Dir[i].FirstBlock = BE16(firstFree1); if (!remove) { dir.Dir[i].CopyCounter = dir.Dir[i].CopyCounter+1; @@ -642,7 +612,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove) int j = 2; while(j < BE16(direntry.BlockCount) + 1) { - bat_backup.Map[i] = Common::swap16(last + (u16)j); + bat_backup.Map[i] = BE16(last + (u16)j); i++; j++; } @@ -654,25 +624,16 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove) } //update last allocated block - int lastallocated = BE16(bat_backup.LastAllocated) + j - 1; - bat_backup.LastAllocated[0] = u8(lastallocated >> 8); - bat_backup.LastAllocated[1] = u8(lastallocated); - + *(u16*)&bat_backup.LastAllocated = BE16(BE16(bat_backup.LastAllocated) + j - 1); //update freespace counter - int freespace1 = totalspace - firstFree1 - fileBlocks + MC_FST_BLOCKS; - bat_backup.FreeBlocks[0] = u8(freespace1 >> 8); - bat_backup.FreeBlocks[1] = u8(freespace1); + *(u16*)&bat_backup.FreeBlocks = BE16(totalspace - firstFree1 - fileBlocks + MC_FST_BLOCKS); if (!remove) { // ... and dir update counter - int updateCtr = BE16(dir_backup.UpdateCounter) + 1; - dir_backup.UpdateCounter[0] = u8(updateCtr >> 8); - dir_backup.UpdateCounter[1] = u8(updateCtr); + *(u16*)&dir_backup.UpdateCounter = BE16(BE16(dir_backup.UpdateCounter) + 1); // ... and bat update counter - updateCtr = BE16(bat_backup.UpdateCounter) + 1; - bat_backup.UpdateCounter[0] = u8(updateCtr >> 8); - bat_backup.UpdateCounter[1] = u8(updateCtr); + *(u16*)&bat_backup.UpdateCounter = BE16(BE16(bat_backup.UpdateCounter) + 1); } bat = bat_backup; return SUCCESS; @@ -698,9 +659,7 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array //free the blocks int blocks_left = BE16(dir.Dir[index].BlockCount); - int block = BE16(dir.Dir[index].FirstBlock) - 1; - bat.LastAllocated[0] = (u8)(block >> 8); - bat.LastAllocated[1] = (u8)block; + *(u16*)&bat.LastAllocated = BE16(BE16(dir.Dir[index].FirstBlock) - 1); u8 nextIndex = index + 1; memset(&(dir.Dir[index]), 0xFF, DENTRY_SIZE); @@ -713,9 +672,7 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array //Only get file data if it is a valid dir entry if (BE16(tempDEntry->FirstBlock) != 0xFFFF) { - u16 freeBlock= BE16(bat.FreeBlocks) - BE16(tempDEntry->BlockCount); - bat.FreeBlocks[0] = u8(freeBlock >> 8); - bat.FreeBlocks[1] = u8(freeBlock); + *(u16*)&bat.FreeBlocks = BE16(BE16(bat.FreeBlocks) - BE16(tempDEntry->BlockCount)); u16 size = DEntry_BlockCount(nextIndex); if (size != 0xFFFF) @@ -754,9 +711,7 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array } } // increment update counter - int updateCtr = BE16(dir.UpdateCounter) + 1; - dir.UpdateCounter[0] = u8(updateCtr >> 8); - dir.UpdateCounter[1] = u8(updateCtr); + *(u16*)&dir.UpdateCounter = BE16(BE16(dir.UpdateCounter) + 1); return SUCCESS; } @@ -989,9 +944,7 @@ void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length) // It is stored only within the corresponding GSV file. // If the GCS file is added without using the GameSaves software, // the value stored is always "1" - int blockCount = length / BLOCK_SIZE; - tempDEntry->BlockCount[0] = u8(blockCount >> 8); - tempDEntry->BlockCount[1] = u8(blockCount); + *(u16*)&tempDEntry->BlockCount = BE16(length / BLOCK_SIZE); } break; case SAV: @@ -1157,69 +1110,55 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) return frames; } -bool GCMemcard::Format(bool sjis, int slot, u16 SizeMb) + +bool GCMemcard::Format(u8 * card_data, bool sjis, u16 SizeMb) { - // Currently only formats cards for slot A - m_sizeMb = SizeMb; - mc_data_size = BLOCK_SIZE * (m_sizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS); - - SRAM m_SRAM; + if (!card_data) + return false; + memset(card_data, 0xFF, BLOCK_SIZE*3); + memset(card_data + BLOCK_SIZE*3, 0, BLOCK_SIZE*2); + GCMC_Header gcp; + gcp.hdr = (Header*)card_data; + gcp.dir = (Directory *)(card_data + BLOCK_SIZE); + gcp.dir_backup = (Directory *)(card_data + BLOCK_SIZE*2); + gcp.bat = (BlockAlloc *)(card_data + BLOCK_SIZE*3); + gcp.bat_backup = (BlockAlloc *)(card_data + BLOCK_SIZE*4); + *(u16*)gcp.hdr->SizeMb = BE16(SizeMb); + *(u16*)gcp.hdr->Encoding = BE16(sjis ? 1 : 0); - File::IOFile pStream(File::GetUserPath(F_GCSRAM_IDX), "rb"); - if (pStream) - { - pStream.ReadBytes(&m_SRAM, 64); - pStream.Close(); - } - else - { - m_SRAM = sram_dump; - } - - const u64 time = CEXIIPL::GetGCTime(); - u64 rand = Common::swap64(time); + FormatInternal(gcp); + return true; +} +bool GCMemcard::Format(bool sjis, u16 SizeMb) +{ memset(&hdr, 0xFF, BLOCK_SIZE); - for(int i = 0; i < 12; i++) - { - rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16); - hdr.serial[i] = (u8)(m_SRAM.flash_id[slot][i] + (u32)rand); - rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16); - rand &= (u64)0x0000000000007fffULL; - } - - hdr.fmtTime.high = (time >> 32) & 0xFFFFFFFF; - hdr.fmtTime.low = time & 0xFFFFFFFF; - *(u32*)&(hdr.SramBias) = m_SRAM.counter_bias; - *(u32*)&(hdr.SramLang) = m_SRAM.lang; - // TODO: determine the purpose of Unk2 1 works for slot A, 0 works for both slot A and slot B - *(u32*)&(hdr.Unk2) = 0; // = _viReg[55]; static vu16* const _viReg = (u16*)0xCC002000; - *(u16*)&(hdr.deviceID) = 0; - *(u16*)&(hdr.SizeMb) = Common::swap16(m_sizeMb); - *(u16*)&(hdr.Encoding) = Common::swap16(sjis ? 1 : 0); - memset(&dir, 0xFF, BLOCK_SIZE); memset(&dir_backup, 0xFF, BLOCK_SIZE); - *(u16*)&dir.UpdateCounter = 0; - *(u16*)&dir_backup.UpdateCounter = Common::swap16(1); - - - maxBlock = (u32)m_sizeMb * MBIT_TO_BLOCKS; - memset(&bat, 0, BLOCK_SIZE); memset(&bat_backup, 0, BLOCK_SIZE); - *(u16*)&bat.UpdateCounter = 0; - *(u16*)&bat_backup.UpdateCounter = Common::swap16(1); - *(u16*)&bat.FreeBlocks = *(u16*)&bat_backup.FreeBlocks = Common::swap16(maxBlock - MC_FST_BLOCKS); - *(u16*)&bat.LastAllocated = *(u16*)&bat_backup.LastAllocated = Common::swap16(4); + GCMC_Header gcp; + gcp.hdr = &hdr; + gcp.dir = &dir; + gcp.dir_backup = &dir_backup; + gcp.bat = &bat; + gcp.bat_backup = &bat_backup; + + *(u16*)hdr.SizeMb = BE16(SizeMb); + *(u16*)hdr.Encoding = BE16(sjis ? 1 : 0); + FormatInternal(gcp); + + m_sizeMb = SizeMb; + maxBlock = (u32)m_sizeMb * MBIT_TO_BLOCKS; if (mc_data) { delete mc_data; mc_data = NULL; } + mc_data_size = BLOCK_SIZE * (m_sizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS); mc_data = new u8[mc_data_size]; if (!mc_data) return false; @@ -1227,6 +1166,41 @@ bool GCMemcard::Format(bool sjis, int slot, u16 SizeMb) memset(mc_data, 0xFF, mc_data_size); m_valid = true; - FixChecksums(); return Save(); } + +void GCMemcard::FormatInternal(GCMC_Header &GCP) +{ + Header *p_hdr = GCP.hdr; + u64 rand = CEXIIPL::GetGCTime(); + p_hdr->formatTime = Common::swap64(rand); + + for(int i = 0; i < 12; i++) + { + rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16); + p_hdr->serial[i] = (u8)(g_SRAM.flash_id[0][i] + (u32)rand); + rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16); + rand &= (u64)0x0000000000007fffULL; + } + *(u32*)&p_hdr->SramBias = g_SRAM.counter_bias; + *(u32*)&p_hdr->SramLang = g_SRAM.lang; + // TODO: determine the purpose of Unk2 1 works for slot A, 0 works for both slot A and slot B + *(u32*)&p_hdr->Unk2 = 0; // = _viReg[55]; static vu16* const _viReg = (u16*)0xCC002000; + *(u16*)&p_hdr->deviceID = 0; + calc_checksumsBE((u16*)p_hdr, 0xFE, &p_hdr->Checksum, &p_hdr->Checksum_Inv); + + Directory *p_dir = GCP.dir, + *p_dir_backup = GCP.dir_backup; + *(u16*)&p_dir->UpdateCounter = 0; + *(u16*)&p_dir_backup->UpdateCounter = BE16(1); + calc_checksumsBE((u16*)p_dir, 0xFFE, &p_dir->Checksum, &p_dir->Checksum_Inv); + calc_checksumsBE((u16*)p_dir_backup, 0xFFE, &p_dir_backup->Checksum, &p_dir_backup->Checksum_Inv); + + BlockAlloc *p_bat = GCP.bat, + *p_bat_backup = GCP.bat_backup; + *(u16*)&p_bat_backup->UpdateCounter = BE16(1); + *(u16*)&p_bat->FreeBlocks = *(u16*)&p_bat_backup->FreeBlocks = BE16(( BE16(p_hdr->SizeMb) * MBIT_TO_BLOCKS) - MC_FST_BLOCKS); + *(u16*)&p_bat->LastAllocated = *(u16*)&p_bat_backup->LastAllocated = BE16(4); + calc_checksumsBE((u16*)p_bat+2, 0xFFE, &p_bat->Checksum, &p_bat->Checksum_Inv); + calc_checksumsBE((u16*)p_bat_backup+2, 0xFFE, &p_bat_backup->Checksum, &p_bat_backup->Checksum_Inv); +} diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h index 48d0a09b5e..c53830034d 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h @@ -23,8 +23,8 @@ #include "StringUtil.h" #include "../../../Core/Src/HW/EXI_DeviceIPL.h" -#define BE32(x) ((u32((x)[0])<<24) | (u32((x)[1])<<16) | (u32((x)[2])<<8) | u32((x)[3])) -#define BE16(x) ((u16((x)[0])<<8) | u16((x)[1])) +#define BE32(x) (Common::swap32(x)) +#define BE16(x) (Common::swap16(x)) #define ArrayByteSwap(a) (ByteSwap(a, a+sizeof(u8))); enum @@ -81,15 +81,10 @@ private: u16 m_sizeMb; #pragma pack(push,1) - struct OSTime { - u32 low; - u32 high; - }; - struct Header { //Offset Size Description // Serial in libogc u8 serial[12]; //0x0000 12 ? - OSTime fmtTime; //0x000c 8 time of format (OSTime value) + u64 formatTime; //0x000c 8 time of format (OSTime value) u8 SramBias[4]; //0x0014 4 sram bias at time of format u8 SramLang[4]; //0x0018 4 sram language u8 Unk2[4]; //0x001c 4 ? almost always 0 @@ -99,8 +94,8 @@ private: u8 Encoding[2]; //0x0024 2 encoding (ASCII or japanese) u8 Unused1[468]; //0x0026 468 unused (0xff) u8 UpdateCounter[2];//0x01fa 2 update Counter (?, probably unused) - u8 CheckSum1[2]; //0x01fc 2 Checksum 1 (?) - u8 CheckSum2[2]; //0x01fe 2 Checksum 2 (?) + u16 Checksum; //0x01fc 2 Additive Checksum + u16 Checksum_Inv; //0x01fe 2 Inverse Checksum u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff) } hdr; @@ -153,31 +148,38 @@ private: DEntry Dir[DIRLEN]; //0x0000 Directory Entries (max 127) u8 Padding[0x3a]; u8 UpdateCounter[2];//0x1ffa 2 update Counter - u8 CheckSum1[2]; //0x1ffc 2 Checksum 1 - u8 CheckSum2[2]; //0x1ffe 2 Checksum 2 + u16 Checksum; //0x1ffc 2 Additive Checksum + u16 Checksum_Inv; //0x1ffe 2 Inverse Checksum } dir, dir_backup; struct BlockAlloc { - u8 CheckSum1[2]; //0x0000 2 Checksum 1 - u8 CheckSum2[2]; //0x0002 2 Checksum 2 + u16 Checksum; //0x0000 2 Additive Checksum + u16 Checksum_Inv; //0x0002 2 Inverse Checksum u8 UpdateCounter[2];//0x0004 2 update Counter u8 FreeBlocks[2]; //0x0006 2 free Blocks u8 LastAllocated[2];//0x0008 2 last allocated Block u16 Map[0xFFB]; //0x000a 0x1ff8 Map of allocated Blocks } bat,bat_backup; + struct GCMC_Header + { + Header *hdr; + Directory *dir, *dir_backup; + BlockAlloc *bat, *bat_backup; + }; #pragma pack(pop) u32 ImportGciInternal(FILE* gcih, const char *inputFile, std::string outputFile); - + static void FormatInternal(GCMC_Header &GCP); public: GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false); bool IsValid() { return m_valid; } bool IsAsciiEncoding(); bool Save(); - bool Format(bool sjis = false, int slot = 0, u16 SizeMb = MemCard2043Mb); + bool Format(bool sjis = false, u16 SizeMb = MemCard2043Mb); + static bool Format(u8 * card_data, bool sjis = false, u16 SizeMb = MemCard2043Mb); - void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2); + static void calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum); u32 TestChecksums(); bool FixChecksums(); From 5316c6d97b75ec8352a379274d2d27c6570941b2 Mon Sep 17 00:00:00 2001 From: LPFaint99 Date: Tue, 4 Oct 2011 10:51:13 -0700 Subject: [PATCH 3/3] Move GCMemcard from DolphinWX/Memorycards to Core/HW --- Source/Core/Core/CMakeLists.txt | 1 + Source/Core/Core/Core.vcxproj | 2 ++ Source/Core/Core/Core.vcxproj.filters | 9 +++++++++ Source/Core/Core/SConscript | 1 + Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp | 2 +- .../Src/MemoryCards => Core/Src/HW}/GCMemcard.cpp | 0 .../Src/MemoryCards => Core/Src/HW}/GCMemcard.h | 4 ++-- Source/Core/DolphinWX/CMakeLists.txt | 1 - Source/Core/DolphinWX/Dolphin.vcxproj | 2 -- Source/Core/DolphinWX/Dolphin.vcxproj.filters | 6 ------ Source/Core/DolphinWX/SConscript | 1 - Source/Core/DolphinWX/Src/ConfigMain.cpp | 2 +- Source/Core/DolphinWX/Src/MemcardManager.h | 2 +- 13 files changed, 18 insertions(+), 15 deletions(-) rename Source/Core/{DolphinWX/Src/MemoryCards => Core/Src/HW}/GCMemcard.cpp (100%) rename Source/Core/{DolphinWX/Src/MemoryCards => Core/Src/HW}/GCMemcard.h (98%) diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index b5e731ce15..734d966781 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -101,6 +101,7 @@ set(SRCS Src/ActionReplay.cpp Src/HW/EXI_DeviceIPL.cpp Src/HW/EXI_DeviceMemoryCard.cpp Src/HW/EXI_DeviceMic.cpp + Src/HW/GCMemcard.cpp Src/HW/GCPad.cpp Src/HW/GCPadEmu.cpp Src/HW/GPFifo.cpp diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index cc6d673f29..b0b72fcc1b 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -287,6 +287,7 @@ + @@ -483,6 +484,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index e51098f2ec..66b25af176 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -553,6 +553,9 @@ FifoPlayer + + HW %28Flipper/Hollywood%29\GCMemcard + @@ -1027,6 +1030,9 @@ FifoPlayer + + HW %28Flipper/Hollywood%29\GCMemcard + @@ -1165,5 +1171,8 @@ {ca7d56f7-4e84-4d15-9aea-7ae6fa7d6586} + + {3e9e6e83-c1bf-45f9-aeff-231f98f60d29} + \ No newline at end of file diff --git a/Source/Core/Core/SConscript b/Source/Core/Core/SConscript index 2f350557ec..3dafad8a62 100644 --- a/Source/Core/Core/SConscript +++ b/Source/Core/Core/SConscript @@ -97,6 +97,7 @@ files = [ 'Src/HW/EXI_DeviceIPL.cpp', 'Src/HW/EXI_DeviceMemoryCard.cpp', 'Src/HW/EXI_DeviceMic.cpp', + 'Src/HW/GCMemcard.cpp', 'Src/HW/GCPad.cpp', 'Src/HW/GCPadEmu.cpp', 'Src/HW/GPFifo.cpp', diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index dcf6cfb0e0..5e3d6865d4 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -26,7 +26,7 @@ #include "EXI_Device.h" #include "EXI_DeviceMemoryCard.h" #include "Sram.h" -#include "../../DolphinWx/Src/MemoryCards/GCMemcard.h" +#include "GCMemcard.h" #define MC_STATUS_BUSY 0x80 #define MC_STATUS_UNLOCKED 0x40 diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp similarity index 100% rename from Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp rename to Source/Core/Core/Src/HW/GCMemcard.cpp diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/Core/Src/HW/GCMemcard.h similarity index 98% rename from Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h rename to Source/Core/Core/Src/HW/GCMemcard.h index c53830034d..5aa0a3c97f 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h +++ b/Source/Core/Core/Src/HW/GCMemcard.h @@ -19,9 +19,9 @@ #define __GCMEMCARD_h__ #include "Common.h" -#include "../../../Core/Src/HW/Sram.h" +#include "Sram.h" #include "StringUtil.h" -#include "../../../Core/Src/HW/EXI_DeviceIPL.h" +#include "EXI_DeviceIPL.h" #define BE32(x) (Common::swap32(x)) #define BE16(x) (Common::swap16(x)) diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt index f38e791cd0..438ee9ce82 100644 --- a/Source/Core/DolphinWX/CMakeLists.txt +++ b/Source/Core/DolphinWX/CMakeLists.txt @@ -52,7 +52,6 @@ if(wxWidgets_FOUND) Src/LogWindow.cpp Src/Main.cpp Src/MemcardManager.cpp - Src/MemoryCards/GCMemcard.cpp Src/MemoryCards/WiiSaveCrypted.cpp Src/NetWindow.cpp Src/PHackSettings.cpp diff --git a/Source/Core/DolphinWX/Dolphin.vcxproj b/Source/Core/DolphinWX/Dolphin.vcxproj index fc232ea77f..2d64eb58bc 100644 --- a/Source/Core/DolphinWX/Dolphin.vcxproj +++ b/Source/Core/DolphinWX/Dolphin.vcxproj @@ -255,7 +255,6 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e / true - @@ -309,7 +308,6 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e / - diff --git a/Source/Core/DolphinWX/Dolphin.vcxproj.filters b/Source/Core/DolphinWX/Dolphin.vcxproj.filters index 3c14226fc0..9c679eee36 100644 --- a/Source/Core/DolphinWX/Dolphin.vcxproj.filters +++ b/Source/Core/DolphinWX/Dolphin.vcxproj.filters @@ -6,9 +6,6 @@ - - GUI\Saves - GUI\Saves @@ -141,9 +138,6 @@ - - GUI\Saves - GUI\Saves diff --git a/Source/Core/DolphinWX/SConscript b/Source/Core/DolphinWX/SConscript index 3d3d1e56c2..92ca4f9f62 100644 --- a/Source/Core/DolphinWX/SConscript +++ b/Source/Core/DolphinWX/SConscript @@ -43,7 +43,6 @@ else: 'Src/LogWindow.cpp', 'Src/Main.cpp', 'Src/MemcardManager.cpp', - 'Src/MemoryCards/GCMemcard.cpp', 'Src/MemoryCards/WiiSaveCrypted.cpp', 'Src/NetWindow.cpp', 'Src/PHackSettings.cpp', diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index 8b2dcb07f6..10472b15eb 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -27,6 +27,7 @@ #include "HW/SI.h" #include "HW/DSPHLE/DSPHLE.h" #include "HW/DSPLLE/DSPLLE.h" +#include "HW/GCMemcard.h" #include "IPC_HLE/WII_IPC_HLE.h" #include "NANDContentLoader.h" @@ -37,7 +38,6 @@ #include "Frame.h" #include "HotkeyDlg.h" #include "Main.h" -#include "MemoryCards/GCMemcard.h" #include "VideoBackendBase.h" #define TEXT_BOX(page, text) new wxStaticText(page, wxID_ANY, text, wxDefaultPosition, wxDefaultSize) diff --git a/Source/Core/DolphinWX/Src/MemcardManager.h b/Source/Core/DolphinWX/Src/MemcardManager.h index e3707f6414..beff71b671 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.h +++ b/Source/Core/DolphinWX/Src/MemcardManager.h @@ -29,7 +29,7 @@ #include "IniFile.h" #include "FileUtil.h" -#include "MemoryCards/GCMemcard.h" +#include "HW/GCMemcard.h" #undef MEMCARD_MANAGER_STYLE #define MEMCARD_MANAGER_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxCLOSE_BOX | wxRESIZE_BORDER | wxMAXIMIZE_BOX