mirror of https://github.com/zeldaret/tp.git
295 lines
7.2 KiB
C
295 lines
7.2 KiB
C
//
|
|
// Generated By: dol2asm
|
|
// Translation Unit: CARDMount
|
|
//
|
|
|
|
#include "dolphin/card/CARDMount.h"
|
|
#include "dol2asm.h"
|
|
#include "dolphin/card/card.h"
|
|
#include "dolphin/dsp/dsp.h"
|
|
#include "dolphin/dvd/dvd.h"
|
|
#include "dolphin/exi/EXIBios.h"
|
|
|
|
#include "dolphin/card/CARDPriv.h"
|
|
|
|
u8 GameChoice : 0x800030E3;
|
|
|
|
//
|
|
// Forward References:
|
|
//
|
|
|
|
static BOOL IsCard(u32 id);
|
|
static s32 DoMount(s32 chan);
|
|
static void DoUnmount(s32 chan, s32 result);
|
|
|
|
//
|
|
// Declarations:
|
|
//
|
|
|
|
/* ############################################################################################## */
|
|
/* 803D2000-803D2020 02F120 0020+00 3/3 0/0 0/0 .data SectorSizeTable */
|
|
static u32 SectorSizeTable[8] = {
|
|
8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0,
|
|
};
|
|
|
|
/* 80356948-80356A14 351288 00CC+00 2/2 0/0 0/0 .text IsCard */
|
|
static BOOL IsCard(u32 id) {
|
|
u32 size;
|
|
s32 sectorSize;
|
|
if (id & (0xFFFF0000) && (id != 0x80000004 || __CARDVendorID == 0xFFFF)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if ((id & 3) != 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
size = id & 0xfc;
|
|
switch (size) {
|
|
case 4:
|
|
case 8:
|
|
case 16:
|
|
case 32:
|
|
case 64:
|
|
case 128:
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
|
|
if (sectorSize == 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
if ((size * 1024 * 1024 / 8) / sectorSize < 8) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* 80356A14-80356A4C 351354 0038+00 0/0 1/1 0/0 .text CARDProbe */
|
|
s32 CARDProbe(s32 chan) {
|
|
s32 result;
|
|
|
|
if (GameChoice & 0x80) {
|
|
result = 0;
|
|
} else {
|
|
result = EXIProbe(chan);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/* 80356A4C-80356BC8 35138C 017C+00 0/0 1/1 0/0 .text CARDProbeEx */
|
|
s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) {
|
|
u32 id;
|
|
CARDControl* card;
|
|
BOOL enabled;
|
|
s32 result;
|
|
int probe;
|
|
|
|
if (chan < 0 || 2 <= chan) {
|
|
return CARD_RESULT_FATAL_ERROR;
|
|
}
|
|
|
|
if (GameChoice & 0x80) {
|
|
return CARD_RESULT_NOCARD;
|
|
}
|
|
|
|
card = &__CARDBlock[chan];
|
|
enabled = OSDisableInterrupts();
|
|
|
|
probe = EXIProbeEx(chan);
|
|
if (probe == -1) {
|
|
result = CARD_RESULT_NOCARD;
|
|
} else if (probe == 0) {
|
|
result = CARD_RESULT_BUSY;
|
|
} else if (card->attached) {
|
|
if (card->mountStep < 1) {
|
|
result = CARD_RESULT_BUSY;
|
|
} else {
|
|
if (memSize) {
|
|
*memSize = card->size;
|
|
}
|
|
if (sectorSize) {
|
|
*sectorSize = card->sectorSize;
|
|
}
|
|
result = CARD_RESULT_READY;
|
|
}
|
|
} else if ((EXIGetState(chan) & 8)) {
|
|
result = CARD_RESULT_WRONGDEVICE;
|
|
} else if (!EXIGetID(chan, 0, &id)) {
|
|
result = CARD_RESULT_BUSY;
|
|
} else if (IsCard(id)) {
|
|
if (memSize) {
|
|
*memSize = (s32)(id & 0xfc);
|
|
}
|
|
if (sectorSize) {
|
|
*sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
|
|
}
|
|
result = CARD_RESULT_READY;
|
|
} else {
|
|
result = CARD_RESULT_WRONGDEVICE;
|
|
}
|
|
|
|
OSRestoreInterrupts(enabled);
|
|
return result;
|
|
}
|
|
|
|
/* ############################################################################################## */
|
|
/* 803D2020-803D2040 02F140 0020+00 1/1 0/0 0/0 .data LatencyTable */
|
|
static u32 LatencyTable[8] = {
|
|
4, 8, 16, 32, 64, 128, 256, 512,
|
|
};
|
|
|
|
/* 80356BC8-8035701C 351508 0454+00 2/2 0/0 0/0 .text DoMount */
|
|
#pragma push
|
|
#pragma optimization_level 0
|
|
#pragma optimizewithasm off
|
|
static asm s32 DoMount(s32 chan) {
|
|
nofralloc
|
|
#include "asm/dolphin/card/CARDMount/DoMount.s"
|
|
}
|
|
#pragma pop
|
|
|
|
/* 8035701C-80357154 35195C 0138+00 2/2 1/1 0/0 .text __CARDMountCallback */
|
|
void __CARDMountCallback(s32 chan, s32 result) {
|
|
CARDControl* card;
|
|
CARDCallback callback;
|
|
|
|
card = &__CARDBlock[chan];
|
|
|
|
switch (result) {
|
|
case CARD_RESULT_READY:
|
|
if (++card->mountStep < CARD_MAX_MOUNT_STEP) {
|
|
result = DoMount(chan);
|
|
if (0 <= result) {
|
|
return;
|
|
}
|
|
} else {
|
|
result = __CARDVerify(card);
|
|
}
|
|
break;
|
|
case CARD_RESULT_UNLOCKED:
|
|
card->unlockCallback = __CARDMountCallback;
|
|
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
|
|
return;
|
|
}
|
|
card->unlockCallback = 0;
|
|
|
|
result = DoMount(chan);
|
|
if (0 <= result) {
|
|
return;
|
|
}
|
|
break;
|
|
case CARD_RESULT_IOERROR:
|
|
case CARD_RESULT_NOCARD:
|
|
DoUnmount(chan, result);
|
|
break;
|
|
}
|
|
|
|
callback = card->apiCallback;
|
|
card->apiCallback = 0;
|
|
__CARDPutControlBlock(card, result);
|
|
callback(chan, result);
|
|
}
|
|
|
|
/* 80357154-803572F4 351A94 01A0+00 1/1 0/0 0/0 .text CARDMountAsync */
|
|
s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback,
|
|
CARDCallback attachCallback) {
|
|
CARDControl* card;
|
|
BOOL enabled;
|
|
|
|
if (chan < 0 || 2 <= chan) {
|
|
return CARD_RESULT_FATAL_ERROR;
|
|
}
|
|
|
|
if (GameChoice & 0x80) {
|
|
return CARD_RESULT_NOCARD;
|
|
}
|
|
|
|
card = &__CARDBlock[chan];
|
|
|
|
enabled = OSDisableInterrupts();
|
|
if (card->result == CARD_RESULT_BUSY) {
|
|
OSRestoreInterrupts(enabled);
|
|
return CARD_RESULT_BUSY;
|
|
}
|
|
|
|
if (!card->attached && (EXIGetState(chan) & 0x08)) {
|
|
OSRestoreInterrupts(enabled);
|
|
return CARD_RESULT_WRONGDEVICE;
|
|
}
|
|
|
|
card->result = CARD_RESULT_BUSY;
|
|
card->workArea = workArea;
|
|
card->extCallback = detachCallback;
|
|
card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback;
|
|
card->exiCallback = 0;
|
|
|
|
if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) {
|
|
card->result = CARD_RESULT_NOCARD;
|
|
OSRestoreInterrupts(enabled);
|
|
return CARD_RESULT_NOCARD;
|
|
}
|
|
|
|
card->mountStep = 0;
|
|
card->attached = TRUE;
|
|
EXISetExiCallback(chan, 0);
|
|
OSCancelAlarm(&card->alarm);
|
|
|
|
card->currentDir = 0;
|
|
card->currentFat = 0;
|
|
|
|
OSRestoreInterrupts(enabled);
|
|
|
|
card->unlockCallback = __CARDMountCallback;
|
|
if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
|
|
return CARD_RESULT_READY;
|
|
}
|
|
card->unlockCallback = 0;
|
|
|
|
return DoMount(chan);
|
|
}
|
|
|
|
/* 803572F4-8035733C 351C34 0048+00 0/0 1/1 0/0 .text CARDMount */
|
|
s32 CARDMount(s32 chan, void* workArea, CARDCallback attachCb) {
|
|
s32 result = CARDMountAsync(chan, workArea, attachCb, __CARDSyncCallback);
|
|
if (result < 0) {
|
|
return result;
|
|
}
|
|
|
|
return __CARDSync(chan);
|
|
}
|
|
|
|
/* 8035733C-803573D8 351C7C 009C+00 2/2 0/0 0/0 .text DoUnmount */
|
|
static void DoUnmount(s32 chan, s32 result) {
|
|
CARDControl* card;
|
|
BOOL enabled;
|
|
|
|
card = &__CARDBlock[chan];
|
|
enabled = OSDisableInterrupts();
|
|
if (card->attached) {
|
|
EXISetExiCallback(chan, 0);
|
|
EXIDetach(chan);
|
|
OSCancelAlarm(&card->alarm);
|
|
card->attached = FALSE;
|
|
card->result = result;
|
|
card->mountStep = 0;
|
|
}
|
|
OSRestoreInterrupts(enabled);
|
|
}
|
|
|
|
/* 803573D8-80357484 351D18 00AC+00 0/0 2/2 0/0 .text CARDUnmount */
|
|
#pragma push
|
|
#pragma optimization_level 0
|
|
#pragma optimizewithasm off
|
|
asm s32 CARDUnmount(s32 chan) {
|
|
nofralloc
|
|
#include "asm/dolphin/card/CARDMount/CARDUnmount.s"
|
|
}
|
|
#pragma pop
|