#include "dolphin/card/CARDRead.h" #include "dolphin/card.h" #include "dolphin/card/CARDPriv.h" #include "dolphin/dsp.h" static void ReadCallback(s32 chan, s32 result); /* 803584A0-80358658 352DE0 01B8+00 1/1 1/1 0/0 .text __CARDSeek */ s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) { CARDControl* card; CARDDir* dir; CARDDir* ent; s32 result; u16* fat; result = __CARDGetControlBlock(fileInfo->chan, &card); if (result < 0) { return result; } if (!CARDIsValidBlockNo(card, fileInfo->iBlock) || card->cBlock * card->sectorSize <= fileInfo->offset) { return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR); } dir = __CARDGetDirBlock(card); ent = &dir[fileInfo->fileNo]; if (ent->length * card->sectorSize <= offset || ent->length * card->sectorSize < offset + length) { return __CARDPutControlBlock(card, CARD_RESULT_LIMIT); } card->fileInfo = fileInfo; fileInfo->length = length; if (offset < fileInfo->offset) { fileInfo->offset = 0; fileInfo->iBlock = ent->startBlock; if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); } } fat = __CARDGetFatBlock(card); while (fileInfo->offset < TRUNC(offset, card->sectorSize)) { fileInfo->offset += card->sectorSize; fileInfo->iBlock = fat[fileInfo->iBlock]; if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { return __CARDPutControlBlock(card, CARD_RESULT_BROKEN); } } fileInfo->offset = offset; *pcard = card; return CARD_RESULT_READY; } /* 80358658-80358788 352F98 0130+00 1/1 0/0 0/0 .text ReadCallback */ static void ReadCallback(s32 chan, s32 result) { CARDControl* card; CARDCallback callback; u16* fat; CARDFileInfo* fileInfo; s32 length; card = &__CARDBlock[chan]; if (result < 0) { goto error; } fileInfo = card->fileInfo; if (fileInfo->length < 0) { result = CARD_RESULT_CANCELED; goto error; } length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset; fileInfo->length -= length; if (fileInfo->length <= 0) { goto error; } fat = __CARDGetFatBlock(card); fileInfo->offset += length; fileInfo->iBlock = fat[fileInfo->iBlock]; if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) { result = CARD_RESULT_BROKEN; goto error; } result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock, (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize, card->buffer, ReadCallback); if (result < 0) { goto error; } return; error: callback = card->apiCallback; card->apiCallback = 0; __CARDPutControlBlock(card, result); callback(chan, result); } /* 80358788-803588CC 3530C8 0144+00 1/1 0/0 0/0 .text CARDReadAsync */ s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset, CARDCallback callback) { CARDControl* card; s32 result; CARDDir* dir; CARDDir* ent; if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) { return CARD_RESULT_FATAL_ERROR; } result = __CARDSeek(fileInfo, length, offset, &card); if (result < 0) { return result; } dir = __CARDGetDirBlock(card); ent = &dir[fileInfo->fileNo]; result = __CARDIsReadable(card, ent); if (result < 0) { return __CARDPutControlBlock(card, result); } DCInvalidateRange(buf, (u32)length); card->apiCallback = callback ? callback : __CARDDefaultApiCallback; offset = (s32)OFFSET(fileInfo->offset, card->sectorSize); length = (length < card->sectorSize - offset) ? length : card->sectorSize - offset; result = __CARDRead(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock + offset, length, buf, ReadCallback); if (result < 0) { __CARDPutControlBlock(card, result); } return result; } /* 803588CC-80358914 35320C 0048+00 0/0 2/2 0/0 .text CARDRead */ s32 CARDRead(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset) { s32 result = CARDReadAsync(fileInfo, buf, length, offset, __CARDSyncCallback); if (result < 0) { return result; } return __CARDSync(fileInfo->chan); }