summaryrefslogtreecommitdiff
path: root/src/Dolphin/card/CARDFormat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Dolphin/card/CARDFormat.c')
-rw-r--r--src/Dolphin/card/CARDFormat.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/Dolphin/card/CARDFormat.c b/src/Dolphin/card/CARDFormat.c
new file mode 100644
index 0000000..ebfff8b
--- /dev/null
+++ b/src/Dolphin/card/CARDFormat.c
@@ -0,0 +1,127 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+#include <dolphin/OSRtcPriv.h>
+#include <dolphin/vi.h>
+
+static void FormatCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ ++card->formatStep;
+ if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) {
+ result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback);
+ if (0 <= result) {
+ return;
+ }
+ } else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) {
+ int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK;
+ result = __CARDWrite(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE,
+ (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback);
+ if (result >= 0) {
+ return;
+ }
+ } else {
+ card->currentDir = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE);
+ memcpy(card->currentDir, (u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE,
+ CARD_SYSTEM_BLOCK_SIZE);
+ card->currentFat = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE);
+ memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE,
+ CARD_SYSTEM_BLOCK_SIZE);
+ }
+
+error:
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ __CARDPutControlBlock(card, result);
+ callback(chan, result);
+}
+
+s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) {
+ CARDControl* card;
+ CARDID* id;
+ CARDDir* dir;
+ u16* fat;
+ s16 i;
+ s32 result;
+ OSSram* sram;
+ OSSramEx* sramEx;
+ u16 viDTVStatus;
+ OSTime time;
+ OSTime rand;
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ id = (CARDID*)card->workArea;
+ memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE);
+ viDTVStatus = __VIRegs[55];
+
+ id->encode = encode;
+
+ sram = __OSLockSram();
+ *(u32*)&id->serial[20] = sram->counterBias;
+ *(u32*)&id->serial[24] = sram->language;
+ __OSUnlockSram(FALSE);
+
+ rand = time = OSGetTime();
+
+ sramEx = __OSLockSramEx();
+ for (i = 0; i < 12; i++) {
+ rand = (rand * 1103515245 + 12345) >> 16;
+ id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand);
+ rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF;
+ }
+ __OSUnlockSramEx(FALSE);
+
+ *(u32*)&id->serial[28] = viDTVStatus;
+ *(OSTime*)&id->serial[12] = time;
+
+ id->deviceID = 0;
+ id->size = card->size;
+ __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv);
+
+ for (i = 0; i < 2; i++) {
+ CARDDirCheck* check;
+
+ dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE);
+ memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE);
+ check = __CARDGetDirCheck(dir);
+ check->checkCode = i;
+ __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum,
+ &check->checkSumInv);
+ }
+ for (i = 0; i < 2; i++) {
+ fat = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE);
+ memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE);
+ fat[CARD_FAT_CHECKCODE] = (u16)i;
+ fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK);
+ fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1;
+ __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32),
+ &fat[CARD_FAT_CHECKSUM], &fat[CARD_FAT_CHECKSUMINV]);
+ }
+
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+ DCStoreRange(card->workArea, CARD_WORKAREA_SIZE);
+
+ card->formatStep = 0;
+ result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
+
+s32 CARDFormatAsync(s32 chan, CARDCallback callback) {
+ return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback);
+}