summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPheenoh <pheenoh@gmail.com>2022-03-22 23:57:36 -0400
committerPheenoh <pheenoh@gmail.com>2022-03-22 23:57:36 -0400
commit158a128fb39a55fae19a3e5fa08f4a0127773d70 (patch)
treeb14f59009b9f437cbbdd9336027c455e221cd8ad /src
parentf5a2c5900c777328d4f28353067083e02903d327 (diff)
parent3af0f511867268022b4a4a05413f90c7d4348a6b (diff)
Merge remote-tracking branch 'upstream/master' into docs
Diffstat (limited to 'src')
-rw-r--r--src/m_Do/m_Do_MemCard.cpp554
-rw-r--r--src/m_Do/m_Do_MemCardRWmng.cpp174
2 files changed, 481 insertions, 247 deletions
diff --git a/src/m_Do/m_Do_MemCard.cpp b/src/m_Do/m_Do_MemCard.cpp
index 329695f0ff..55dfb43baa 100644
--- a/src/m_Do/m_Do_MemCard.cpp
+++ b/src/m_Do/m_Do_MemCard.cpp
@@ -4,27 +4,12 @@
//
#include "m_Do/m_Do_MemCard.h"
+#include "JSystem/JKernel/JKRThread.h"
+#include "MSL_C/MSL_Common/Src/string.h"
#include "dol2asm.h"
#include "dolphin/types.h"
-
-//
-// Types:
-//
-
-struct mDoRst {
- static u8 mResetData[4 + 4 /* padding */];
-};
-
-struct JKRThread {
- /* 802D16B8 */ JKRThread(OSThread*, int);
- /* 802D1758 */ ~JKRThread();
-};
-
-struct JKRHeap {
- /* 802CE438 */ void becomeCurrentHeap();
-};
-
-struct CARDFileInfo {};
+#include "m_Do/m_Do_Ext.h"
+#include "m_Do/m_Do_Reset.h"
//
// Forward References:
@@ -59,27 +44,12 @@ extern "C" extern char const* const m_Do_m_Do_MemCard__stringBase0;
// External References:
//
-SECTION_INIT void memcpy();
extern "C" void mDoExt_getAssertHeap__Fv();
extern "C" void mDoMemCdRWm_Store__FP12CARDFileInfoPvUl();
extern "C" void mDoMemCdRWm_Restore__FP12CARDFileInfoPvUl();
extern "C" void becomeCurrentHeap__7JKRHeapFv();
extern "C" void __ct__9JKRThreadFP8OSThreadi();
extern "C" void __dt__9JKRThreadFv();
-extern "C" void OSInitCond();
-extern "C" void OSWaitCond();
-extern "C" void OSSignalCond();
-extern "C" void CARDInit();
-extern "C" void CARDFreeBlocks();
-extern "C" void CARDCheck();
-extern "C" void CARDProbe();
-extern "C" void CARDProbeEx();
-extern "C" void CARDMount();
-extern "C" void CARDUnmount();
-extern "C" void CARDFormat();
-extern "C" void CARDOpen();
-extern "C" void CARDClose();
-extern "C" void CARDCreate();
extern "C" void _savegpr_27();
extern "C" void _savegpr_28();
extern "C" void _restgpr_27();
@@ -91,178 +61,359 @@ extern "C" u8 mResetData__6mDoRst[4 + 4 /* padding */];
//
/* 8001672C-80016730 01106C 0004+00 1/1 0/0 0/0 .text __ct__15mDoMemCd_Ctrl_cFv */
-mDoMemCd_Ctrl_c::mDoMemCd_Ctrl_c() {
- /* empty function */
-}
+mDoMemCd_Ctrl_c::mDoMemCd_Ctrl_c() {}
/* ############################################################################################## */
/* 803DFC20-803E0C20 00C940 1000+00 1/1 0/0 0/0 .bss MemCardStack */
static u8 MemCardStack[4096];
/* 803E0C20-803E0F40 00D940 0318+08 1/1 0/0 0/0 .bss MemCardThread */
-static u8 MemCardThread[792 + 8 /* padding */];
+static OSThread MemCardThread;
/* 80016730-800167D0 011070 00A0+00 0/0 1/1 0/0 .text ThdInit__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::ThdInit() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/ThdInit__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::ThdInit() {
+ CARDInit();
+ mCopyToPos = 0;
+ mProbeStat = 2;
+ mCardState = 0;
+ mCardCommand = CARD_NO_COMMAND;
+ mChannel = 0;
+
+ OSInitMutex(&mMutex);
+ OSInitCond(&mCond);
+
+ int priority = OSGetThreadPriority(OSGetCurrentThread());
+ OSCreateThread(&MemCardThread, mDoMemCd_main, NULL, MemCardStack + sizeof(MemCardStack),
+ sizeof(MemCardStack), priority + 1, 1);
+ OSResumeThread(&MemCardThread);
}
-#pragma pop
/* 800167D0-80016894 011110 00C4+00 1/1 0/0 0/0 .text main__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::main() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/main__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::main() {
+ do {
+ OSLockMutex(&mMutex);
+ while (mCardCommand == CARD_NO_COMMAND) {
+ OSWaitCond(&mCond, &mMutex);
+ }
+ OSUnlockMutex(&mMutex);
+
+ switch (mCardCommand) {
+ case CARD_RESTORE:
+ restore();
+ break;
+ case CARD_STORE:
+ store();
+ break;
+ case CARD_FORMAT:
+ format();
+ break;
+ case CARD_ATTACH:
+ attach();
+ break;
+ case CARD_DETACH:
+ detach();
+ break;
+ }
+
+ OSLockMutex(&mMutex);
+ mCardCommand = CARD_NO_COMMAND;
+ OSUnlockMutex(&mMutex);
+ } while (true);
}
-#pragma pop
/* 80016894-800169B4 0111D4 0120+00 0/0 1/1 0/0 .text update__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::update() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/update__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::update() {
+ if (mDoRst::isReset()) {
+ OSLockMutex(&mMutex);
+ mCardCommand = CARD_DETACH;
+ mProbeStat = 3;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ } else if (getStatus(0) != 14) {
+ if (CARDProbe(0) && getStatus(0) == 0) {
+ OSLockMutex(&mMutex);
+ mProbeStat = 0;
+ mCardState = 13;
+ mCardCommand = CARD_ATTACH;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ } else if (!CARDProbe(0) && getStatus(0) != 0) {
+ OSLockMutex(&mMutex);
+ mProbeStat = 1;
+ mCardState = 13;
+ mCardCommand = CARD_DETACH;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ }
+ }
}
-#pragma pop
/* 800169B4-80016A0C 0112F4 0058+00 0/0 2/2 0/0 .text load__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::load() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/load__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::load() {
+ if (OSTryLockMutex(&mMutex)) {
+ field_0x1fc8 = 0;
+ mCardCommand = CARD_RESTORE;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ }
}
-#pragma pop
-
-/* ############################################################################################## */
-/* 803743F8-803743F8 000A58 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */
-#pragma push
-#pragma force_active on
-SECTION_DEAD static char const* const stringBase_803743F8 = "gczelda2";
-/* @stringBase0 padding */
-SECTION_DEAD static char const* const pad_80374401 = "\0\0\0\0\0\0";
-#pragma pop
/* 80016A0C-80016AB0 01134C 00A4+00 1/1 0/0 0/0 .text restore__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::restore() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/restore__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::restore() {
+ CARDFileInfo file;
+ field_0x1fc8 = 0;
+
+ s32 card_state = CARDOpen(mChannel, "gczelda2", &file);
+ if (card_state == CARD_ERROR_READY) {
+ if (!mDoMemCdRWm_Restore(&file, this, sizeof(mData))) {
+ mCardState = 3;
+ } else {
+ setCardState(card_state);
+ }
+ CARDClose(&file);
+ } else {
+ setCardState(card_state);
+ }
+
+ field_0x1fc8 = 1;
}
-#pragma pop
/* 80016AB0-80016B58 0113F0 00A8+00 0/0 2/2 0/0 .text LoadSync__15mDoMemCd_Ctrl_cFPvUlUl
*/
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::LoadSync(void* param_0, u32 param_1, u32 param_2) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/LoadSync__15mDoMemCd_Ctrl_cFPvUlUl.s"
+s32 mDoMemCd_Ctrl_c::LoadSync(void* buffer, u32 size, u32 index) {
+ int ret = 0;
+
+ if (field_0x1fc8 == 0) {
+ return 0;
+ }
+
+ if (OSTryLockMutex(&mMutex)) {
+ if (mCardState == 3) {
+ memcpy(buffer, &mData[index], size);
+ mCardState = 1;
+ ret = 1;
+ } else {
+ mCardState = 2;
+ ret = 2;
+ }
+ OSUnlockMutex(&mMutex);
+ }
+
+ return ret;
}
-#pragma pop
/* 80016B58-80016BD4 011498 007C+00 0/0 2/2 0/0 .text save__15mDoMemCd_Ctrl_cFPvUlUl */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::save(void* param_0, u32 param_1, u32 param_2) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/save__15mDoMemCd_Ctrl_cFPvUlUl.s"
+void mDoMemCd_Ctrl_c::save(void* buffer, u32 size, u32 index) {
+ if (OSTryLockMutex(&mMutex)) {
+ memcpy(&mData[index], buffer, size);
+ field_0x1fc8 = 0;
+ mCardCommand = CARD_STORE;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ }
}
-#pragma pop
/* 80016BD4-80016CE0 011514 010C+00 1/1 0/0 0/0 .text store__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::store() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/store__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::store() {
+ CARDFileInfo file;
+ s32 card_state;
+ field_0x1fc8 = 0;
+
+ if (mCardState == 2) {
+ card_state = CARDCreate(mChannel, "gczelda2", 0x8000, &file);
+ if (card_state == CARD_ERROR_READY || card_state == CARD_ERROR_EXIST) {
+ mCardState = 1;
+ } else {
+ setCardState(card_state);
+ }
+ }
+
+ if (mCardState == 1) {
+ card_state = CARDOpen(mChannel, "gczelda2", &file);
+ if (card_state == CARD_ERROR_READY) {
+ card_state = mDoMemCdRWm_Store(&file, this, sizeof(mData));
+ if (card_state != CARD_ERROR_READY) {
+ setCardState(card_state);
+ } else {
+ mCardState = 4;
+ }
+ CARDClose(&file);
+ } else {
+ setCardState(card_state);
+ }
+ } else {
+ setCardState(card_state);
+ }
+
+ field_0x1fc8 = 1;
}
-#pragma pop
/* 80016CE0-80016D74 011620 0094+00 0/0 6/6 0/0 .text SaveSync__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::SaveSync() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/SaveSync__15mDoMemCd_Ctrl_cFv.s"
+s32 mDoMemCd_Ctrl_c::SaveSync() {
+ int ret = 0;
+
+ if (field_0x1fc8 == 0) {
+ return 0;
+ }
+
+ if (OSTryLockMutex(&mMutex)) {
+ if (mCardState == 4) {
+ mCardState = 1;
+ ret = 1;
+ } else if (mCardState == 1) {
+ ret = 0;
+ } else {
+ ret = 2;
+ }
+ OSUnlockMutex(&mMutex);
+ }
+
+ return ret;
}
-#pragma pop
-
-/* ############################################################################################## */
-/* 803A34F8-803A3530 -00001 0038+00 1/1 0/0 0/0 .data @3770 */
-SECTION_DATA static void* lit_3770[14] = {
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x74),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x4C),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x54),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x5C),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x64),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x6C),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x7C),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x84),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x8C),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x94),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0x9C),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0xA4),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0xAC),
- (void*)(((char*)getStatus__15mDoMemCd_Ctrl_cFUl) + 0xB4),
-};
/* 80016D74-80016E58 0116B4 00E4+00 2/1 2/2 0/0 .text getStatus__15mDoMemCd_Ctrl_cFUl */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::getStatus(u32 param_0) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/getStatus__15mDoMemCd_Ctrl_cFUl.s"
+u32 mDoMemCd_Ctrl_c::getStatus(u32) {
+ u32 status;
+ if (OSTryLockMutex(&mMutex)) {
+ switch (mCardState) {
+ case 1:
+ status = 2;
+ break;
+ case 2:
+ status = 1;
+ break;
+ case 3:
+ status = 3;
+ break;
+ case 4:
+ status = 4;
+ break;
+ case 5:
+ status = 5;
+ break;
+ case 0:
+ status = 0;
+ break;
+ case 6:
+ status = 7;
+ break;
+ case 7:
+ status = 6;
+ break;
+ case 8:
+ status = 11;
+ break;
+ case 9:
+ status = 12;
+ break;
+ case 10:
+ status = 9;
+ break;
+ case 11:
+ status = 10;
+ break;
+ case 12:
+ status = 8;
+ break;
+ case 13:
+ status = 14;
+ break;
+ }
+
+ OSUnlockMutex(&mMutex);
+ return status;
+ }
+
+ return 14;
}
-#pragma pop
/* 80016E58-80016EA8 011798 0050+00 0/0 2/2 0/0 .text command_format__15mDoMemCd_Ctrl_cFv
*/
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::command_format() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/command_format__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::command_format() {
+ if (OSTryLockMutex(&mMutex)) {
+ mCardCommand = CARD_FORMAT;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ }
}
-#pragma pop
/* 80016EA8-80016F2C 0117E8 0084+00 1/1 0/0 0/0 .text format__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::format() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/format__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::format() {
+ field_0x1fc8 = 0;
+
+ s32 card_state = CARDFormat(mChannel);
+ if (OSTryLockMutex(&mMutex)) {
+ if (card_state == CARD_ERROR_READY) {
+ mCardState = 5;
+ } else {
+ setCardState(card_state);
+ }
+
+ field_0x1fc8 = 1;
+ OSUnlockMutex(&mMutex);
+ }
}
-#pragma pop
/* 80016F2C-80016FB8 01186C 008C+00 0/0 2/2 0/0 .text FormatSync__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::FormatSync() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/FormatSync__15mDoMemCd_Ctrl_cFv.s"
+s32 mDoMemCd_Ctrl_c::FormatSync() {
+ int ret = 0;
+
+ if (field_0x1fc8 == 0) {
+ return 0;
+ }
+
+ if (OSTryLockMutex(&mMutex)) {
+ if (mCardState != 13) {
+ if (mCardState == 5) {
+ mCardState = 2;
+ ret = 1;
+ } else {
+ ret = 2;
+ }
+ }
+ OSUnlockMutex(&mMutex);
+ }
+
+ return ret;
}
-#pragma pop
/* 80016FB8-800170B8 0118F8 0100+00 1/1 0/0 0/0 .text attach__15mDoMemCd_Ctrl_cFv */
+// switch has case issues
+#ifdef NONMATCHING
+void mDoMemCd_Ctrl_c::attach() {
+ s32 mem_size;
+ s32 sect_size;
+
+ s32 card_state = CARDProbeEx(mChannel, &mem_size, &sect_size);
+ if (card_state == CARD_ERROR_NOCARD) {
+ mCardState = 0;
+ } else if (card_state == CARD_ERROR_FATAL_ERROR) {
+ mCardState = 12;
+ } else if (card_state == CARD_ERROR_WRONGDEVICE) {
+ mCardState = 10;
+ } else if (sect_size != 0x2000) {
+ mCardState = 11;
+ } else {
+ if (mount()) {
+ if (loadfile()) {
+ mCardState = 1;
+ } else {
+ switch (checkspace()) {
+ case 0:
+ mCardState = 2;
+ break;
+ case 1:
+ mCardState = 8;
+ break;
+ case 2:
+ mCardState = 9;
+ break;
+ }
+ }
+ }
+ }
+}
+#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
@@ -271,27 +422,24 @@ asm void mDoMemCd_Ctrl_c::attach() {
#include "asm/m_Do/m_Do_MemCard/attach__15mDoMemCd_Ctrl_cFv.s"
}
#pragma pop
+#endif
/* 800170B8-80017110 0119F8 0058+00 0/0 1/1 0/0 .text command_attach__15mDoMemCd_Ctrl_cFv
*/
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::command_attach() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/command_attach__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::command_attach() {
+ if (OSTryLockMutex(&mMutex)) {
+ mCardState = 13;
+ mCardCommand = CARD_ATTACH;
+ OSUnlockMutex(&mMutex);
+ OSSignalCond(&mCond);
+ }
}
-#pragma pop
/* 80017110-80017148 011A50 0038+00 1/1 0/0 0/0 .text detach__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::detach() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/detach__15mDoMemCd_Ctrl_cFv.s"
+void mDoMemCd_Ctrl_c::detach() {
+ CARDUnmount(mChannel);
+ mCardState = 0;
}
-#pragma pop
/* ############################################################################################## */
/* 803A3530-803A3568 -00001 0038+00 1/1 0/0 0/0 .data @3850 */
@@ -313,33 +461,37 @@ SECTION_DATA static void* lit_3850[14] = {
};
/* 803E0F40-803EAF40 00DC60 A000+00 1/1 0/0 0/0 .bss MemCardWorkArea0 */
-static u8 MemCardWorkArea0[40960];
+static u8 MemCardWorkArea0[5 * 8 * 1024] ALIGN_DECL(32);
/* 80017148-80017274 011A88 012C+00 2/1 0/0 0/0 .text mount__15mDoMemCd_Ctrl_cFv */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::mount() {
+asm s32 mDoMemCd_Ctrl_c::mount() {
nofralloc
#include "asm/m_Do/m_Do_MemCard/mount__15mDoMemCd_Ctrl_cFv.s"
}
#pragma pop
/* 80017274-800172D4 011BB4 0060+00 1/1 0/0 0/0 .text loadfile__15mDoMemCd_Ctrl_cFv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::loadfile() {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/loadfile__15mDoMemCd_Ctrl_cFv.s"
+s32 mDoMemCd_Ctrl_c::loadfile() {
+ CARDFileInfo file;
+
+ s32 card_state = CARDOpen(mChannel, "gczelda2", &file);
+ if (card_state == CARD_ERROR_READY) {
+ CARDClose(&file);
+ return CARD_ERROR_UNLOCKED;
+ } else {
+ setCardState(card_state);
+ return CARD_ERROR_READY;
+ }
}
-#pragma pop
/* 800172D4-80017360 011C14 008C+00 1/1 0/0 0/0 .text checkspace__15mDoMemCd_Ctrl_cFv */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-asm void mDoMemCd_Ctrl_c::checkspace() {
+asm s32 mDoMemCd_Ctrl_c::checkspace() {
nofralloc
#include "asm/m_Do/m_Do_MemCard/checkspace__15mDoMemCd_Ctrl_cFv.s"
}
@@ -347,6 +499,31 @@ asm void mDoMemCd_Ctrl_c::checkspace() {
/* 80017360-8001741C 011CA0 00BC+00 5/5 0/0 0/0 .text setCardState__15mDoMemCd_Ctrl_cFl
*/
+// cases aren't fully correct
+#ifdef NONMATCHING
+void mDoMemCd_Ctrl_c::setCardState(s32 param_0) {
+ switch (param_0) {
+ case CARD_ERROR_IOERROR:
+ case CARD_ERROR_FATAL_ERROR:
+ mCardState = 12;
+ break;
+ case CARD_ERROR_NOCARD:
+ mCardState = 0;
+ break;
+ case CARD_ERROR_READY:
+ if (CARDCheck(mChannel) != 0) {
+ mCardState = 7;
+ }
+ break;
+ case CARD_ERROR_ENCODING:
+ mCardState = 6;
+ break;
+ case CARD_ERROR_BROKEN:
+ mCardState = 2;
+ break;
+ }
+}
+#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
@@ -355,19 +532,20 @@ asm void mDoMemCd_Ctrl_c::setCardState(s32 param_0) {
#include "asm/m_Do/m_Do_MemCard/setCardState__15mDoMemCd_Ctrl_cFl.s"
}
#pragma pop
+#endif
/* ############################################################################################## */
/* 803EAF40-803ECF40 017C60 2000+00 2/2 27/27 0/0 .bss g_mDoMemCd_control */
mDoMemCd_Ctrl_c g_mDoMemCd_control;
/* 8001741C-80017470 011D5C 0054+00 1/1 0/0 0/0 .text mDoMemCd_main__FPv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-static asm void mDoMemCd_main(void* param_0) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCard/mDoMemCd_main__FPv.s"
+static int mDoMemCd_main(void*) {
+ { JKRThread thread(OSGetCurrentThread(), 0); }
+
+ mDoExt_getAssertHeap()->becomeCurrentHeap();
+
+ g_mDoMemCd_control.main();
+ return 0;
}
-#pragma pop
/* 803743F8-803743F8 000A58 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */
diff --git a/src/m_Do/m_Do_MemCardRWmng.cpp b/src/m_Do/m_Do_MemCardRWmng.cpp
index 4b54218bd3..8f656bd41e 100644
--- a/src/m_Do/m_Do_MemCardRWmng.cpp
+++ b/src/m_Do/m_Do_MemCardRWmng.cpp
@@ -4,16 +4,12 @@
//
#include "m_Do/m_Do_MemCardRWmng.h"
+#include "MSL_C/MSL_Common/Src/printf.h"
+#include "MSL_C/MSL_Common/Src/string.h"
+#include "d/com/d_com_inf_game.h"
#include "dol2asm.h"
#include "dolphin/types.h"
-
-//
-// Types:
-//
-
-struct mDoMemCdRWm_HeaderData {};
-
-struct CARDFileInfo {};
+#include "m_Do/m_Do_MemCard.h"
//
// Forward References:
@@ -34,22 +30,10 @@ extern "C" extern char const* const m_Do_m_Do_MemCardRWmng__stringBase0;
// External References:
//
-SECTION_INIT void memset();
-SECTION_INIT void memcpy();
-extern "C" void OSGetTime();
-extern "C" void OSTicksToCalendarTime();
-extern "C" void CARDRead();
-extern "C" void CARDWrite();
-extern "C" void CARDGetStatus();
-extern "C" void CARDSetStatus();
-extern "C" void CARDGetSerialNo();
extern "C" void _savegpr_20();
extern "C" void _savegpr_28();
extern "C" void _restgpr_20();
extern "C" void _restgpr_28();
-extern "C" void snprintf();
-extern "C" extern u8 g_mDoMemCd_control[8192];
-extern "C" extern u8 g_dComIfG_gameInfo[122384];
//
// Declarations:
@@ -57,50 +41,95 @@ extern "C" extern u8 g_dComIfG_gameInfo[122384];
/* ############################################################################################## */
/* 803ECF40-803F0F40 019C60 4000+00 2/2 0/0 0/0 .bss sTmpBuf */
-static u8 sTmpBuf[16384];
+static u8 sTmpBuf[0x4000];
/* 80017498-8001769C 011DD8 0204+00 0/0 1/1 0/0 .text mDoMemCdRWm_Store__FP12CARDFileInfoPvUl */
+#ifdef NONMATCHING
+void mDoMemCdRWm_Store(CARDFileInfo* file, void* data, u32 length) {
+ mDoMemCdRWm_BuildHeader((mDoMemCdRWm_HeaderData*)sTmpBuf);
+
+ s32 card_state = CARDWrite(file, sTmpBuf, sizeof(sTmpBuf), 0);
+ if (card_state != CARD_ERROR_READY) {
+ if (!mDoMemCdRWm_CheckCardStat(file)) {
+ memset(sTmpBuf, 0, sizeof(sTmpBuf));
+
+ card_state = CARDWrite(file, sTmpBuf, sizeof(sTmpBuf) / 2, 0x4000);
+ if (card_state == CARD_ERROR_READY) {
+ return;
+ }
+
+ card_state = CARDWrite(file, sTmpBuf, sizeof(sTmpBuf) / 2, 0x6000);
+ if (card_state == CARD_ERROR_READY) {
+ return;
+ }
+ }
+
+ memset(sTmpBuf, 0, sizeof(sTmpBuf));
+ *(int*)(sTmpBuf + 4) = 6;
+ memcpy(sTmpBuf + 8, data, length);
+ *(int*)(sTmpBuf) = 0;
+ u32 checksum = mDoMemCdRWm_CalcCheckSum(sTmpBuf, 0x1FFC);
+ *(u32*)(sTmpBuf + 0x1FFC) = checksum;
+
+ if (CARDWrite(file, sTmpBuf, sizeof(sTmpBuf) / 2, 0x4000) == CARD_ERROR_READY &&
+ CARDRead(file, sTmpBuf, sizeof(sTmpBuf) / 2, 0x4000) == CARD_ERROR_READY) {
+ if (checksum == mDoMemCdRWm_CalcCheckSum(sTmpBuf, 0x1FFC)) {
+ if (CARDWrite(file, sTmpBuf, sizeof(sTmpBuf) / 2, 0x6000) == CARD_ERROR_READY &&
+ CARDRead(file, sTmpBuf, sizeof(sTmpBuf) / 2, 0x6000) == CARD_ERROR_READY) {
+ if (checksum == mDoMemCdRWm_CalcCheckSum(sTmpBuf, 0x1FFC)) {
+ mDoMemCdRWm_SetCardStat(file);
+ }
+ }
+ }
+ }
+ }
+}
+#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-asm void mDoMemCdRWm_Store(CARDFileInfo* param_0, void* param_1, u32 param_2) {
+asm s32 mDoMemCdRWm_Store(CARDFileInfo* param_0, void* param_1, u32 param_2) {
nofralloc
#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_Store__FP12CARDFileInfoPvUl.s"
}
#pragma pop
+#endif
/* 8001769C-8001787C 011FDC 01E0+00 0/0 1/1 0/0 .text mDoMemCdRWm_Restore__FP12CARDFileInfoPvUl */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-asm void mDoMemCdRWm_Restore(CARDFileInfo* param_0, void* param_1, u32 param_2) {
+asm s32 mDoMemCdRWm_Restore(CARDFileInfo* param_0, void* param_1, u32 param_2) {
nofralloc
#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_Restore__FP12CARDFileInfoPvUl.s"
}
#pragma pop
-/* ############################################################################################## */
-/* 80374408-80374408 000A68 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */
-#pragma push
-#pragma force_active on
-SECTION_DEAD static char const* const stringBase_80374408 = "Zelda: Twilight Princess";
-SECTION_DEAD static char const* const stringBase_80374421 = "%d/%d Save Data";
-SECTION_DEAD static char const* const stringBase_80374431 = "zelda2_gc_banner.bti";
-SECTION_DEAD static char const* const stringBase_80374446 = "zelda2_gc_icon.bti";
-/* @stringBase0 padding */
-SECTION_DEAD static char const* const pad_80374459 = "\0\0\0\0\0\0";
-#pragma pop
-
/* 8001787C-800179E4 0121BC 0168+00 1/1 0/0 0/0 .text
* mDoMemCdRWm_BuildHeader__FP22mDoMemCdRWm_HeaderData */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-static asm void mDoMemCdRWm_BuildHeader(mDoMemCdRWm_HeaderData* param_0) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_BuildHeader__FP22mDoMemCdRWm_HeaderData.s"
+static void mDoMemCdRWm_BuildHeader(mDoMemCdRWm_HeaderData* header) {
+ snprintf(header->mTitle, sizeof(header->mTitle), "Zelda: Twilight Princess");
+
+ OSCalendarTime time;
+ OSTicksToCalendarTime(OSGetTime(), &time);
+ snprintf(header->mComment, sizeof(header->mComment), "%d/%d Save Data", time.month + 1,
+ time.day_of_month);
+
+ ResTIMG* banner_data =
+ (ResTIMG*)g_dComIfG_gameInfo.play.mCardIconResArchive->getResource("zelda2_gc_banner.bti");
+ ResTIMG* icon_data =
+ (ResTIMG*)g_dComIfG_gameInfo.play.mCardIconResArchive->getResource("zelda2_gc_icon.bti");
+
+ memcpy(header->mBannerTexData, (u8*)banner_data + banner_data->texDataOffset,
+ (banner_data->paletteCount * 2) + 0xC00);
+ memcpy(header->mIconTexData0, (u8*)icon_data + icon_data->texDataOffset, 0x400);
+ memcpy(header->mIconTexData1, (u8*)icon_data + icon_data->texDataOffset, 0x400);
+ memcpy(header->mIconTexData2, (u8*)icon_data + icon_data->texDataOffset, 0x400);
+ memcpy(header->mIconTexData3, (u8*)icon_data + icon_data->texDataOffset, 0x400);
+ memcpy(header->mIconTexData4, (u8*)icon_data + icon_data->texDataOffset,
+ (icon_data->paletteCount * 2) + 0x400);
+ g_dComIfG_gameInfo.play.mCardIconResArchive->removeResourceAll();
}
-#pragma pop
/* 800179E4-80017B4C 012324 0168+00 1/1 0/0 0/0 .text mDoMemCdRWm_SetCardStat__FP12CARDFileInfo */
#pragma push
@@ -117,50 +146,77 @@ static asm void mDoMemCdRWm_SetCardStat(CARDFileInfo* param_0) {
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-static asm void mDoMemCdRWm_CheckCardStat(CARDFileInfo* param_0) {
+static asm BOOL mDoMemCdRWm_CheckCardStat(CARDFileInfo* param_0) {
nofralloc
#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_CheckCardStat__FP12CARDFileInfo.s"
}
#pragma pop
/* 80017C74-80017CB4 0125B4 0040+00 1/1 0/0 0/0 .text mDoMemCdRWm_CalcCheckSum__FPvUl */
+// matches except regalloc in the beginning
+#ifdef NONMATCHING
+static u32 mDoMemCdRWm_CalcCheckSum(void* data, u32 size) {
+ u16 high = 0;
+ u16 low = 0;
+
+ u16* d = (u16*)data;
+ for (int i = 0; i < size / 2; i++) {
+ high += *d;
+ low += ~*d;
+ d++;
+ }
+
+ return high << 16 | low;
+}
+#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-static asm void mDoMemCdRWm_CalcCheckSum(void* param_0, u32 param_1) {
+static asm u32 mDoMemCdRWm_CalcCheckSum(void* param_0, u32 param_1) {
nofralloc
#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_CalcCheckSum__FPvUl.s"
}
#pragma pop
+#endif
/* 80017CB4-80017CEC 0125F4 0038+00 2/2 0/0 0/0 .text mDoMemCdRWm_CalcCheckSumGameData__FPvUl */
+// same beginning regalloc issue
+#ifdef NONMATCHING
+static u64 mDoMemCdRWm_CalcCheckSumGameData(void* data, u32 size) {
+ u32 high = 0;
+ u32 low = 0;
+
+ u8* d = (u8*)data;
+ for (int i = 0; i < size; i++) {
+ high += *d;
+ low += ~*d;
+ d++;
+ }
+
+ return (u64)high << 32 | low;
+}
+#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
-static asm void mDoMemCdRWm_CalcCheckSumGameData(void* param_0, u32 param_1) {
+static asm u64 mDoMemCdRWm_CalcCheckSumGameData(void* param_0, u32 param_1) {
nofralloc
#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_CalcCheckSumGameData__FPvUl.s"
}
#pragma pop
+#endif
/* 80017CEC-80017D38 01262C 004C+00 1/1 4/4 0/0 .text mDoMemCdRWm_TestCheckSumGameData__FPv */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCdRWm_TestCheckSumGameData(void* param_0) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_TestCheckSumGameData__FPv.s"
+BOOL mDoMemCdRWm_TestCheckSumGameData(void* data) {
+ u64 checksum = mDoMemCdRWm_CalcCheckSumGameData(data, 0xA8C);
+ return checksum == *(u64*)((u8*)data + 0xA8C);
}
-#pragma pop
/* 80017D38-80017D7C 012678 0044+00 0/0 4/4 0/0 .text mDoMemCdRWm_SetCheckSumGameData__FPUcUc */
-#pragma push
-#pragma optimization_level 0
-#pragma optimizewithasm off
-asm void mDoMemCdRWm_SetCheckSumGameData(u8* param_0, u8 param_1) {
- nofralloc
-#include "asm/m_Do/m_Do_MemCardRWmng/mDoMemCdRWm_SetCheckSumGameData__FPUcUc.s"
+void mDoMemCdRWm_SetCheckSumGameData(u8* data, u8 dataNum) {
+ u8* file_ptr = data + (dataNum * 0xA94);
+
+ *(u64*)(file_ptr + 0xA8C) = mDoMemCdRWm_CalcCheckSumGameData(file_ptr, 0xA8C);
}
-#pragma pop
/* 80374408-80374408 000A68 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */