diff --git a/include/dolphin/CARDPriv.h b/include/dolphin/CARDPriv.h index afad3a5b..0b94a1a3 100644 --- a/include/dolphin/CARDPriv.h +++ b/include/dolphin/CARDPriv.h @@ -11,6 +11,8 @@ extern "C" { #define CARD_FAT_FREEBLOCKS 0x0003u #define CARD_FAT_LASTSLOT 0x0004u +#define CARD_SEG_SIZE 512u + #define CARD_NUM_SYSTEM_BLOCK 5 #define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u) diff --git a/obj_files.mk b/obj_files.mk index 1abaa5ad..6bd09114 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -817,7 +817,7 @@ DTK_FILES :=\ CARD_FILES :=\ $(BUILD_DIR)/asm/Dolphin/card/CARDBios.o\ $(BUILD_DIR)/src/Dolphin/card/CARDUnlock.ep.o\ - $(BUILD_DIR)/asm/Dolphin/card/CARDRdwr.o\ + $(BUILD_DIR)/src/Dolphin/card/CARDRdwr.ep.o\ $(BUILD_DIR)/asm/Dolphin/card/CARDBlock.o\ $(BUILD_DIR)/asm/Dolphin/card/CARDDir.o\ $(BUILD_DIR)/asm/Dolphin/card/CARDCheck.o\ diff --git a/src/Dolphin/card/CARDRdwr.c b/src/Dolphin/card/CARDRdwr.c new file mode 100644 index 00000000..737d94d8 --- /dev/null +++ b/src/Dolphin/card/CARDRdwr.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include + +#include + +static void BlockReadCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + card->xferred += 0x200; + + card->addr += 0x200; + (u8*)card->buffer += 0x200; + if (--card->repeat <= 0) { + goto error; + } + + result = __CARDReadSegment(chan, BlockReadCallback); + if (result < 0) { + goto error; + } + return; + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) { + card->xferCallback = 0; + callback(chan, result); + } +} + +s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { + CARDControl* card; + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + card->xferCallback = callback; + card->repeat = (int)(length / CARD_SEG_SIZE); + card->addr = addr; + card->buffer = dst; + + return __CARDReadSegment(chan, BlockReadCallback); +} + +static void BlockWriteCallback(s32 chan, s32 result) { + CARDControl* card; + CARDCallback callback; + + card = &__CARDBlock[chan]; + if (result < 0) { + goto error; + } + + card->xferred += 128; + + card->addr += 128; + (u8*)card->buffer += 128; + if (--card->repeat <= 0) { + goto error; + } + + result = __CARDWritePage(chan, BlockWriteCallback); + if (result < 0) { + goto error; + } + return; + +error: + if (card->apiCallback == 0) { + __CARDPutControlBlock(card, result); + } + callback = card->xferCallback; + if (callback) { + card->xferCallback = 0; + callback(chan, result); + } +} + +s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) { + CARDControl* card; + card = &__CARDBlock[chan]; + if (!card->attached) { + return CARD_RESULT_NOCARD; + } + + card->xferCallback = callback; + card->repeat = (int)(length / 128u); + card->addr = addr; + card->buffer = dst; + + return __CARDWritePage(chan, BlockWriteCallback); +}