diff --git a/Source/Core/Core/Src/HW/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp index 7423f9ca24..5ba0c2aaa6 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.cpp +++ b/Source/Core/Core/Src/HW/GCMemcard.cpp @@ -573,9 +573,16 @@ u16 GCMemcard::BlockAlloc::GetNextBlock(u16 Block) const u16 GCMemcard::BlockAlloc::NextFreeBlock(u16 StartingBlock) const { - for (u16 i = StartingBlock; i < BAT_SIZE; ++i) - if (Map[i-MC_FST_BLOCKS] == 0) - return i; + if (FreeBlocks) + { + for (u16 i = StartingBlock; i < BAT_SIZE; ++i) + if (Map[i-MC_FST_BLOCKS] == 0) + return i; + for (u16 i = 0; i < StartingBlock; ++i) + if (Map[i-MC_FST_BLOCKS] == 0) + return i; + } + return 0xFFFF; } bool GCMemcard::BlockAlloc::ClearBlocks(u16 FirstBlock, u16 BlockCount) @@ -647,8 +654,9 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector &saveBlocks) } // find first free data block - u16 firstBlock = CurrentBat->NextFreeBlock(); - + u16 firstBlock = CurrentBat->NextFreeBlock(BE16(CurrentBat->LastAllocated)); + if (firstBlock == 0xFFFF) + return OUTOFBLOCKS; Directory UpdatedDir = *CurrentDir; // find first free dir entry @@ -685,14 +693,18 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector &saveBlocks) // keep assuming no freespace fragmentation, and copy over all the data for (int i = 0; i < fileBlocks; ++i) { + if (firstBlock == 0xFFFF) + PanicAlert("Fatal Error"); mc_data_blocks[firstBlock - MC_FST_BLOCKS] = saveBlocks[i]; if (i == fileBlocks-1) nextBlock = 0xFFFF; else nextBlock = UpdatedBat.NextFreeBlock(firstBlock+1); UpdatedBat.Map[firstBlock - MC_FST_BLOCKS] = BE16(nextBlock); + UpdatedBat.LastAllocated = BE16(firstBlock); firstBlock = nextBlock; } + UpdatedBat.FreeBlocks = BE16(BE16(UpdatedBat.FreeBlocks) - fileBlocks); UpdatedBat.UpdateCounter = BE16(BE16(UpdatedBat.UpdateCounter) + 1); *PreviousBat = UpdatedBat; diff --git a/Source/Core/Core/Src/HW/GCMemcard.h b/Source/Core/Core/Src/HW/GCMemcard.h index c04217d895..be78bb527c 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.h +++ b/Source/Core/Core/Src/HW/GCMemcard.h @@ -24,6 +24,7 @@ #include "StringUtil.h" #include "EXI_DeviceIPL.h" +#define BE64(x) (Common::swap64(x)) #define BE32(x) (Common::swap32(x)) #define BE16(x) (Common::swap16(x)) #define ArrayByteSwap(a) (ByteSwap(a, a+sizeof(u8)));