Skip to content

Commit

Permalink
m_Do_MemCardRWmng work
Browse files Browse the repository at this point in the history
  • Loading branch information
magcius committed Jul 14, 2024
1 parent 11362ce commit ee2fef6
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 18 deletions.
1 change: 1 addition & 0 deletions include/dolphin/card.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ s32 CARDCheck(s32);
s32 CARDFreeBlocks(s32, s32*, s32*);
s32 CARDRead(CARDFileInfo*, void*, s32, s32);
s32 CARDWrite(CARDFileInfo*, const void*, s32, s32);
s32 CARDGetSerialNo(s32, u64*);

#ifdef __cplusplus
}
Expand Down
9 changes: 6 additions & 3 deletions include/m_Do/m_Do_MemCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class mDoMemCd_Ctrl_c {
s32 checkspace();
void setCardState(s32);

bool isCardCommNone() { return mCardCommand == CARD_NO_COMMAND; }
bool isCardCommNone() { return mCardCommand != NULL; }

/* 0x0000 */ u8 mData[0x1650];
/* 0x1650 */ s32 mCardCommand;
/* 0x1650 */ u8* mCardCommand;
/* 0x1654 */ u8* mCardBuf;
/* 0x1658 */ u8 mCardSlot;
/* 0x1659 */ u8 field_0x1659;
Expand All @@ -58,7 +58,10 @@ class mDoMemCd_Ctrl_c {
/* 0x1660 */ s32 field_0x1660;
/* 0x1664 */ OSMutex mMutex;
/* 0x167C */ OSCond mCond;
/* 0x1684 */ u32 field_0x1684[5];
/* 0x1684 */ u32 field_0x1684;
/* 0x1688 */ u64 mCardSerialNo;
/* 0x1690 */ u32 field_0x1690;
/* 0x1694 */ u32 field_0x1694;
}; // Size: 0x1698

static int mDoMemCd_main(void*);
Expand Down
2 changes: 1 addition & 1 deletion include/m_Do/m_Do_MemCardRWmng.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ u32 mDoMemCdRWm_CalcCheckSum(void*, u32);
u16 mDoMemCdRWm_CalcCheckSumPictData(void*, u32);
BOOL mDoMemCdRWm_TestCheckSumPictData(void*);
void mDoMemCdRWm_SetCheckSumPictData(u8*);
unsigned long long mDoMemCdRWm_CalcCheckSumGameData(void*, u32);
u64 mDoMemCdRWm_CalcCheckSumGameData(void*, u32);
BOOL mDoMemCdRWm_TestCheckSumGameData(void*);
void mDoMemCdRWm_SetCheckSumGameData(u8*, u8);

Expand Down
2 changes: 1 addition & 1 deletion src/m_Do/m_Do_MemCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mDoMemCd_Ctrl_c::mDoMemCd_Ctrl_c() {
/* 80018D70-80018E18 .text ThdInit__15mDoMemCd_Ctrl_cFv */
void mDoMemCd_Ctrl_c::ThdInit() {
CARDInit();
mCardCommand = 0;
mCardCommand = NULL;
mCardBuf = NULL;
field_0x1659 = 0;
field_0x165A = 2;
Expand Down
89 changes: 76 additions & 13 deletions src/m_Do/m_Do_MemCardRWmng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ struct mDoMemCdRWm_HeaderData
/* 0x1c20 */ char info[32];
};

struct card_savedata
{
u32 saveCount;
u32 field_0x04;
u8 data[0x1ff4];
u32 csum;
};

struct card_pictdata
{
u8 data[0x1ffe];
Expand All @@ -41,10 +33,20 @@ struct card_pictdata
struct card_gamedata
{
u8 data[0x768];
unsigned long long csum;
u64 csum;
};

struct card_savedata
{
u32 saveCount;
u32 field_0x04;
card_gamedata gamedata[3];
u32 field_0x1658[0x269];
u32 csum;
};

static u8 sTmpBuf[0x2000];
static u8 sTmpBuf2[0x2000];
static u32 sSaveCount;

/* 80019940-80019CE8 .text mDoMemCdRWm_Store__FP12CARDFileInfoPvUl */
Expand All @@ -67,7 +69,7 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) {
memset(sTmpBuf, 0, 0x2000);
card_savedata* save = (card_savedata*)sTmpBuf;
save->field_0x04 = 0;
memcpy(save->data, data, size);
memcpy(save->gamedata, data, size);
save->saveCount = ++sSaveCount;
s32 csum = mDoMemCdRWm_CalcCheckSum(data, 0x1FFC);
save->csum = csum;
Expand Down Expand Up @@ -118,8 +120,69 @@ s32 mDoMemCdRWm_Store(CARDFileInfo* card, void* data, u32 size) {
}

/* 80019CE8-80019F4C .text mDoMemCdRWm_Restore__FP12CARDFileInfoPvUl */
s32 mDoMemCdRWm_Restore(CARDFileInfo*, void*, u32) {
s32 mDoMemCdRWm_Restore(CARDFileInfo* card, void* dst, u32 size) {
/* Nonmatching */
s32 ret;
card_savedata* save;
card_savedata* save2;
BOOL needsWrite = FALSE;
BOOL invalid;
BOOL csum0a;
BOOL csum1a;
BOOL csum2a;
BOOL csum0b;
BOOL csum1b;
BOOL csum2b;
u64 serialNo;

save = (card_savedata*)sTmpBuf;
save2 = (card_savedata*)sTmpBuf2;
ret = CARDRead(card, save, 0x2000, 0x2000);
if (ret != CARD_ERROR_READY) return ret;
csum0a = mDoMemCdRWm_TestCheckSumGameData(&save->gamedata[0]);
csum1a = mDoMemCdRWm_TestCheckSumGameData(&save->gamedata[1]);
csum2a = mDoMemCdRWm_TestCheckSumGameData(&save->gamedata[2]);
ret = CARDRead(card, save2, 0x2000, 0x4000);
if (ret != CARD_ERROR_READY) return ret;
csum0b = mDoMemCdRWm_TestCheckSumGameData(&save2->gamedata[0]);
csum1b = mDoMemCdRWm_TestCheckSumGameData(&save2->gamedata[1]);
csum2b = mDoMemCdRWm_TestCheckSumGameData(&save2->gamedata[2]);
if (!csum0a && csum0b) {
memcpy(&save->gamedata[0], &save2->gamedata[0], sizeof(card_gamedata));
needsWrite = TRUE;
}
if (!csum1a && csum1b) {
memcpy(&save->gamedata[1], &save2->gamedata[1], sizeof(card_gamedata));
needsWrite = TRUE;
}
if (!csum2a && csum2b) {
memcpy(&save->gamedata[2], &save2->gamedata[2], sizeof(card_gamedata));
needsWrite = TRUE;
}

invalid = !csum0a && !csum1a && !csum2a && !csum0b && !csum1b && !csum2b;
if (!mDoMemCdRWm_CheckCardStat(card))
return CARD_ERROR_FATAL_ERROR;

if (needsWrite) {
ret = CARDWrite(card, save, 0x2000, 0x2000);
if (ret != CARD_ERROR_READY) return ret;
ret = CARDWrite(card, save, 0x2000, 0x4000);
if (ret != CARD_ERROR_READY) return ret;
memcpy(dst, save->gamedata, size);
sSaveCount = save->saveCount;
g_mDoMemCd_control.field_0x1690 = save->field_0x04;
if (!invalid && g_mDoMemCd_control.mCardCommand != NULL) {
ret = CARDRead(card, g_mDoMemCd_control.mCardCommand, 0x12000, 0x6000);
if (ret != CARD_ERROR_READY) return ret;
}

serialNo;
CARDGetSerialNo(g_mDoMemCd_control.mCardSlot, &serialNo);
g_mDoMemCd_control.mCardSerialNo = serialNo;
}

return CARD_ERROR_READY;
}

#if VERSION == VERSION_PAL
Expand Down Expand Up @@ -237,15 +300,15 @@ void mDoMemCdRWm_SetCheckSumPictData(u8* p) {
}

/* 8001A3D0-8001A408 .text mDoMemCdRWm_CalcCheckSumGameData__FPvUl */
unsigned long long mDoMemCdRWm_CalcCheckSumGameData(void* p, u32 size) {
u64 mDoMemCdRWm_CalcCheckSumGameData(void* p, u32 size) {
/* Nonmatching */
u32 c0 = 0, c1 = 0;
for (int i = 0; i < size; i++) {
u8 v = ((u8*)p)[i];
c0 += v;
c1 += ~v;
}
return ((unsigned long long)c0 << 32) | c1;
return ((u64)c0 << 32) | c1;
}

/* 8001A408-8001A454 .text mDoMemCdRWm_TestCheckSumGameData__FPv */
Expand Down

0 comments on commit ee2fef6

Please sign in to comment.