Optimize space usage of supercard platform (#74)

This commit is contained in:
Edoardo Lolletti
2025-12-28 17:38:28 +01:00
committed by GitHub
parent 9f6311014d
commit 7134c4b330
8 changed files with 81 additions and 68 deletions

View File

@@ -3,23 +3,32 @@
#include "thumbInstructions.h" #include "thumbInstructions.h"
#include "../SdReadPatchCode.h" #include "../SdReadPatchCode.h"
DEFINE_SECTION_SYMBOLS(scsd_change_mode);
DEFINE_SECTION_SYMBOLS(scsd_common); DEFINE_SECTION_SYMBOLS(scsd_common);
extern "C" void sccmn_changeMode(); extern "C" void sccmn_changeMode();
extern "C" void sccmn_sdSendClock10(); extern "C" void sccmn_sdSendClock10();
extern "C" void sccmn_sdio4BitCrc16(); 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 class SuperCardCommonPatchCode : public PatchCode
{ {
public: public:
explicit SuperCardCommonPatchCode(PatchHeap& patchHeap) explicit SuperCardCommonPatchCode(PatchHeap& patchHeap)
: PatchCode(SECTION_START(scsd_common), SECTION_SIZE(scsd_common), patchHeap) { } : PatchCode(SECTION_START(scsd_common), SECTION_SIZE(scsd_common), patchHeap) { }
const void* GetScChangeModeFunction() const
{
return GetAddressAtTarget((void*)sccmn_changeMode);
}
const void* GetSdSendClock10Function() const const void* GetSdSendClock10Function() const
{ {
return GetAddressAtTarget((void*)sccmn_sdSendClock10); return GetAddressAtTarget((void*)sccmn_sdSendClock10);

View File

@@ -1,9 +1,11 @@
.cpu arm7tdmi .cpu arm7tdmi
.syntax unified .syntax unified
.section "scsd_common", "ax" .section "scsd_change_mode", "ax"
#include "asminc.h" #include "asminc.h"
.equ sd_resetaddr, 0x9440000
@ void sc_change_mode(uint16_t mode); @ void sc_change_mode(uint16_t mode);
BEGIN_THUMB_FUNCTION sccmn_changeMode BEGIN_THUMB_FUNCTION sccmn_changeMode
ldr r2,= 0x09FFFFFE ldr r2,= 0x09FFFFFE
@@ -12,8 +14,17 @@ BEGIN_THUMB_FUNCTION sccmn_changeMode
strh r3, [r2] strh r3, [r2]
strh r0, [r2] strh r0, [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 @ this function will trash r4 but leave r0 and r1 untouched
@ void SDSendClock10(void) @ void SDSendClock10(void)
BEGIN_THUMB_FUNCTION sccmn_sdSendClock10 BEGIN_THUMB_FUNCTION sccmn_sdSendClock10

View File

@@ -12,15 +12,19 @@ public:
const SdReadPatchCode* CreateSdReadPatchCode( const SdReadPatchCode* CreateSdReadPatchCode(
PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override
{ {
auto common = patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCommonPatchCode(patchHeap);
});
auto changeMode = patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardChangeModePatchCode(patchHeap);
});
if (isScLite) if (isScLite)
{ {
return patchCodeCollection.GetOrAddSharedPatchCode([&] return patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardReadSectorLitePatchCode(patchHeap, return new SuperCardReadSectorLitePatchCode(patchHeap, common, changeMode,
patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCommonPatchCode(patchHeap);
}),
patchCodeCollection.GetOrAddSharedPatchCode([&] patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardSDCommandAndDropLitePatchCode(patchHeap); return new SuperCardSDCommandAndDropLitePatchCode(patchHeap);
@@ -36,11 +40,7 @@ public:
{ {
return patchCodeCollection.GetOrAddSharedPatchCode([&] return patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardReadSectorPatchCode(patchHeap, return new SuperCardReadSectorPatchCode(patchHeap, common, changeMode,
patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCommonPatchCode(patchHeap);
}),
patchCodeCollection.GetOrAddSharedPatchCode([&] patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardSdCommandAndDropPatchCode(patchHeap); return new SuperCardSdCommandAndDropPatchCode(patchHeap);
@@ -57,15 +57,19 @@ public:
const SdWritePatchCode* CreateSdWritePatchCode( const SdWritePatchCode* CreateSdWritePatchCode(
PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const override
{ {
auto common = patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCommonPatchCode(patchHeap);
});
auto changeMode = patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardChangeModePatchCode(patchHeap);
});
if (isScLite) if (isScLite)
{ {
return patchCodeCollection.GetOrAddSharedPatchCode([&] return patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardWriteSectorLitePatchCode(patchHeap, return new SuperCardWriteSectorLitePatchCode(patchHeap, common, changeMode,
patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCommonPatchCode(patchHeap);
}),
patchCodeCollection.GetOrAddSharedPatchCode([&] patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardSDCommandAndDropLitePatchCode(patchHeap); return new SuperCardSDCommandAndDropLitePatchCode(patchHeap);
@@ -81,11 +85,7 @@ public:
{ {
return patchCodeCollection.GetOrAddSharedPatchCode([&] return patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardWriteSectorPatchCode(patchHeap, return new SuperCardWriteSectorPatchCode(patchHeap, common, changeMode,
patchCodeCollection.GetOrAddSharedPatchCode([&]
{
return new SuperCardCommonPatchCode(patchHeap);
}),
patchCodeCollection.GetOrAddSharedPatchCode([&] patchCodeCollection.GetOrAddSharedPatchCode([&]
{ {
return new SuperCardSdCommandAndDropPatchCode(patchHeap); return new SuperCardSdCommandAndDropPatchCode(patchHeap);

View File

@@ -23,30 +23,33 @@
.pool .pool
.endm .endm
#ifdef LITE
.macro CALL func, interworkLabel .macro CALL func, interworkLabel
ldr r4, \func\()_\interworkLabel\()Lite_address LOAD_INTERWORK_FUNCTION \func \interworkLabel r4
bl \interworkLabel bl \interworkLabel
.endm .endm
#ifdef LITE
.macro INTERWORK_FUNCTION func, interworkLabel .macro INTERWORK_FUNCTION func, interworkLabel
.global \func\()_\interworkLabel\()Lite_address .global \func\()_\interworkLabel\()Lite_address
\func\()_\interworkLabel\()Lite_address: \func\()_\interworkLabel\()Lite_address:
.word 0 .word 0
.endm .endm
#else .macro LOAD_INTERWORK_FUNCTION func, interworkLabel, reg
ldr \reg, \func\()_\interworkLabel\()Lite_address
.macro CALL func, interworkLabel
ldr r4, \func\()_\interworkLabel\()_address
bl \interworkLabel
.endm .endm
#else
.macro INTERWORK_FUNCTION func, interworkLabel .macro INTERWORK_FUNCTION func, interworkLabel
.global \func\()_\interworkLabel\()_address .global \func\()_\interworkLabel\()_address
\func\()_\interworkLabel\()_address: \func\()_\interworkLabel\()_address:
.word 0 .word 0
.endm .endm
.macro LOAD_INTERWORK_FUNCTION func, interworkLabel, reg
ldr \reg, \func\()_\interworkLabel\()_address
.endm
#endif #endif

View File

@@ -73,11 +73,12 @@ class SuperCardReadSectorLitePatchCode : public SdReadPatchCode
public: public:
SuperCardReadSectorLitePatchCode(PatchHeap& patchHeap, SuperCardReadSectorLitePatchCode(PatchHeap& patchHeap,
const SuperCardCommonPatchCode* superCardCommonPatchCode, const SuperCardCommonPatchCode* superCardCommonPatchCode,
const SuperCardChangeModePatchCode* superCardChangeModePatchCode,
const SuperCardSDCommandAndDropLitePatchCode* superCardSdCommandAndDropLitePatchCode, const SuperCardSDCommandAndDropLitePatchCode* superCardSdCommandAndDropLitePatchCode,
const SuperCardReadDataLitePatchCode* superCardReadDataLitePatchCode) const SuperCardReadDataLitePatchCode* superCardReadDataLitePatchCode)
: SdReadPatchCode(SECTION_START(sclite_read_sector), SECTION_SIZE(sclite_read_sector), patchHeap) : 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) INTERWORK_LABEL(sclite_sdCommandAndDropResponse6, readInterwork)
= (u32)superCardSdCommandAndDropLitePatchCode->GetSdCommandAndDropResponse6Function(); = (u32)superCardSdCommandAndDropLitePatchCode->GetSdCommandAndDropResponse6Function();
INTERWORK_LABEL(sclite_readData, readInterwork) = (u32)superCardReadDataLitePatchCode->GetReadDataLiteFunction(); INTERWORK_LABEL(sclite_readData, readInterwork) = (u32)superCardReadDataLitePatchCode->GetReadDataLiteFunction();
@@ -95,6 +96,7 @@ class SuperCardWriteSectorLitePatchCode : public SdWritePatchCode
public: public:
SuperCardWriteSectorLitePatchCode(PatchHeap& patchHeap, SuperCardWriteSectorLitePatchCode(PatchHeap& patchHeap,
const SuperCardCommonPatchCode* superCardCommonPatchCode, const SuperCardCommonPatchCode* superCardCommonPatchCode,
const SuperCardChangeModePatchCode* superCardChangeModePatchCode,
const SuperCardSDCommandAndDropLitePatchCode* superCardSdCommandAndDropLitePatchCode, const SuperCardSDCommandAndDropLitePatchCode* superCardSdCommandAndDropLitePatchCode,
const SuperCardWriteDataLitePatchCode* superCardWriteDataLitePatchCode) const SuperCardWriteDataLitePatchCode* superCardWriteDataLitePatchCode)
: SdWritePatchCode(SECTION_START(sclite_write_sector), SECTION_SIZE(sclite_write_sector), patchHeap) : 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(sclite_writeData, writeInterwork) = (u32)superCardWriteDataLitePatchCode->GetWriteDataLiteFunction();
INTERWORK_LABEL(sccmn_sdio4BitCrc16, writeInterwork) = (u32)superCardCommonPatchCode->GetCrc16ChecksumFunction(); INTERWORK_LABEL(sccmn_sdio4BitCrc16, writeInterwork) = (u32)superCardCommonPatchCode->GetCrc16ChecksumFunction();
INTERWORK_LABEL(sccmn_sdSendClock10, writeInterwork) = (u32)superCardCommonPatchCode->GetSdSendClock10Function(); 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) INTERWORK_LABEL(sclite_sdCommandAndDropResponse6, writeInterwork)
= (u32)superCardSdCommandAndDropLitePatchCode->GetSdCommandAndDropResponse6Function(); = (u32)superCardSdCommandAndDropLitePatchCode->GetSdCommandAndDropResponse6Function();
} }

View File

@@ -125,11 +125,6 @@ sclite_writeSectorSdhcLabel:
movs r0, #3 movs r0, #3
CALL sccmn_changeMode writeInterwork CALL sccmn_changeMode writeInterwork
@ SDResetCard
@ write 0
ldr r2,=sd_resetaddr
strh r2, [r2]
@ WRITE_MULTIPLE_BLOCK @ WRITE_MULTIPLE_BLOCK
SD_COMMAND_ARGUMENT #25 SD_COMMAND_ARGUMENT #25
@ 2nd parameter is in r1 from above @ 2nd parameter is in r1 from above
@@ -213,11 +208,6 @@ sclite_readSectorSdhcLabel:
movs r0, #3 movs r0, #3
CALL sccmn_changeMode readInterwork CALL sccmn_changeMode readInterwork
@ SDResetCard
@ write 0
ldr r2,= sd_resetaddr
strh r2, [r2]
@ READ_MULTIPLE_BLOCK @ READ_MULTIPLE_BLOCK
SD_COMMAND_ARGUMENT #18 SD_COMMAND_ARGUMENT #18
@ 2nd parameter is in r1 from above @ 2nd parameter is in r1 from above

View File

@@ -73,6 +73,7 @@ class SuperCardWriteSectorPatchCode : public SdWritePatchCode
public: public:
SuperCardWriteSectorPatchCode(PatchHeap& patchHeap, SuperCardWriteSectorPatchCode(PatchHeap& patchHeap,
const SuperCardCommonPatchCode* superCardCommonPatchCode, const SuperCardCommonPatchCode* superCardCommonPatchCode,
const SuperCardChangeModePatchCode* superCardChangeModePatchCode,
const SuperCardSdCommandAndDropPatchCode* superCardSdCommandAndDropPatchCode, const SuperCardSdCommandAndDropPatchCode* superCardSdCommandAndDropPatchCode,
const SuperCardWriteDataPatchCode* superCardWriteDataPatchCode) const SuperCardWriteDataPatchCode* superCardWriteDataPatchCode)
: SdWritePatchCode(SECTION_START(scsd_write_sector), SECTION_SIZE(scsd_write_sector), patchHeap) : 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(scsd_writeData, writeInterwork) = (u32)superCardWriteDataPatchCode->GetWriteDataFunction();
INTERWORK_LABEL(sccmn_sdio4BitCrc16, writeInterwork) = (u32)superCardCommonPatchCode->GetCrc16ChecksumFunction(); INTERWORK_LABEL(sccmn_sdio4BitCrc16, writeInterwork) = (u32)superCardCommonPatchCode->GetCrc16ChecksumFunction();
INTERWORK_LABEL(sccmn_sdSendClock10, writeInterwork) = (u32)superCardCommonPatchCode->GetSdSendClock10Function(); 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) INTERWORK_LABEL(scsd_sdCommandAndDropResponse6, writeInterwork)
= (u32)superCardSdCommandAndDropPatchCode->GetSdCommandAndDropResponse6Function(); = (u32)superCardSdCommandAndDropPatchCode->GetSdCommandAndDropResponse6Function();
} }
@@ -96,11 +97,12 @@ class SuperCardReadSectorPatchCode : public SdReadPatchCode
public: public:
SuperCardReadSectorPatchCode(PatchHeap& patchHeap, SuperCardReadSectorPatchCode(PatchHeap& patchHeap,
const SuperCardCommonPatchCode* superCardCommonPatchCode, const SuperCardCommonPatchCode* superCardCommonPatchCode,
const SuperCardChangeModePatchCode* superCardChangeModePatchCode,
const SuperCardSdCommandAndDropPatchCode* superCardSdCommandAndDropPatchCode, const SuperCardSdCommandAndDropPatchCode* superCardSdCommandAndDropPatchCode,
const SuperCardReadDataPatchCode* superCardReadDataPatchCode) const SuperCardReadDataPatchCode* superCardReadDataPatchCode)
: SdReadPatchCode(SECTION_START(scsd_read_sector), SECTION_SIZE(scsd_read_sector), patchHeap) : 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) INTERWORK_LABEL(scsd_sdCommandAndDropResponse6, readInterwork)
= (u32)superCardSdCommandAndDropPatchCode->GetSdCommandAndDropResponse6Function(); = (u32)superCardSdCommandAndDropPatchCode->GetSdCommandAndDropResponse6Function();
INTERWORK_LABEL(scsd_readData, readInterwork) = (u32)superCardReadDataPatchCode->GetReadDataFunction(); INTERWORK_LABEL(scsd_readData, readInterwork) = (u32)superCardReadDataPatchCode->GetReadDataFunction();

View File

@@ -182,21 +182,16 @@ scsd_writeSectorSdhcLabel:
@ enable sd access @ enable sd access
@ this function won't touch r1 @ this function won't touch r1
movs r0, #3 movs r0, #3
CALL sccmn_changeMode writeInterwork bl scsd_sccmn_changeMode_call
@ SDResetCard
@ write 0
ldr r2,= sd_resetaddr
strh r2, [r2]
@ WRITE_MULTIPLE_BLOCK @ WRITE_MULTIPLE_BLOCK
SD_COMMAND_ARGUMENT #25 SD_COMMAND_ARGUMENT #25
@ 2nd parameter is in r1 from above @ 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 @ this function will trash r4 but leave r0 and r1 untouched
CALL sccmn_sdSendClock10 writeInterwork bl scsd_sccmn_sdSendClock10_call
LOAD_FAST_EXMEMCNT LOAD_FAST_EXMEMCNT
@@ -215,7 +210,7 @@ write_sector_loop:
CALL scsd_writeData writeInterwork CALL scsd_writeData writeInterwork
@ this function will trash r4 but leave r0 and r1 untouched @ this function will trash r4 but leave r0 and r1 untouched
CALL sccmn_sdSendClock10 writeInterwork bl scsd_sccmn_sdSendClock10_call
subs r1, #1 subs r1, #1
bne write_sector_loop bne write_sector_loop
@@ -227,10 +222,10 @@ write_sector_loop:
@ 2nd parameter is passed in r1 @ 2nd parameter is passed in r1
@ and from the loop above r1 is already 0 @ 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 @ 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 @ SD_DATAADD is loaded by scsd_writeData into r5
@ while(*r5 &0x100) == 0 @ while(*r5 &0x100) == 0
@@ -240,12 +235,20 @@ beginwhile_WriteSector:
bcc beginwhile_WriteSector bcc beginwhile_WriteSector
movs r0, #1 movs r0, #1
CALL sccmn_changeMode writeInterwork bl scsd_sccmn_changeMode_call
@ restore EXMEMCNT register @ restore EXMEMCNT register
RESTORE_EXMEMCNT RESTORE_EXMEMCNT
pop {r4-r7,pc} 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 writeInterwork
INTERWORK_FUNCTION scsd_writeData writeInterwork INTERWORK_FUNCTION scsd_writeData writeInterwork
INTERWORK_FUNCTION sccmn_sdio4BitCrc16 writeInterwork INTERWORK_FUNCTION sccmn_sdio4BitCrc16 writeInterwork
@@ -253,8 +256,6 @@ INTERWORK_FUNCTION sccmn_sdSendClock10 writeInterwork
INTERWORK_FUNCTION sccmn_changeMode writeInterwork INTERWORK_FUNCTION sccmn_changeMode writeInterwork
INTERWORK_FUNCTION scsd_sdCommandAndDropResponse6 writeInterwork INTERWORK_FUNCTION scsd_sdCommandAndDropResponse6 writeInterwork
.balign 4
.pool
.section "scsd_read_sector", "ax" .section "scsd_read_sector", "ax"
@ bool scsd_readSector(uint32_t sector, uint8_t *buff, uint32_t readnum) @ bool scsd_readSector(uint32_t sector, uint8_t *buff, uint32_t readnum)
@@ -274,11 +275,6 @@ scsd_readSectorSdhcLabel:
movs r0, #3 movs r0, #3
CALL sccmn_changeMode readInterwork CALL sccmn_changeMode readInterwork
@ SDResetCard
@ write 0
ldr r2,= sd_resetaddr
strh r2, [r2]
@ READ_MULTIPLE_BLOCK @ READ_MULTIPLE_BLOCK
SD_COMMAND_ARGUMENT #18 SD_COMMAND_ARGUMENT #18
@ 2nd parameter is in r1 from above @ 2nd parameter is in r1 from above