From 7134c4b3306c6f0d3a092bb74740a9830db5a8ca Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Sun, 28 Dec 2025 17:38:28 +0100 Subject: [PATCH] Optimize space usage of supercard platform (#74) --- .../platform/supercard/SuperCardCommon.h | 19 ++++++--- .../platform/supercard/SuperCardCommon.s | 15 ++++++- .../supercard/SuperCardLoaderPlatform.h | 40 +++++++++---------- .../patches/platform/supercard/asminc.h | 19 +++++---- .../supercard/sclite/SuperCardLiteImpl.h | 6 ++- .../supercard/sclite/SuperCardLiteImpl.s | 10 ----- .../platform/supercard/scsd/SuperCardSDImpl.h | 6 ++- .../platform/supercard/scsd/SuperCardSDImpl.s | 34 +++++++--------- 8 files changed, 81 insertions(+), 68 deletions(-) diff --git a/arm9/source/patches/platform/supercard/SuperCardCommon.h b/arm9/source/patches/platform/supercard/SuperCardCommon.h index e3de318..931992e 100644 --- a/arm9/source/patches/platform/supercard/SuperCardCommon.h +++ b/arm9/source/patches/platform/supercard/SuperCardCommon.h @@ -3,23 +3,32 @@ #include "thumbInstructions.h" #include "../SdReadPatchCode.h" +DEFINE_SECTION_SYMBOLS(scsd_change_mode); DEFINE_SECTION_SYMBOLS(scsd_common); extern "C" void sccmn_changeMode(); + extern "C" void sccmn_sdSendClock10(); extern "C" void sccmn_sdio4BitCrc16(); +class SuperCardChangeModePatchCode : public PatchCode +{ +public: + explicit SuperCardChangeModePatchCode(PatchHeap& patchHeap) + : PatchCode(SECTION_START(scsd_change_mode), SECTION_SIZE(scsd_change_mode), patchHeap) { } + + const void* GetScChangeModeFunction() const + { + return GetAddressAtTarget((void*)sccmn_changeMode); + } +}; + class SuperCardCommonPatchCode : public PatchCode { public: explicit SuperCardCommonPatchCode(PatchHeap& patchHeap) : PatchCode(SECTION_START(scsd_common), SECTION_SIZE(scsd_common), patchHeap) { } - const void* GetScChangeModeFunction() const - { - return GetAddressAtTarget((void*)sccmn_changeMode); - } - const void* GetSdSendClock10Function() const { return GetAddressAtTarget((void*)sccmn_sdSendClock10); diff --git a/arm9/source/patches/platform/supercard/SuperCardCommon.s b/arm9/source/patches/platform/supercard/SuperCardCommon.s index 4fedc8d..48911df 100644 --- a/arm9/source/patches/platform/supercard/SuperCardCommon.s +++ b/arm9/source/patches/platform/supercard/SuperCardCommon.s @@ -1,9 +1,11 @@ .cpu arm7tdmi .syntax unified -.section "scsd_common", "ax" +.section "scsd_change_mode", "ax" #include "asminc.h" +.equ sd_resetaddr, 0x9440000 + @ void sc_change_mode(uint16_t mode); BEGIN_THUMB_FUNCTION sccmn_changeMode ldr r2,= 0x09FFFFFE @@ -12,8 +14,17 @@ BEGIN_THUMB_FUNCTION sccmn_changeMode strh r3, [r2] strh r0, [r2] strh r0, [r2] - mov pc,lr + cmp r0, #3 + bne 1f + @ if mode is 3 (sd enable), reset the sd card + @ SDResetCard + @ write 0 + ldr r2,= sd_resetaddr + strh r2, [r2] +1: + mov pc, lr +.section "scsd_common", "ax" @ this function will trash r4 but leave r0 and r1 untouched @ void SDSendClock10(void) BEGIN_THUMB_FUNCTION sccmn_sdSendClock10 diff --git a/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h b/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h index cffc383..037a0e0 100644 --- a/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h +++ b/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h @@ -12,15 +12,19 @@ public: const SdReadPatchCode* CreateSdReadPatchCode( PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override { + auto common = patchCodeCollection.GetOrAddSharedPatchCode([&] + { + return new SuperCardCommonPatchCode(patchHeap); + }); + auto changeMode = patchCodeCollection.GetOrAddSharedPatchCode([&] + { + return new SuperCardChangeModePatchCode(patchHeap); + }); if (isScLite) { return patchCodeCollection.GetOrAddSharedPatchCode([&] { - return new SuperCardReadSectorLitePatchCode(patchHeap, - patchCodeCollection.GetOrAddSharedPatchCode([&] - { - return new SuperCardCommonPatchCode(patchHeap); - }), + return new SuperCardReadSectorLitePatchCode(patchHeap, common, changeMode, patchCodeCollection.GetOrAddSharedPatchCode([&] { return new SuperCardSDCommandAndDropLitePatchCode(patchHeap); @@ -36,11 +40,7 @@ public: { return patchCodeCollection.GetOrAddSharedPatchCode([&] { - return new SuperCardReadSectorPatchCode(patchHeap, - patchCodeCollection.GetOrAddSharedPatchCode([&] - { - return new SuperCardCommonPatchCode(patchHeap); - }), + return new SuperCardReadSectorPatchCode(patchHeap, common, changeMode, patchCodeCollection.GetOrAddSharedPatchCode([&] { return new SuperCardSdCommandAndDropPatchCode(patchHeap); @@ -57,15 +57,19 @@ public: const SdWritePatchCode* CreateSdWritePatchCode( PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override { + auto common = patchCodeCollection.GetOrAddSharedPatchCode([&] + { + return new SuperCardCommonPatchCode(patchHeap); + }); + auto changeMode = patchCodeCollection.GetOrAddSharedPatchCode([&] + { + return new SuperCardChangeModePatchCode(patchHeap); + }); if (isScLite) { return patchCodeCollection.GetOrAddSharedPatchCode([&] { - return new SuperCardWriteSectorLitePatchCode(patchHeap, - patchCodeCollection.GetOrAddSharedPatchCode([&] - { - return new SuperCardCommonPatchCode(patchHeap); - }), + return new SuperCardWriteSectorLitePatchCode(patchHeap, common, changeMode, patchCodeCollection.GetOrAddSharedPatchCode([&] { return new SuperCardSDCommandAndDropLitePatchCode(patchHeap); @@ -81,11 +85,7 @@ public: { return patchCodeCollection.GetOrAddSharedPatchCode([&] { - return new SuperCardWriteSectorPatchCode(patchHeap, - patchCodeCollection.GetOrAddSharedPatchCode([&] - { - return new SuperCardCommonPatchCode(patchHeap); - }), + return new SuperCardWriteSectorPatchCode(patchHeap, common, changeMode, patchCodeCollection.GetOrAddSharedPatchCode([&] { return new SuperCardSdCommandAndDropPatchCode(patchHeap); diff --git a/arm9/source/patches/platform/supercard/asminc.h b/arm9/source/patches/platform/supercard/asminc.h index 65a0e08..cb21e0f 100644 --- a/arm9/source/patches/platform/supercard/asminc.h +++ b/arm9/source/patches/platform/supercard/asminc.h @@ -23,30 +23,33 @@ .pool .endm -#ifdef LITE - .macro CALL func, interworkLabel - ldr r4, \func\()_\interworkLabel\()Lite_address + LOAD_INTERWORK_FUNCTION \func \interworkLabel r4 bl \interworkLabel .endm +#ifdef LITE + .macro INTERWORK_FUNCTION func, interworkLabel .global \func\()_\interworkLabel\()Lite_address \func\()_\interworkLabel\()Lite_address: .word 0 .endm -#else - -.macro CALL func, interworkLabel - ldr r4, \func\()_\interworkLabel\()_address - bl \interworkLabel +.macro LOAD_INTERWORK_FUNCTION func, interworkLabel, reg + ldr \reg, \func\()_\interworkLabel\()Lite_address .endm +#else + .macro INTERWORK_FUNCTION func, interworkLabel .global \func\()_\interworkLabel\()_address \func\()_\interworkLabel\()_address: .word 0 .endm +.macro LOAD_INTERWORK_FUNCTION func, interworkLabel, reg + ldr \reg, \func\()_\interworkLabel\()_address +.endm + #endif diff --git a/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.h b/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.h index ec58e70..b9ad434 100644 --- a/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.h +++ b/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.h @@ -73,11 +73,12 @@ class SuperCardReadSectorLitePatchCode : public SdReadPatchCode public: SuperCardReadSectorLitePatchCode(PatchHeap& patchHeap, const SuperCardCommonPatchCode* superCardCommonPatchCode, + const SuperCardChangeModePatchCode* superCardChangeModePatchCode, const SuperCardSDCommandAndDropLitePatchCode* superCardSdCommandAndDropLitePatchCode, const SuperCardReadDataLitePatchCode* superCardReadDataLitePatchCode) : SdReadPatchCode(SECTION_START(sclite_read_sector), SECTION_SIZE(sclite_read_sector), patchHeap) { - INTERWORK_LABEL(sccmn_changeMode, readInterwork) = (u32)superCardCommonPatchCode->GetScChangeModeFunction(); + INTERWORK_LABEL(sccmn_changeMode, readInterwork) = (u32)superCardChangeModePatchCode->GetScChangeModeFunction(); INTERWORK_LABEL(sclite_sdCommandAndDropResponse6, readInterwork) = (u32)superCardSdCommandAndDropLitePatchCode->GetSdCommandAndDropResponse6Function(); INTERWORK_LABEL(sclite_readData, readInterwork) = (u32)superCardReadDataLitePatchCode->GetReadDataLiteFunction(); @@ -95,6 +96,7 @@ class SuperCardWriteSectorLitePatchCode : public SdWritePatchCode public: SuperCardWriteSectorLitePatchCode(PatchHeap& patchHeap, const SuperCardCommonPatchCode* superCardCommonPatchCode, + const SuperCardChangeModePatchCode* superCardChangeModePatchCode, const SuperCardSDCommandAndDropLitePatchCode* superCardSdCommandAndDropLitePatchCode, const SuperCardWriteDataLitePatchCode* superCardWriteDataLitePatchCode) : SdWritePatchCode(SECTION_START(sclite_write_sector), SECTION_SIZE(sclite_write_sector), patchHeap) @@ -102,7 +104,7 @@ public: INTERWORK_LABEL(sclite_writeData, writeInterwork) = (u32)superCardWriteDataLitePatchCode->GetWriteDataLiteFunction(); INTERWORK_LABEL(sccmn_sdio4BitCrc16, writeInterwork) = (u32)superCardCommonPatchCode->GetCrc16ChecksumFunction(); INTERWORK_LABEL(sccmn_sdSendClock10, writeInterwork) = (u32)superCardCommonPatchCode->GetSdSendClock10Function(); - INTERWORK_LABEL(sccmn_changeMode, writeInterwork) = (u32)superCardCommonPatchCode->GetScChangeModeFunction(); + INTERWORK_LABEL(sccmn_changeMode, writeInterwork) = (u32)superCardChangeModePatchCode->GetScChangeModeFunction(); INTERWORK_LABEL(sclite_sdCommandAndDropResponse6, writeInterwork) = (u32)superCardSdCommandAndDropLitePatchCode->GetSdCommandAndDropResponse6Function(); } diff --git a/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.s b/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.s index 8fa18cc..cb565fc 100644 --- a/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.s +++ b/arm9/source/patches/platform/supercard/sclite/SuperCardLiteImpl.s @@ -125,11 +125,6 @@ sclite_writeSectorSdhcLabel: movs r0, #3 CALL sccmn_changeMode writeInterwork - @ SDResetCard - @ write 0 - ldr r2,=sd_resetaddr - strh r2, [r2] - @ WRITE_MULTIPLE_BLOCK SD_COMMAND_ARGUMENT #25 @ 2nd parameter is in r1 from above @@ -213,11 +208,6 @@ sclite_readSectorSdhcLabel: movs r0, #3 CALL sccmn_changeMode readInterwork - @ SDResetCard - @ write 0 - ldr r2,= sd_resetaddr - strh r2, [r2] - @ READ_MULTIPLE_BLOCK SD_COMMAND_ARGUMENT #18 @ 2nd parameter is in r1 from above diff --git a/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.h b/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.h index 4ffabf9..04a4007 100644 --- a/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.h +++ b/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.h @@ -73,6 +73,7 @@ class SuperCardWriteSectorPatchCode : public SdWritePatchCode public: SuperCardWriteSectorPatchCode(PatchHeap& patchHeap, const SuperCardCommonPatchCode* superCardCommonPatchCode, + const SuperCardChangeModePatchCode* superCardChangeModePatchCode, const SuperCardSdCommandAndDropPatchCode* superCardSdCommandAndDropPatchCode, const SuperCardWriteDataPatchCode* superCardWriteDataPatchCode) : SdWritePatchCode(SECTION_START(scsd_write_sector), SECTION_SIZE(scsd_write_sector), patchHeap) @@ -80,7 +81,7 @@ public: INTERWORK_LABEL(scsd_writeData, writeInterwork) = (u32)superCardWriteDataPatchCode->GetWriteDataFunction(); INTERWORK_LABEL(sccmn_sdio4BitCrc16, writeInterwork) = (u32)superCardCommonPatchCode->GetCrc16ChecksumFunction(); INTERWORK_LABEL(sccmn_sdSendClock10, writeInterwork) = (u32)superCardCommonPatchCode->GetSdSendClock10Function(); - INTERWORK_LABEL(sccmn_changeMode, writeInterwork) = (u32)superCardCommonPatchCode->GetScChangeModeFunction(); + INTERWORK_LABEL(sccmn_changeMode, writeInterwork) = (u32)superCardChangeModePatchCode->GetScChangeModeFunction(); INTERWORK_LABEL(scsd_sdCommandAndDropResponse6, writeInterwork) = (u32)superCardSdCommandAndDropPatchCode->GetSdCommandAndDropResponse6Function(); } @@ -96,11 +97,12 @@ class SuperCardReadSectorPatchCode : public SdReadPatchCode public: SuperCardReadSectorPatchCode(PatchHeap& patchHeap, const SuperCardCommonPatchCode* superCardCommonPatchCode, + const SuperCardChangeModePatchCode* superCardChangeModePatchCode, const SuperCardSdCommandAndDropPatchCode* superCardSdCommandAndDropPatchCode, const SuperCardReadDataPatchCode* superCardReadDataPatchCode) : SdReadPatchCode(SECTION_START(scsd_read_sector), SECTION_SIZE(scsd_read_sector), patchHeap) { - INTERWORK_LABEL(sccmn_changeMode, readInterwork) = (u32)superCardCommonPatchCode->GetScChangeModeFunction(); + INTERWORK_LABEL(sccmn_changeMode, readInterwork) = (u32)superCardChangeModePatchCode->GetScChangeModeFunction(); INTERWORK_LABEL(scsd_sdCommandAndDropResponse6, readInterwork) = (u32)superCardSdCommandAndDropPatchCode->GetSdCommandAndDropResponse6Function(); INTERWORK_LABEL(scsd_readData, readInterwork) = (u32)superCardReadDataPatchCode->GetReadDataFunction(); diff --git a/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.s b/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.s index 84e1f75..9e7b143 100644 --- a/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.s +++ b/arm9/source/patches/platform/supercard/scsd/SuperCardSDImpl.s @@ -182,21 +182,16 @@ scsd_writeSectorSdhcLabel: @ enable sd access @ this function won't touch r1 movs r0, #3 - CALL sccmn_changeMode writeInterwork - - @ SDResetCard - @ write 0 - ldr r2,= sd_resetaddr - strh r2, [r2] + bl scsd_sccmn_changeMode_call @ WRITE_MULTIPLE_BLOCK SD_COMMAND_ARGUMENT #25 @ 2nd parameter is in r1 from above - CALL scsd_sdCommandAndDropResponse6 writeInterwork + bl scsd_sdCommandAndDropResponse6_call @ this function will trash r4 but leave r0 and r1 untouched - CALL sccmn_sdSendClock10 writeInterwork + bl scsd_sccmn_sdSendClock10_call LOAD_FAST_EXMEMCNT @@ -215,7 +210,7 @@ write_sector_loop: CALL scsd_writeData writeInterwork @ this function will trash r4 but leave r0 and r1 untouched - CALL sccmn_sdSendClock10 writeInterwork + bl scsd_sccmn_sdSendClock10_call subs r1, #1 bne write_sector_loop @@ -227,10 +222,10 @@ write_sector_loop: @ 2nd parameter is passed in r1 @ and from the loop above r1 is already 0 - CALL scsd_sdCommandAndDropResponse6 writeInterwork + bl scsd_sdCommandAndDropResponse6_call @ this function will trash r4 but leave r0 and r1 untouched - CALL sccmn_sdSendClock10 writeInterwork + bl scsd_sccmn_sdSendClock10_call @ SD_DATAADD is loaded by scsd_writeData into r5 @ while(*r5 &0x100) == 0 @@ -240,12 +235,20 @@ beginwhile_WriteSector: bcc beginwhile_WriteSector movs r0, #1 - CALL sccmn_changeMode writeInterwork + bl scsd_sccmn_changeMode_call @ restore EXMEMCNT register RESTORE_EXMEMCNT pop {r4-r7,pc} +scsd_sccmn_sdSendClock10_call: + LOAD_INTERWORK_FUNCTION sccmn_sdSendClock10 writeInterwork r4 + bx r4 +scsd_sdCommandAndDropResponse6_call: + LOAD_INTERWORK_FUNCTION scsd_sdCommandAndDropResponse6 writeInterwork r4 + bx r4 +scsd_sccmn_changeMode_call: + LOAD_INTERWORK_FUNCTION sccmn_changeMode writeInterwork r4 INTERWORK writeInterwork INTERWORK_FUNCTION scsd_writeData writeInterwork INTERWORK_FUNCTION sccmn_sdio4BitCrc16 writeInterwork @@ -253,8 +256,6 @@ INTERWORK_FUNCTION sccmn_sdSendClock10 writeInterwork INTERWORK_FUNCTION sccmn_changeMode writeInterwork INTERWORK_FUNCTION scsd_sdCommandAndDropResponse6 writeInterwork -.balign 4 -.pool .section "scsd_read_sector", "ax" @ bool scsd_readSector(uint32_t sector, uint8_t *buff, uint32_t readnum) @@ -274,11 +275,6 @@ scsd_readSectorSdhcLabel: movs r0, #3 CALL sccmn_changeMode readInterwork - @ SDResetCard - @ write 0 - ldr r2,= sd_resetaddr - strh r2, [r2] - @ READ_MULTIPLE_BLOCK SD_COMMAND_ARGUMENT #18 @ 2nd parameter is in r1 from above