mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-09 20:41:29 -04:00
Work on dvd, si, os and exi (#249)
This commit is contained in:
+192
-191
@@ -4,10 +4,10 @@
|
||||
//
|
||||
|
||||
#include "dolphin/dvd/dvd.h"
|
||||
#include "dolphin/dvd/dvdlow.h"
|
||||
#include "MSL_C/MSL_Common/Src/mem.h"
|
||||
#include "MSL_C/MSL_Common/Src/string.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/dvd/dvdlow.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
|
||||
//
|
||||
@@ -195,7 +195,7 @@ void stateReadingFST() {
|
||||
LastState = (stateFunc)stateReadingFST;
|
||||
|
||||
if (bootInfo->fst_max_length < BB2.FSTLength) {
|
||||
OSPanic("dvd.c", 661, "DVDChangeDisk(): FST in the new disc is too big. ");
|
||||
OSPanic(__FILE__, 661, "DVDChangeDisk(): FST in the new disc is too big. ");
|
||||
}
|
||||
|
||||
DVDLowRead(bootInfo->fst_location, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition,
|
||||
@@ -236,8 +236,8 @@ static void cbForStateReadingFST(u32 intType) {
|
||||
}
|
||||
|
||||
inline static void stateError(u32 error) {
|
||||
__DVDStoreErrorCode(error);
|
||||
DVDLowStopMotor(cbForStateError);
|
||||
__DVDStoreErrorCode(error);
|
||||
DVDLowStopMotor(cbForStateError);
|
||||
}
|
||||
|
||||
/* 803492DC-80349388 343C1C 00AC+00 12/12 0/0 0/0 .text cbForStateError */
|
||||
@@ -574,11 +574,11 @@ static void cbForStateCheckID2(u32 intType) {
|
||||
LastState = (stateFunc)stateReadingFST;
|
||||
|
||||
if (bootInfo->fst_max_length < BB2.FSTLength) {
|
||||
OSPanic("dvd.c", 661, "DVDChangeDisk(): FST in the new disc is too big. ");
|
||||
OSPanic(__FILE__, 661, "DVDChangeDisk(): FST in the new disc is too big. ");
|
||||
}
|
||||
|
||||
DVDLowRead(bootInfo->fst_location, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition,
|
||||
cbForStateReadingFST);
|
||||
cbForStateReadingFST);
|
||||
|
||||
} else {
|
||||
stateGettingError();
|
||||
@@ -844,199 +844,199 @@ static u32 ImmCommand[] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||
SECTION_SDATA static u32 DmaCommand[] = {0xFFFFFFFF};
|
||||
|
||||
inline static BOOL IsImmCommandWithResult(u32 command) {
|
||||
u32 i;
|
||||
u32 i;
|
||||
|
||||
if (command == 9 || command == 10 || command == 11 || command == 12) {
|
||||
return TRUE;
|
||||
}
|
||||
if (command == 9 || command == 10 || command == 11 || command == 12) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(ImmCommand) / sizeof(ImmCommand[0]); i++) {
|
||||
if (command == ImmCommand[i])
|
||||
return TRUE;
|
||||
}
|
||||
for (i = 0; i < sizeof(ImmCommand) / sizeof(ImmCommand[0]); i++) {
|
||||
if (command == ImmCommand[i])
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
inline static BOOL IsDmaCommand(u32 command) {
|
||||
u32 i;
|
||||
u32 i;
|
||||
|
||||
if (command == 1 || command == 4 || command == 5 || command == 14)
|
||||
return TRUE;
|
||||
if (command == 1 || command == 4 || command == 5 || command == 14)
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < sizeof(DmaCommand) / sizeof(DmaCommand[0]); i++) {
|
||||
if (command == DmaCommand[i])
|
||||
return TRUE;
|
||||
}
|
||||
for (i = 0; i < sizeof(DmaCommand) / sizeof(DmaCommand[0]); i++) {
|
||||
if (command == DmaCommand[i])
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 8034A6D4-8034AD2C 345014 0658+00 1/1 0/0 0/0 .text cbForStateBusy */
|
||||
static void cbForStateBusy(u32 intType) {
|
||||
DVDCommandBlock* finished;
|
||||
DVDCommandBlock* finished;
|
||||
|
||||
if (intType == 16) {
|
||||
stateTimeout();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((CurrCommand == 3) || (CurrCommand == 15)) {
|
||||
if (intType & 2) {
|
||||
stateError(0x1234567);
|
||||
return;
|
||||
}
|
||||
|
||||
NumInternalRetry = 0;
|
||||
|
||||
if (CurrCommand == 15) {
|
||||
ResetRequired = TRUE;
|
||||
}
|
||||
|
||||
if (CheckCancel(7)) {
|
||||
return;
|
||||
}
|
||||
|
||||
executing->state = 7;
|
||||
stateMotorStopped();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsDmaCommand(CurrCommand)) {
|
||||
executing->transferred_size += executing->current_transfer_size - __DIRegs[6];
|
||||
}
|
||||
|
||||
if (intType & 8) {
|
||||
Canceling = FALSE;
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 10;
|
||||
if (finished->callback)
|
||||
(*finished->callback)(-3, finished);
|
||||
if (CancelCallback)
|
||||
(CancelCallback)(0, finished);
|
||||
stateReady();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (intType & 1) {
|
||||
NumInternalRetry = 0;
|
||||
|
||||
if (CurrCommand == 16) {
|
||||
MotorState = 1;
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(*finished->callback)(0, finished);
|
||||
}
|
||||
stateReady();
|
||||
if (intType == 16) {
|
||||
stateTimeout();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckCancel(0))
|
||||
return;
|
||||
if ((CurrCommand == 3) || (CurrCommand == 15)) {
|
||||
if (intType & 2) {
|
||||
stateError(0x1234567);
|
||||
return;
|
||||
}
|
||||
|
||||
NumInternalRetry = 0;
|
||||
|
||||
if (CurrCommand == 15) {
|
||||
ResetRequired = TRUE;
|
||||
}
|
||||
|
||||
if (CheckCancel(7)) {
|
||||
return;
|
||||
}
|
||||
|
||||
executing->state = 7;
|
||||
stateMotorStopped();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsDmaCommand(CurrCommand)) {
|
||||
if (executing->transferred_size != executing->length) {
|
||||
stateBusy(executing);
|
||||
return;
|
||||
}
|
||||
executing->transferred_size += executing->current_transfer_size - __DIRegs[6];
|
||||
}
|
||||
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)((s32)finished->transferred_size, finished);
|
||||
}
|
||||
stateReady();
|
||||
} else if (IsImmCommandWithResult(CurrCommand)) {
|
||||
s32 result;
|
||||
|
||||
if ((CurrCommand == 11) || (CurrCommand == 10)) {
|
||||
result = (s32)(__DIRegs[8] << 2);
|
||||
} else {
|
||||
result = (s32)__DIRegs[8];
|
||||
}
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(result, finished);
|
||||
}
|
||||
stateReady();
|
||||
} else if (CurrCommand == 6) {
|
||||
if (executing->current_transfer_size == 0) {
|
||||
if (__DIRegs[8] & 1) {
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 9;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(-2, finished);
|
||||
}
|
||||
stateReady();
|
||||
} else {
|
||||
AutoFinishing = FALSE;
|
||||
executing->current_transfer_size = 1;
|
||||
DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy);
|
||||
}
|
||||
} else {
|
||||
if (intType & 8) {
|
||||
Canceling = FALSE;
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(0, finished);
|
||||
}
|
||||
finished->state = 10;
|
||||
if (finished->callback)
|
||||
(*finished->callback)(-3, finished);
|
||||
if (CancelCallback)
|
||||
(CancelCallback)(0, finished);
|
||||
stateReady();
|
||||
}
|
||||
} else {
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(0, finished);
|
||||
}
|
||||
stateReady();
|
||||
}
|
||||
} else {
|
||||
if (CurrCommand == 14) {
|
||||
stateError(0x01234567);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) &&
|
||||
(executing->transferred_size == executing->length)) {
|
||||
if (CheckCancel(0)) {
|
||||
return;
|
||||
}
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)((s32)finished->transferred_size, finished);
|
||||
}
|
||||
stateReady();
|
||||
return;
|
||||
}
|
||||
|
||||
stateGettingError();
|
||||
}
|
||||
if (intType & 1) {
|
||||
NumInternalRetry = 0;
|
||||
|
||||
if (CurrCommand == 16) {
|
||||
MotorState = 1;
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(*finished->callback)(0, finished);
|
||||
}
|
||||
stateReady();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckCancel(0))
|
||||
return;
|
||||
|
||||
if (IsDmaCommand(CurrCommand)) {
|
||||
if (executing->transferred_size != executing->length) {
|
||||
stateBusy(executing);
|
||||
return;
|
||||
}
|
||||
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)((s32)finished->transferred_size, finished);
|
||||
}
|
||||
stateReady();
|
||||
} else if (IsImmCommandWithResult(CurrCommand)) {
|
||||
s32 result;
|
||||
|
||||
if ((CurrCommand == 11) || (CurrCommand == 10)) {
|
||||
result = (s32)(__DIRegs[8] << 2);
|
||||
} else {
|
||||
result = (s32)__DIRegs[8];
|
||||
}
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(result, finished);
|
||||
}
|
||||
stateReady();
|
||||
} else if (CurrCommand == 6) {
|
||||
if (executing->current_transfer_size == 0) {
|
||||
if (__DIRegs[8] & 1) {
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 9;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(-2, finished);
|
||||
}
|
||||
stateReady();
|
||||
} else {
|
||||
AutoFinishing = FALSE;
|
||||
executing->current_transfer_size = 1;
|
||||
DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy);
|
||||
}
|
||||
} else {
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(0, finished);
|
||||
}
|
||||
stateReady();
|
||||
}
|
||||
} else {
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)(0, finished);
|
||||
}
|
||||
stateReady();
|
||||
}
|
||||
} else {
|
||||
if (CurrCommand == 14) {
|
||||
stateError(0x01234567);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) &&
|
||||
(executing->transferred_size == executing->length)) {
|
||||
if (CheckCancel(0)) {
|
||||
return;
|
||||
}
|
||||
finished = executing;
|
||||
executing = &DummyCommandBlock;
|
||||
|
||||
finished->state = 0;
|
||||
if (finished->callback) {
|
||||
(finished->callback)((s32)finished->transferred_size, finished);
|
||||
}
|
||||
stateReady();
|
||||
return;
|
||||
}
|
||||
|
||||
stateGettingError();
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL issueCommand(s32 prio, DVDCommandBlock* block) {
|
||||
BOOL level;
|
||||
BOOL result;
|
||||
|
||||
if (autoInvalidation && (block->command == 1 || block->command == 4 || block->command == 5 ||
|
||||
block->command == 14)) {
|
||||
if (autoInvalidation &&
|
||||
(block->command == 1 || block->command == 4 || block->command == 5 || block->command == 14)) {
|
||||
DCInvalidateRange(block->buffer, block->length);
|
||||
}
|
||||
|
||||
@@ -1199,7 +1199,8 @@ void DVDResume(void) {
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D15F8-803D163C 02E718 0041+03 0/0 0/0 0/0 .data @789 */
|
||||
static char string_DVDChangeDiskAsyncMsg[] = "DVDChangeDiskAsync(): You can't specify NULL to company name. \n";
|
||||
static char string_DVDChangeDiskAsyncMsg[] =
|
||||
"DVDChangeDiskAsync(): You can't specify NULL to company name. \n";
|
||||
|
||||
/* 8034B2D4-8034B550 345C14 027C+00 3/2 0/0 0/0 .text DVDCancelAsync */
|
||||
BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) {
|
||||
@@ -1408,38 +1409,38 @@ BOOL DVDCheckDisk(void) {
|
||||
}
|
||||
|
||||
inline void DVDPause(void) {
|
||||
BOOL level;
|
||||
level = OSDisableInterrupts();
|
||||
PauseFlag = TRUE;
|
||||
if (executing == (DVDCommandBlock*)NULL) {
|
||||
PausingFlag = TRUE;
|
||||
}
|
||||
OSRestoreInterrupts(level);
|
||||
BOOL level;
|
||||
level = OSDisableInterrupts();
|
||||
PauseFlag = TRUE;
|
||||
if (executing == (DVDCommandBlock*)NULL) {
|
||||
PausingFlag = TRUE;
|
||||
}
|
||||
OSRestoreInterrupts(level);
|
||||
}
|
||||
|
||||
inline BOOL DVDCancelAllAsync(DVDCBCallback callback) {
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* p;
|
||||
BOOL retVal;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* p;
|
||||
BOOL retVal;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
DVDPause();
|
||||
enabled = OSDisableInterrupts();
|
||||
DVDPause();
|
||||
|
||||
while ((p = __DVDPopWaitingQueue()) != 0) {
|
||||
DVDCancelAsync(p, NULL);
|
||||
}
|
||||
while ((p = __DVDPopWaitingQueue()) != 0) {
|
||||
DVDCancelAsync(p, NULL);
|
||||
}
|
||||
|
||||
if (executing)
|
||||
retVal = DVDCancelAsync(executing, callback);
|
||||
else {
|
||||
retVal = TRUE;
|
||||
if (callback)
|
||||
(*callback)(0, NULL);
|
||||
}
|
||||
if (executing)
|
||||
retVal = DVDCancelAsync(executing, callback);
|
||||
else {
|
||||
retVal = TRUE;
|
||||
if (callback)
|
||||
(*callback)(0, NULL);
|
||||
}
|
||||
|
||||
DVDResume();
|
||||
OSRestoreInterrupts(enabled);
|
||||
return retVal;
|
||||
DVDResume();
|
||||
OSRestoreInterrupts(enabled);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/* 8034B720-8034B83C 346060 011C+00 0/0 1/1 0/0 .text __DVDPrepareResetAsync */
|
||||
|
||||
@@ -23,14 +23,12 @@ void __DVDPrintFatalMessage();
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 804517C8-804517D0 000CC8 0004+04 1/1 0/0 0/0 .sbss FatalFunc */
|
||||
static u8 FatalFunc[4 + 4 /* padding */];
|
||||
static void (*FatalFunc)(void) = NULL;
|
||||
|
||||
/* 8034BCFC-8034BD2C 34663C 0030+00 0/0 1/1 0/0 .text __DVDPrintFatalMessage */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDPrintFatalMessage() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdFatal/__DVDPrintFatalMessage.s"
|
||||
void __DVDPrintFatalMessage(void) {
|
||||
if (!FatalFunc) {
|
||||
return;
|
||||
}
|
||||
FatalFunc();
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
+50
-24
@@ -5,52 +5,78 @@
|
||||
|
||||
#include "dolphin/dvd/dvderror.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/os/OSRtc.h"
|
||||
#include "dolphin/types.h"
|
||||
|
||||
//
|
||||
// Forward References:
|
||||
//
|
||||
|
||||
static void ErrorCode2Num();
|
||||
static u8 ErrorCode2Num(u32 errorCode);
|
||||
void __DVDStoreErrorCode();
|
||||
|
||||
//
|
||||
// External References:
|
||||
//
|
||||
|
||||
void __OSLockSramEx();
|
||||
void __OSUnlockSramEx();
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
//
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D16A8-803D16F0 02E7C8 0048+00 1/1 0/0 0/0 .data ErrorTable */
|
||||
SECTION_DATA static u8 ErrorTable[72] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3A, 0x00, 0x00, 0x06, 0x28, 0x00, 0x00, 0x03, 0x02,
|
||||
0x00, 0x00, 0x03, 0x11, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x05, 0x20, 0x01, 0x00, 0x05,
|
||||
0x21, 0x00, 0x00, 0x05, 0x24, 0x00, 0x00, 0x05, 0x24, 0x01, 0x00, 0x05, 0x24, 0x02, 0x00,
|
||||
0x0B, 0x5A, 0x01, 0x00, 0x05, 0x63, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00, 0x02, 0x04, 0x00,
|
||||
0x00, 0x04, 0x08, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
static u32 ErrorTable[] = {
|
||||
0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000,
|
||||
0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01,
|
||||
0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0,
|
||||
};
|
||||
|
||||
/* 8034BA6C-8034BB88 3463AC 011C+00 1/1 0/0 0/0 .text ErrorCode2Num */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void ErrorCode2Num() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvderror/ErrorCode2Num.s"
|
||||
static u8 ErrorCode2Num(u32 errorCode) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < sizeof(ErrorTable) / sizeof(ErrorTable[0]); i++) {
|
||||
if (ErrorTable[i] == errorCode) {
|
||||
return (u8)i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((errorCode >= 0x00100000) && (errorCode <= 0x00100008)) {
|
||||
return 17;
|
||||
}
|
||||
|
||||
return 29;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034BB88-8034BC04 3464C8 007C+00 0/0 12/12 0/0 .text __DVDStoreErrorCode */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDStoreErrorCode() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvderror/__DVDStoreErrorCode.s"
|
||||
static u8 Convert(u32 error) {
|
||||
u32 statusCode;
|
||||
u32 errorCode;
|
||||
u8 errorNum;
|
||||
|
||||
if (error == 0x01234567)
|
||||
return 255;
|
||||
|
||||
if (error == 0x01234568)
|
||||
return 254;
|
||||
|
||||
statusCode = (error & 0xff000000) >> 24;
|
||||
errorCode = error & 0x00ffffff;
|
||||
|
||||
errorNum = ErrorCode2Num(errorCode);
|
||||
if (statusCode >= 6)
|
||||
statusCode = 6;
|
||||
|
||||
return (u8)(statusCode * 30 + errorNum);
|
||||
}
|
||||
|
||||
void __DVDStoreErrorCode(u32 error) {
|
||||
OSSramEx* sram;
|
||||
u8 num;
|
||||
|
||||
num = Convert(error);
|
||||
|
||||
sram = __OSLockSramEx();
|
||||
sram->dvdErrorCode = num;
|
||||
__OSUnlockSramEx(TRUE);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
+376
-137
@@ -4,70 +4,74 @@
|
||||
//
|
||||
|
||||
#include "dolphin/dvd/dvdfs.h"
|
||||
#include "dolphin/dvd/dvd.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/types.h"
|
||||
#include "MSL_C/MSL_Common/Src/ctype.h"
|
||||
|
||||
//
|
||||
// Forward References:
|
||||
//
|
||||
|
||||
void __DVDFSInit();
|
||||
void DVDConvertPathToEntrynum();
|
||||
void DVDFastOpen();
|
||||
void DVDOpen();
|
||||
void DVDClose();
|
||||
static void entryToPath();
|
||||
static void DVDConvertEntrynumToPath();
|
||||
static void DVDGetCurrentDir();
|
||||
void DVDChangeDir();
|
||||
void DVDReadAsyncPrio();
|
||||
int DVDConvertPathToEntrynum(const char* path);
|
||||
int DVDFastOpen(long entryNum, DVDFileInfo* info);
|
||||
BOOL DVDOpen(const char* filename, DVDFileInfo* fileinfo);
|
||||
BOOL DVDClose(DVDFileInfo* fileinfo);
|
||||
static u32 entryToPath(u32 entry, char* path, u32 maxlen);
|
||||
static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen);
|
||||
static BOOL DVDGetCurrentDir(char* path, u32 maxlen);
|
||||
BOOL DVDChangeDir(const char* dirname);
|
||||
BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
|
||||
DVDCallback callback, s32 prio);
|
||||
static void cbForReadAsync();
|
||||
void DVDReadPrio();
|
||||
int DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio);
|
||||
static void cbForReadSync();
|
||||
void DVDOpenDir();
|
||||
void DVDReadDir();
|
||||
u8 DVDCloseDir();
|
||||
BOOL DVDOpenDir(const char*, DVDDirectory* dir);
|
||||
BOOL DVDReadDir(DVDDirectory* dir, DVDDirectoryEntry* entry);
|
||||
BOOL DVDCloseDir();
|
||||
|
||||
//
|
||||
// External References:
|
||||
//
|
||||
|
||||
void OSReport();
|
||||
void OSPanic();
|
||||
void OSDisableInterrupts();
|
||||
void OSRestoreInterrupts();
|
||||
void OSSleepThread();
|
||||
void OSWakeupThread();
|
||||
void DVDReadAbsAsyncPrio();
|
||||
void DVDCancel();
|
||||
void tolower();
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
//
|
||||
|
||||
|
||||
typedef struct FSTEntry FSTEntry;
|
||||
|
||||
struct FSTEntry {
|
||||
unsigned int isDirAndStringOff;
|
||||
unsigned int parentOrPosition;
|
||||
unsigned int nextEntryOrLength;
|
||||
};
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 80451758-8045175C 000C58 0004+00 1/1 0/0 0/0 .sbss BootInfo */
|
||||
static u8 BootInfo[4];
|
||||
static OSBootInfo* BootInfo;
|
||||
|
||||
/* 8045175C-80451760 000C5C 0004+00 10/10 0/0 0/0 .sbss FstStart */
|
||||
static u8 FstStart[4];
|
||||
static FSTEntry* FstStart;
|
||||
|
||||
/* 80451760-80451764 000C60 0004+00 5/5 0/0 0/0 .sbss FstStringStart */
|
||||
static u8 FstStringStart[4];
|
||||
static char* FstStringStart;
|
||||
|
||||
/* 80451764-80451768 000C64 0004+00 2/2 0/0 0/0 .sbss MaxEntryNum */
|
||||
static u8 MaxEntryNum[4];
|
||||
static unsigned int MaxEntryNum;
|
||||
|
||||
/* 803484F0-80348528 342E30 0038+00 0/0 2/2 0/0 .text __DVDFSInit */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDFSInit() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/__DVDFSInit.s"
|
||||
void __DVDFSInit() {
|
||||
BootInfo = (OSBootInfo*)OSPhysicalToCached(0);
|
||||
FstStart = (FSTEntry*)BootInfo->fst_location;
|
||||
|
||||
if (FstStart) {
|
||||
MaxEntryNum = FstStart[0].nextEntryOrLength;
|
||||
FstStringStart = (char*)&(FstStart[MaxEntryNum]);
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D1380-803D1448 02E4A0 00C8+00 1/1 0/0 0/0 .data @119 */
|
||||
@@ -80,173 +84,408 @@ SECTION_DATA static char lit_119[] =
|
||||
SECTION_SDATA static char lit_118[] = "dvdfs.c";
|
||||
|
||||
/* 80451768-8045176C 000C68 0004+00 4/4 0/0 0/0 .sbss currentDirectory */
|
||||
static u8 currentDirectory[4];
|
||||
static u32 currentDirectory;
|
||||
|
||||
/* 80451770-80451778 000C70 0008+00 2/2 3/3 0/0 .sbss __DVDThreadQueue */
|
||||
extern u8 __DVDThreadQueue[8];
|
||||
u8 __DVDThreadQueue[8];
|
||||
OSThreadQueue __DVDThreadQueue;
|
||||
|
||||
/* 8045176C-80451770 000C6C 0004+00 1/1 1/1 0/0 .sbss __DVDLongFileNameFlag */
|
||||
extern u8 __DVDLongFileNameFlag[4];
|
||||
u8 __DVDLongFileNameFlag[4];
|
||||
u32 __DVDLongFileNameFlag;
|
||||
|
||||
|
||||
/* For convenience */
|
||||
#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE)
|
||||
#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000)
|
||||
#define parentDir(i) (FstStart[i].parentOrPosition)
|
||||
#define nextDir(i) (FstStart[i].nextEntryOrLength)
|
||||
#define filePosition(i) (FstStart[i].parentOrPosition)
|
||||
#define fileLength(i) (FstStart[i].nextEntryOrLength)
|
||||
|
||||
static inline BOOL isSame(const char* path, const char* string) {
|
||||
while (*string != '\0') {
|
||||
if (tolower(*path++) != tolower(*string++)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*path == '/') || (*path == '\0')) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 80348528-8034881C 342E68 02F4+00 3/3 6/6 0/0 .text DVDConvertPathToEntrynum */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDConvertPathToEntrynum() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDConvertPathToEntrynum.s"
|
||||
int DVDConvertPathToEntrynum(const char* pathPtr) {
|
||||
const char* ptr;
|
||||
char* stringPtr;
|
||||
BOOL isDir;
|
||||
u32 length;
|
||||
u32 dirLookAt;
|
||||
u32 i;
|
||||
const char* origPathPtr = pathPtr;
|
||||
const char* extentionStart;
|
||||
BOOL illegal;
|
||||
BOOL extention;
|
||||
|
||||
dirLookAt = currentDirectory;
|
||||
|
||||
while (1) {
|
||||
if (*pathPtr == '\0') {
|
||||
return (s32)dirLookAt;
|
||||
} else if (*pathPtr == '/') {
|
||||
dirLookAt = 0;
|
||||
pathPtr++;
|
||||
continue;
|
||||
} else if (*pathPtr == '.') {
|
||||
if (*(pathPtr + 1) == '.') {
|
||||
if (*(pathPtr + 2) == '/') {
|
||||
dirLookAt = parentDir(dirLookAt);
|
||||
pathPtr += 3;
|
||||
continue;
|
||||
} else if (*(pathPtr + 2) == '\0') {
|
||||
return (s32)parentDir(dirLookAt);
|
||||
}
|
||||
} else if (*(pathPtr + 1) == '/') {
|
||||
pathPtr += 2;
|
||||
continue;
|
||||
} else if (*(pathPtr + 1) == '\0') {
|
||||
return (s32)dirLookAt;
|
||||
}
|
||||
}
|
||||
|
||||
if (__DVDLongFileNameFlag == 0) {
|
||||
extention = FALSE;
|
||||
illegal = FALSE;
|
||||
|
||||
for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) {
|
||||
if (*ptr == '.') {
|
||||
if ((ptr - pathPtr > 8) || (extention == TRUE)) {
|
||||
illegal = TRUE;
|
||||
break;
|
||||
}
|
||||
extention = TRUE;
|
||||
extentionStart = ptr + 1;
|
||||
|
||||
} else if (*ptr == ' ')
|
||||
illegal = TRUE;
|
||||
}
|
||||
|
||||
if ((extention == TRUE) && (ptr - extentionStart > 3))
|
||||
illegal = TRUE;
|
||||
|
||||
if (illegal)
|
||||
OSPanic(lit_118, 387, lit_119, origPathPtr);
|
||||
} else {
|
||||
for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++)
|
||||
;
|
||||
}
|
||||
|
||||
isDir = (*ptr == '\0') ? FALSE : TRUE;
|
||||
length = (u32)(ptr - pathPtr);
|
||||
|
||||
ptr = pathPtr;
|
||||
|
||||
for (i = dirLookAt + 1; i < nextDir(dirLookAt); i = entryIsDir(i) ? nextDir(i) : (i + 1)) {
|
||||
if ((entryIsDir(i) == FALSE) && (isDir == TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stringPtr = FstStringStart + stringOff(i);
|
||||
|
||||
if (isSame(ptr, stringPtr) == TRUE) {
|
||||
goto next_hier;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
next_hier:
|
||||
if (!isDir) {
|
||||
return (s32)i;
|
||||
}
|
||||
|
||||
dirLookAt = i;
|
||||
pathPtr += length + 1;
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034881C-80348890 34315C 0074+00 0/0 3/3 0/0 .text DVDFastOpen */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDFastOpen() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDFastOpen.s"
|
||||
int DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) {
|
||||
if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fileInfo->start_address = filePosition(entrynum);
|
||||
fileInfo->length = fileLength(entrynum);
|
||||
fileInfo->callback = (DVDCallback)NULL;
|
||||
fileInfo->block.state = DVD_STATE_END;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D1448-803D1480 02E568 0037+01 1/1 0/0 0/0 .data @140 */
|
||||
SECTION_DATA static char lit_140[] = "Warning: DVDOpen(): file '%s' was not found under %s.\n";
|
||||
|
||||
/* 80348890-80348958 3431D0 00C8+00 0/0 3/3 1/1 .text DVDOpen */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDOpen() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDOpen.s"
|
||||
BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo) {
|
||||
s32 entry;
|
||||
char currentDir[128];
|
||||
|
||||
entry = DVDConvertPathToEntrynum(fileName);
|
||||
|
||||
if (0 > entry) {
|
||||
DVDGetCurrentDir(currentDir, 128);
|
||||
OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (entryIsDir(entry)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fileInfo->start_address = filePosition(entry);
|
||||
fileInfo->length = fileLength(entry);
|
||||
fileInfo->callback = (DVDCallback)NULL;
|
||||
fileInfo->block.state = DVD_STATE_END;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80348958-8034897C 343298 0024+00 0/0 4/4 2/2 .text DVDClose */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDClose() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDClose.s"
|
||||
BOOL DVDClose(DVDFileInfo* fileInfo) {
|
||||
DVDCancel(&(fileInfo->block));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline u32 myStrncpy(char* dest, char* src, u32 maxlen) {
|
||||
u32 i = maxlen;
|
||||
|
||||
while ((i > 0) && (*src != 0)) {
|
||||
*dest++ = *src++;
|
||||
i--;
|
||||
}
|
||||
|
||||
return (maxlen - i);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034897C-80348ADC 3432BC 0160+00 2/2 0/0 0/0 .text entryToPath */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void entryToPath() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/entryToPath.s"
|
||||
static u32 entryToPath(u32 entry, char* path, u32 maxlen) {
|
||||
char* name;
|
||||
u32 loc;
|
||||
|
||||
if (entry == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
name = FstStringStart + stringOff(entry);
|
||||
|
||||
loc = entryToPath(parentDir(entry), path, maxlen);
|
||||
|
||||
if (loc == maxlen) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
*(path + loc++) = '/';
|
||||
|
||||
loc += myStrncpy(path + loc, name, maxlen - loc);
|
||||
|
||||
return loc;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80348ADC-80348C30 34341C 0154+00 1/1 0/0 0/0 .text DVDConvertEntrynumToPath */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void DVDConvertEntrynumToPath() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDConvertEntrynumToPath.s"
|
||||
static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) {
|
||||
u32 loc;
|
||||
|
||||
loc = entryToPath((u32)entrynum, path, maxlen);
|
||||
|
||||
if (loc == maxlen) {
|
||||
path[maxlen - 1] = '\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (entryIsDir(entrynum)) {
|
||||
if (loc == maxlen - 1) {
|
||||
path[loc] = '\0';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
path[loc++] = '/';
|
||||
}
|
||||
|
||||
path[loc] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
|
||||
/* 80348C30-80348CF4 343570 00C4+00 1/1 0/0 0/0 .text DVDGetCurrentDir */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void DVDGetCurrentDir() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDGetCurrentDir.s"
|
||||
BOOL DVDGetCurrentDir(char* path, u32 maxlen) {
|
||||
return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80348CF4-80348D54 343634 0060+00 0/0 2/2 0/0 .text DVDChangeDir */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDChangeDir() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDChangeDir.s"
|
||||
BOOL DVDChangeDir(const char* dirName) {
|
||||
s32 entry;
|
||||
entry = DVDConvertPathToEntrynum(dirName);
|
||||
if ((entry < 0) || (entryIsDir(entry) == FALSE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
currentDirectory = (u32)entry;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D1480-803D14B4 02E5A0 0034+00 1/1 0/0 0/0 .data @239 */
|
||||
SECTION_DATA static char lit_239[] = "DVDReadAsync(): specified area is out of the file ";
|
||||
|
||||
#define DVD_MIN_TRANSFER_SIZE 32
|
||||
|
||||
/* 80348D54-80348E14 343694 00C0+00 0/0 2/2 0/0 .text DVDReadAsyncPrio */
|
||||
#ifdef NONMATCHING
|
||||
BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
|
||||
DVDCallback callback, s32 prio) {
|
||||
|
||||
if (!((0 <= offset) && (offset <= fileInfo->length))) {
|
||||
OSPanic(lit_118, 750, lit_239);
|
||||
}
|
||||
|
||||
if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
|
||||
OSPanic(lit_118, 756, lit_239);
|
||||
}
|
||||
|
||||
fileInfo->callback = callback;
|
||||
DVDReadAbsAsyncPrio(&(fileInfo->block), addr, length, (s32)(fileInfo->start_address + offset),
|
||||
cbForReadAsync, prio);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDReadAsyncPrio() {
|
||||
asm BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
|
||||
DVDCallback callback, s32 prio) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDReadAsyncPrio.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, memb) ((u32) & ((type*)0)->memb)
|
||||
#endif
|
||||
|
||||
/* 80348E14-80348E44 343754 0030+00 1/1 0/0 0/0 .text cbForReadAsync */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void cbForReadAsync() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/cbForReadAsync.s"
|
||||
static void cbForReadAsync(s32 result, DVDCommandBlock* block) {
|
||||
DVDFileInfo* fileInfo;
|
||||
|
||||
fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, block));
|
||||
if (fileInfo->callback) {
|
||||
(fileInfo->callback)(result, fileInfo);
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D14B4-803D14E4 02E5D4 002F+01 1/1 0/0 0/0 .data @265 */
|
||||
SECTION_DATA static char lit_265[] = "DVDRead(): specified area is out of the file ";
|
||||
|
||||
/* 80348E44-80348F5C 343784 0118+00 0/0 9/9 3/3 .text DVDReadPrio */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDReadPrio() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDReadPrio.s"
|
||||
int DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) {
|
||||
BOOL result;
|
||||
DVDCommandBlock* block;
|
||||
s32 state;
|
||||
BOOL enabled;
|
||||
int retVal;
|
||||
|
||||
if (!((0 <= offset) && (offset <= fileInfo->length))) {
|
||||
OSPanic(lit_118, 820, "DVDRead(): specified area is out of the file ");
|
||||
}
|
||||
|
||||
if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
|
||||
OSPanic(lit_118, 826, "DVDRead(): specified area is out of the file ");
|
||||
}
|
||||
|
||||
block = &(fileInfo->block);
|
||||
|
||||
result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->start_address + offset),
|
||||
cbForReadSync, prio);
|
||||
|
||||
if (result == FALSE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
while (1) {
|
||||
state = ((volatile DVDCommandBlock*)block)->state;
|
||||
|
||||
if (state == DVD_STATE_END) {
|
||||
retVal = (s32)block->transferred_size;
|
||||
break;
|
||||
}
|
||||
if (state == DVD_STATE_FATAL_ERROR) {
|
||||
retVal = DVD_RESULT_FATAL_ERROR;
|
||||
break;
|
||||
}
|
||||
if (state == DVD_STATE_CANCELED) {
|
||||
retVal = DVD_RESULT_CANCELED;
|
||||
break;
|
||||
}
|
||||
|
||||
OSSleepThread(&__DVDThreadQueue);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return retVal;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80348F5C-80348F80 34389C 0024+00 1/1 0/0 0/0 .text cbForReadSync */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void cbForReadSync() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/cbForReadSync.s"
|
||||
}
|
||||
#pragma pop
|
||||
/* This is based on the revolution SDK, these may not match in all cases */
|
||||
static void cbForReadSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); }
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D14E4-803D1520 02E604 003A+02 1/1 0/0 0/0 .data @311 */
|
||||
SECTION_DATA static char lit_311[] = "Warning: DVDOpenDir(): file '%s' was not found under %s.\n";
|
||||
|
||||
/* 80348F80-80349040 3438C0 00C0+00 0/0 3/3 0/0 .text DVDOpenDir */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDOpenDir() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDOpenDir.s"
|
||||
BOOL DVDOpenDir(const char* dirName, DVDDirectory* dir) {
|
||||
s32 entry;
|
||||
char currentDir[128];
|
||||
entry = DVDConvertPathToEntrynum(dirName);
|
||||
|
||||
if (entry < 0) {
|
||||
DVDGetCurrentDir(currentDir, 128);
|
||||
OSReport(lit_311, dirName, currentDir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!entryIsDir(entry)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dir->entry_number = (u32)entry;
|
||||
dir->location = (u32)entry + 1;
|
||||
dir->next = nextDir(entry);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80349040-803490E4 343980 00A4+00 0/0 3/3 0/0 .text DVDReadDir */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void DVDReadDir() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdfs/DVDReadDir.s"
|
||||
BOOL DVDReadDir(DVDDirectory* dir, DVDDirectoryEntry* dirent) {
|
||||
u32 loc = dir->location;
|
||||
if ((loc <= dir->entry_number) || (dir->next <= loc)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dirent->entry_number = loc;
|
||||
dirent->is_directory = entryIsDir(loc);
|
||||
dirent->name = FstStringStart + stringOff(loc);
|
||||
|
||||
dir->location = entryIsDir(loc) ? nextDir(loc) : (loc + 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 803490E4-803490EC 343A24 0008+00 0/0 3/3 0/0 .text DVDCloseDir */
|
||||
u8 DVDCloseDir() {
|
||||
BOOL DVDCloseDir() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+118
-43
@@ -6,78 +6,153 @@
|
||||
#include "dolphin/dvd/dvdqueue.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/types.h"
|
||||
#include "dolphin/dvd/dvd.h"
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
|
||||
//
|
||||
// Forward References:
|
||||
//
|
||||
|
||||
void __DVDClearWaitingQueue();
|
||||
void __DVDPushWaitingQueue();
|
||||
void __DVDPopWaitingQueue();
|
||||
void __DVDCheckWaitingQueue();
|
||||
void __DVDDequeueWaitingQueue();
|
||||
BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block);
|
||||
DVDCommandBlock* __DVDPopWaitingQueue(void);
|
||||
BOOL __DVDCheckWaitingQueue(void);
|
||||
BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block);
|
||||
|
||||
//
|
||||
// External References:
|
||||
//
|
||||
|
||||
void OSDisableInterrupts();
|
||||
void OSRestoreInterrupts();
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
//
|
||||
|
||||
#define MAX_QUEUES 4
|
||||
|
||||
typedef struct {
|
||||
DVDCommandBlock* next;
|
||||
DVDCommandBlock* prev;
|
||||
} DVDQueue;
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 8044C998-8044C9B8 0796B8 0020+00 4/4 0/0 0/0 .bss WaitingQueue */
|
||||
static u8 WaitingQueue[32];
|
||||
static DVDQueue WaitingQueue[MAX_QUEUES];
|
||||
|
||||
/* 8034B874-8034B8AC 3461B4 0038+00 0/0 5/5 0/0 .text __DVDClearWaitingQueue */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDClearWaitingQueue() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdqueue/__DVDClearWaitingQueue.s"
|
||||
void __DVDClearWaitingQueue(void) {
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
DVDCommandBlock* q;
|
||||
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
q->next = q;
|
||||
q->prev = q;
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034B8AC-8034B914 3461EC 0068+00 0/0 5/5 0/0 .text __DVDPushWaitingQueue */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDPushWaitingQueue() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdqueue/__DVDPushWaitingQueue.s"
|
||||
BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) {
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[prio]);
|
||||
|
||||
q->prev->next = block;
|
||||
block->prev = q->prev;
|
||||
block->next = q;
|
||||
q->prev = block;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline DVDCommandBlock* PopWaitingQueuePrio(s32 prio) {
|
||||
DVDCommandBlock* tmp;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[prio]);
|
||||
|
||||
tmp = q->next;
|
||||
q->next = tmp->next;
|
||||
tmp->next->prev = q;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
tmp->next = (DVDCommandBlock*)NULL;
|
||||
tmp->prev = (DVDCommandBlock*)NULL;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034B914-8034B9B4 346254 00A0+00 0/0 2/2 0/0 .text __DVDPopWaitingQueue */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDPopWaitingQueue() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdqueue/__DVDPopWaitingQueue.s"
|
||||
DVDCommandBlock* __DVDPopWaitingQueue(void) {
|
||||
u32 i;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
if (q->next != q) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return PopWaitingQueuePrio((s32)i);
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return (DVDCommandBlock*)NULL;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034B9B4-8034BA0C 3462F4 0058+00 0/0 1/1 0/0 .text __DVDCheckWaitingQueue */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDCheckWaitingQueue() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdqueue/__DVDCheckWaitingQueue.s"
|
||||
BOOL __DVDCheckWaitingQueue(void) {
|
||||
u32 i;
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* q;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
for (i = 0; i < MAX_QUEUES; i++) {
|
||||
q = (DVDCommandBlock*)&(WaitingQueue[i]);
|
||||
if (q->next != q) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034BA0C-8034BA6C 34634C 0060+00 0/0 1/1 0/0 .text __DVDDequeueWaitingQueue */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __DVDDequeueWaitingQueue() {
|
||||
nofralloc
|
||||
#include "asm/dolphin/dvd/dvdqueue/__DVDDequeueWaitingQueue.s"
|
||||
BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block) {
|
||||
BOOL enabled;
|
||||
DVDCommandBlock* prev;
|
||||
DVDCommandBlock* next;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
prev = block->prev;
|
||||
next = block->next;
|
||||
|
||||
if ((prev == (DVDCommandBlock*)NULL) || (next == (DVDCommandBlock*)NULL)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
+488
-176
@@ -10,6 +10,9 @@
|
||||
#define REG_MAX 5
|
||||
#define REG(chan, idx) (__EXIRegs[((chan)*REG_MAX) + (idx)])
|
||||
|
||||
#define CPR_CS(x) ((1u << (x)) << 7)
|
||||
#define CPR_CLK(x) ((x) << 4)
|
||||
|
||||
#define EXI_0CR(tstart, dma, rw, tlen) \
|
||||
((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4))
|
||||
|
||||
@@ -28,10 +31,10 @@ static void EXTIntrruptHandler(s16 interrupt, OSContext* context);
|
||||
// External References:
|
||||
//
|
||||
|
||||
void __OSEnableBarnacle();
|
||||
void __OSEnableBarnacle(u32, u32);
|
||||
void __div2i();
|
||||
void memmove();
|
||||
extern u8 __OSInIPL[4 + 4 /* padding */];
|
||||
extern s32 __OSInIPL;
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
@@ -42,28 +45,27 @@ extern u8 __OSInIPL[4 + 4 /* padding */];
|
||||
static EXIControl Ecb[3];
|
||||
|
||||
/* 80342C0C-80342D00 33D54C 00F4+00 4/4 0/0 0/0 .text SetExiInterruptMask */
|
||||
#ifdef NONMATCHING
|
||||
static void SetExiInterruptMask(s32 chan, EXIControl* exi) {
|
||||
EXIControl* exi2;
|
||||
|
||||
exi2 = &Ecb[2];
|
||||
switch (chan) {
|
||||
case 0:
|
||||
if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) {
|
||||
if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & EXI_STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
|
||||
} else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) {
|
||||
if (exi->exiCallback == 0 || (exi->state & EXI_STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
|
||||
} else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (__OSGetInterruptHandler(OS_INTR_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) {
|
||||
if (__OSGetInterruptHandler(OS_INTR_PI_DEBUG) == 0 || (exi->state & EXI_STATE_LOCKED)) {
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
|
||||
} else {
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
|
||||
@@ -71,19 +73,8 @@ static void SetExiInterruptMask(s32 chan, EXIControl* exi) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void SetExiInterruptMask(s32 chan, EXIControl* exi) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/SetExiInterruptMask.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 80342D00-80342F5C 33D640 025C+00 2/2 9/9 0/0 .text EXIImm */
|
||||
#ifdef NONMATCHING
|
||||
s32 EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
@@ -122,20 +113,8 @@ s32 EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm s32 EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIImm.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 80342F5C-80342FFC 33D89C 00A0+00 0/0 7/7 0/0 .text EXIImmEx */
|
||||
// needs compiler lmw/lwz order patch
|
||||
#ifdef NONMATCHING
|
||||
s32 EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) {
|
||||
s32 xLen;
|
||||
|
||||
@@ -154,19 +133,8 @@ s32 EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) {
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm s32 EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIImmEx.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 80342FFC-803430E8 33D93C 00EC+00 0/0 4/4 0/0 .text EXIDma */
|
||||
#ifdef NONMATCHING
|
||||
BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
@@ -193,146 +161,361 @@ BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIDma.s"
|
||||
|
||||
static void CompleteTransfer(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
u8* buf;
|
||||
u32 data;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
if (exi->state & EXI_STATE_BUSY) {
|
||||
if ((exi->state & EXI_STATE_IMM) && (len = exi->immLen)) {
|
||||
buf = exi->immBuf;
|
||||
data = REG(chan, 4);
|
||||
for (i = 0; i < len; i++) {
|
||||
*buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
exi->state &= ~EXI_STATE_BUSY;
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 803430E8-80343334 33DA28 024C+00 2/2 9/9 0/0 .text EXISync */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXISync(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXISync.s"
|
||||
BOOL EXISync(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL rc = FALSE;
|
||||
BOOL enabled;
|
||||
|
||||
while (exi->state & EXI_STATE_SELECTED) {
|
||||
if (((REG(chan, 3) & 1) >> 0) == 0) {
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->state & EXI_STATE_SELECTED) {
|
||||
CompleteTransfer(chan);
|
||||
if (__OSGetDIConfig() != 0xff || (OSGetConsoleType() & 0xf0000000) == 0x20000000 ||
|
||||
exi->immLen != 4 || (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) ||
|
||||
(REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER &&
|
||||
REG(chan, 4) != 0x04220001) ||
|
||||
__OSDeviceCode == 0x8200) {
|
||||
rc = TRUE;
|
||||
}
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80343334-8034337C 33DC74 0048+00 4/4 0/0 0/0 .text EXIClearInterrupts */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIClearInterrupts.s"
|
||||
u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) {
|
||||
u32 cpr;
|
||||
u32 prev;
|
||||
|
||||
prev = cpr = REG(chan, 0);
|
||||
cpr &= 0x7f5;
|
||||
if (exi)
|
||||
cpr |= 2;
|
||||
if (tc)
|
||||
cpr |= 8;
|
||||
if (ext)
|
||||
cpr |= 0x800;
|
||||
REG(chan, 0) = cpr;
|
||||
return prev;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034337C-803433F8 33DCBC 007C+00 0/0 6/6 0/0 .text EXISetExiCallback */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXISetExiCallback.s"
|
||||
EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
EXICallback prev;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
prev = exi->exiCallback;
|
||||
exi->exiCallback = exiCallback;
|
||||
|
||||
if (chan != 2) {
|
||||
SetExiInterruptMask(chan, exi);
|
||||
} else {
|
||||
SetExiInterruptMask(0, &Ecb[0]);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return prev;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0);
|
||||
|
||||
/* 803433F8-8034356C 33DD38 0174+00 7/7 0/0 0/0 .text __EXIProbe */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL __EXIProbe(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/__EXIProbe.s"
|
||||
static BOOL __EXIProbe(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
u32 cpr;
|
||||
s32 t;
|
||||
|
||||
if (chan == 2) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
rc = TRUE;
|
||||
enabled = OSDisableInterrupts();
|
||||
cpr = REG(chan, 0);
|
||||
if (!(exi->state & EXI_STATE_ATTACHED)) {
|
||||
if (cpr & 0x00000800) {
|
||||
EXIClearInterrupts(chan, FALSE, FALSE, TRUE);
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
}
|
||||
|
||||
if (cpr & 0x00001000) {
|
||||
t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1;
|
||||
if (__EXIProbeStartTime[chan] == 0) {
|
||||
__EXIProbeStartTime[chan] = t;
|
||||
}
|
||||
if (t - __EXIProbeStartTime[chan] < 300 / 100) {
|
||||
rc = FALSE;
|
||||
}
|
||||
} else {
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
} else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) {
|
||||
__EXIProbeStartTime[chan] = exi->idTime = 0;
|
||||
rc = FALSE;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034356C-803435EC 33DEAC 0080+00 0/0 5/5 0/0 .text EXIProbe */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXIProbe(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIProbe.s"
|
||||
BOOL EXIProbe(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL rc;
|
||||
u32 id;
|
||||
|
||||
rc = __EXIProbe(chan);
|
||||
if (rc && exi->idTime == 0) {
|
||||
rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 803435EC-803436A0 33DF2C 00B4+00 0/0 1/1 0/0 .text EXIProbeEx */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm s32 EXIProbeEx(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIProbeEx.s"
|
||||
|
||||
s32 EXIProbeEx(s32 chan) {
|
||||
if (EXIProbe(chan)) {
|
||||
return 1;
|
||||
} else if (__EXIProbeStartTime[chan] != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 803436A0-803437AC 33DFE0 010C+00 0/0 2/2 0/0 .text EXIAttach */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXIAttach(s32 chan, EXICallback extCallback) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIAttach.s"
|
||||
static BOOL __EXIAttach(s32 chan, EXICallback extCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
|
||||
|
||||
exi->extCallback = extCallback;
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan));
|
||||
exi->state |= EXI_STATE_ATTACHED;
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL EXIAttach(s32 chan, EXICallback extCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
|
||||
EXIProbe(chan);
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->idTime == 0) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
rc = __EXIAttach(chan, extCallback);
|
||||
OSRestoreInterrupts(enabled);
|
||||
return rc;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 803437AC-80343868 33E0EC 00BC+00 0/0 3/3 0/0 .text EXIDetach */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXIDetach(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIDetach.s"
|
||||
BOOL EXIDetach(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & EXI_STATE_ATTACHED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
if ((exi->state & EXI_STATE_LOCKED) && exi->dev == 0) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state &= ~EXI_STATE_ATTACHED;
|
||||
__OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80343868-80343994 33E1A8 012C+00 1/1 12/12 0/0 .text EXISelect */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXISelect(s32 chan, u32 dev, u32 freq) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXISelect.s"
|
||||
BOOL EXISelect(s32 chan, u32 dev, u32 freq) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
u32 cpr;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if ((exi->state & EXI_STATE_SELECTED) ||
|
||||
chan != 2 && (dev == 0 && !(exi->state & EXI_STATE_ATTACHED) && !__EXIProbe(chan) ||
|
||||
!(exi->state & EXI_STATE_LOCKED) || (exi->dev != dev)))
|
||||
{
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state |= EXI_STATE_SELECTED;
|
||||
cpr = REG(chan, 0);
|
||||
cpr &= 0x405;
|
||||
cpr |= CPR_CS(dev) | CPR_CLK(freq);
|
||||
REG(chan, 0) = cpr;
|
||||
|
||||
if (exi->state & EXI_STATE_ATTACHED) {
|
||||
switch (chan) {
|
||||
case 0:
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
|
||||
break;
|
||||
case 1:
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80343994-80343AA4 33E2D4 0110+00 1/1 15/15 0/0 .text EXIDeselect */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXIDeselect(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIDeselect.s"
|
||||
BOOL EXIDeselect(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
u32 cpr;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & EXI_STATE_SELECTED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
exi->state &= ~EXI_STATE_SELECTED;
|
||||
cpr = REG(chan, 0);
|
||||
REG(chan, 0) = cpr & 0x405;
|
||||
|
||||
if (exi->state & EXI_STATE_ATTACHED) {
|
||||
switch (chan) {
|
||||
case 0:
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
|
||||
break;
|
||||
case 1:
|
||||
__OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
if (chan != 2 && (cpr & CPR_CS(0))) {
|
||||
return __EXIProbe(chan) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80343AA4-80343B6C 33E3E4 00C8+00 1/1 0/0 0/0 .text EXIIntrruptHandler */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void EXIIntrruptHandler(s16 interrupt, OSContext* context) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIIntrruptHandler.s"
|
||||
static void EXIIntrruptHandler(s16 interrupt, OSContext* context) {
|
||||
s32 chan;
|
||||
EXIControl* exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - OS_INTR_EXI_0_EXI) / 3;
|
||||
exi = &Ecb[chan];
|
||||
EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
|
||||
callback = exi->exiCallback;
|
||||
if (callback) {
|
||||
OSContext exceptionContext;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80343B6C-80343D84 33E4AC 0218+00 1/1 0/0 0/0 .text TCIntrruptHandler */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void TCIntrruptHandler(s16 interrupt, OSContext* context) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/TCIntrruptHandler.s"
|
||||
static void TCIntrruptHandler(s16 interrupt, OSContext* context) {
|
||||
OSContext exceptionContext;
|
||||
s32 chan;
|
||||
EXIControl* exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - OS_INTR_EXI_0_TC) / 3;
|
||||
exi = &Ecb[chan];
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK(interrupt));
|
||||
EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
|
||||
callback = exi->tcCallback;
|
||||
if (callback) {
|
||||
exi->tcCallback = 0;
|
||||
CompleteTransfer(chan);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80343D84-80343E54 33E6C4 00D0+00 1/1 0/0 0/0 .text EXTIntrruptHandler */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void EXTIntrruptHandler(s16 interrupt, OSContext* context) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXTIntrruptHandler.s"
|
||||
static void EXTIntrruptHandler(s16 interrupt, OSContext* context) {
|
||||
s32 chan;
|
||||
EXIControl* exi;
|
||||
EXICallback callback;
|
||||
|
||||
chan = (interrupt - OS_INTR_EXI_0_EXT) / 3;
|
||||
__OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
|
||||
exi = &Ecb[chan];
|
||||
callback = exi->extCallback;
|
||||
exi->state &= ~EXI_STATE_ATTACHED;
|
||||
if (callback) {
|
||||
OSContext exceptionContext;
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
|
||||
exi->extCallback = 0;
|
||||
callback(chan, context);
|
||||
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(context);
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D10A8-803D10F0 02E1C8 0045+03 1/0 0/0 0/0 .data @1 */
|
||||
@@ -343,59 +526,187 @@ SECTION_DATA static char lit_1[] =
|
||||
SECTION_SDATA static const char* __EXIVersion = lit_1;
|
||||
|
||||
/* 804516D8-804516E0 000BD8 0004+04 2/2 0/0 0/0 .sbss IDSerialPort1 */
|
||||
static u8 IDSerialPort1[4 + 4 /* padding */];
|
||||
static u32 IDSerialPort1[2 /* padding */];
|
||||
|
||||
/* 80343E54-80344028 33E794 01D4+00 0/0 1/1 0/0 .text EXIInit */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void EXIInit(void) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIInit.s"
|
||||
void EXIInit(void) {
|
||||
u32 idSerial;
|
||||
|
||||
while (((REG(0, 3) & 1) == 1) || ((REG(1, 3) & 1) == 1) || ((REG(2, 3) & 1) == 1)) {
|
||||
}
|
||||
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC |
|
||||
OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI |
|
||||
OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT |
|
||||
OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC);
|
||||
|
||||
REG(0, 0) = 0;
|
||||
REG(1, 0) = 0;
|
||||
REG(2, 0) = 0;
|
||||
|
||||
REG(0, 0) = 0x00002000;
|
||||
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_0_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_0_TC, TCIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_0_EXT, EXTIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_1_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_1_TC, TCIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_1_EXT, EXTIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_2_EXI, EXIIntrruptHandler);
|
||||
__OSSetInterruptHandler(OS_INTR_EXI_2_TC, TCIntrruptHandler);
|
||||
|
||||
EXIGetID(0, 2, IDSerialPort1);
|
||||
if (__OSInIPL) {
|
||||
__EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
|
||||
Ecb[0].idTime = Ecb[1].idTime = 0;
|
||||
__EXIProbe(0);
|
||||
__EXIProbe(1);
|
||||
} else if (EXIGetID(0, 0, &idSerial) && idSerial == 0x7010000) {
|
||||
__OSEnableBarnacle(1, 0);
|
||||
} else if (EXIGetID(1, 0, &idSerial) && idSerial == 0x7010000) {
|
||||
__OSEnableBarnacle(0, 2);
|
||||
}
|
||||
|
||||
OSRegisterVersion(__EXIVersion);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80344028-8034411C 33E968 00F4+00 1/1 10/10 0/0 .text EXILock */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXILock.s"
|
||||
BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
int i;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (exi->state & EXI_STATE_LOCKED) {
|
||||
if (unlockedCallback) {
|
||||
for (i = 0; i < exi->items; i++) {
|
||||
if (exi->queue[i].dev == dev) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
exi->queue[exi->items].callback = unlockedCallback;
|
||||
exi->queue[exi->items].dev = dev;
|
||||
exi->items++;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
exi->state |= EXI_STATE_LOCKED;
|
||||
exi->dev = dev;
|
||||
SetExiInterruptMask(chan, exi);
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8034411C-803441F8 33EA5C 00DC+00 0/0 14/14 0/0 .text EXIUnlock */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL EXIUnlock(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIUnlock.s"
|
||||
BOOL EXIUnlock(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL enabled;
|
||||
EXICallback unlockedCallback;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
if (!(exi->state & EXI_STATE_LOCKED)) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return FALSE;
|
||||
}
|
||||
exi->state &= ~EXI_STATE_LOCKED;
|
||||
SetExiInterruptMask(chan, exi);
|
||||
|
||||
if (0 < exi->items) {
|
||||
unlockedCallback = exi->queue[0].callback;
|
||||
if (0 < --exi->items) {
|
||||
memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items);
|
||||
}
|
||||
unlockedCallback(chan, 0);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 803441F8-80344210 33EB38 0018+00 0/0 2/2 0/0 .text EXIGetState */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm u32 EXIGetState(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/EXIGetState.s"
|
||||
u32 EXIGetState(s32 chan) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
|
||||
return (u32)exi->state;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80344210-80344238 33EB50 0028+00 1/1 0/0 0/0 .text UnlockedHandler */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void UnlockedHandler(s32 chan, OSContext* context) {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIBios/UnlockedHandler.s"
|
||||
static void UnlockedHandler(s32 chan, OSContext* context) {
|
||||
u32 id;
|
||||
|
||||
EXIGetID(chan, 0, &id);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80344238-803445E8 33EB78 03B0+00 5/5 3/3 0/0 .text EXIGetID */
|
||||
// Use of add. instead of add
|
||||
#ifdef NONMATCHING
|
||||
s32 EXIGetID(s32 chan, u32 dev, u32* id) {
|
||||
EXIControl* exi = &Ecb[chan];
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
s32 startTime;
|
||||
BOOL enabled;
|
||||
|
||||
if (exi == (EXIControl*)NULL && dev == 2 && IDSerialPort1[0] != 0) {
|
||||
*id = IDSerialPort1[0];
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (chan < 2 && dev == 0) {
|
||||
if (!__EXIProbe(chan)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (exi->idTime == __EXIProbeStartTime[chan]) {
|
||||
*id = exi->id;
|
||||
return exi->idTime;
|
||||
}
|
||||
|
||||
if (!__EXIAttach(chan, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
startTime = __EXIProbeStartTime[chan];
|
||||
}
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
|
||||
err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL);
|
||||
if (!err) {
|
||||
err = !EXISelect(chan, dev, EXI_FREQ_1M);
|
||||
if (!err) {
|
||||
cmd = 0;
|
||||
err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, id, 4, EXI_READ, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
}
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
if (chan < 2 && dev == 0) {
|
||||
EXIDetach(chan);
|
||||
enabled = OSDisableInterrupts();
|
||||
err |= (startTime != __EXIProbeStartTime[chan]);
|
||||
if (!err) {
|
||||
exi->id = *id;
|
||||
exi->idTime = startTime;
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
|
||||
return err ? 0 : exi->idTime;
|
||||
}
|
||||
|
||||
return err ? 0 : !0;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
@@ -404,6 +715,7 @@ asm s32 EXIGetID(s32 chan, u32 dev, u32* id) {
|
||||
#include "asm/exi/EXIBios/EXIGetID.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D10F0-803D1100 02E210 000F+01 0/0 0/0 0/0 .data @473 */
|
||||
|
||||
+168
-49
@@ -5,85 +5,204 @@
|
||||
|
||||
#include "dolphin/exi/EXIUart.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/exi/EXIBios.h"
|
||||
#include "dolphin/types.h"
|
||||
|
||||
//
|
||||
// Forward References:
|
||||
//
|
||||
|
||||
static void ProbeBarnacle();
|
||||
void __OSEnableBarnacle();
|
||||
void InitializeUART();
|
||||
void WriteUARTN();
|
||||
|
||||
//
|
||||
// External References:
|
||||
//
|
||||
|
||||
void OSGetConsoleType();
|
||||
void EXIImm();
|
||||
void EXISync();
|
||||
void EXIAttach();
|
||||
void EXIDetach();
|
||||
void EXISelect();
|
||||
void EXIDeselect();
|
||||
void EXILock();
|
||||
void EXIUnlock();
|
||||
void EXIGetID();
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
//
|
||||
|
||||
#define EXI_TX 0x800400u
|
||||
#define EXI_MAGIC 0xa5ff005a
|
||||
|
||||
/* 803445E8-80344774 33EF28 018C+00 1/1 0/0 0/0 .text ProbeBarnacle */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void ProbeBarnacle() {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIUart/ProbeBarnacle.s"
|
||||
static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) {
|
||||
BOOL err;
|
||||
u32 cmd;
|
||||
|
||||
if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
err = !EXILock(chan, dev, NULL);
|
||||
if (!err) {
|
||||
err = !EXISelect(chan, dev, EXI_FREQ_1M);
|
||||
if (!err) {
|
||||
cmd = 0x20011300;
|
||||
err = FALSE;
|
||||
err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIImm(chan, revision, 4, EXI_READ, NULL);
|
||||
err |= !EXISync(chan);
|
||||
err |= !EXIDeselect(chan);
|
||||
}
|
||||
EXIUnlock(chan);
|
||||
}
|
||||
|
||||
if (chan != 2 && dev == 0) {
|
||||
EXIDetach(chan);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (*revision != 0xFFFFFFFF) ? TRUE : FALSE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 804516E0-804516E4 000BE0 0004+00 3/3 0/0 0/0 .sbss Chan */
|
||||
static u8 Chan[4];
|
||||
static s32 Chan;
|
||||
|
||||
/* 804516E4-804516E8 000BE4 0004+00 3/3 0/0 0/0 .sbss Dev */
|
||||
static u8 Dev[4];
|
||||
static u32 Dev;
|
||||
|
||||
/* 804516E8-804516EC 000BE8 0004+00 3/3 0/0 0/0 .sbss Enabled */
|
||||
static u8 Enabled[4];
|
||||
static u32 Enabled;
|
||||
|
||||
/* 804516EC-804516F0 000BEC 0004+00 2/2 0/0 0/0 .sbss BarnacleEnabled */
|
||||
static u8 BarnacleEnabled[4];
|
||||
static u32 BarnacleEnabled;
|
||||
|
||||
/* 80344774-80344930 33F0B4 01BC+00 0/0 1/1 0/0 .text __OSEnableBarnacle */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __OSEnableBarnacle() {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIUart/__OSEnableBarnacle.s"
|
||||
void __OSEnableBarnacle(s32 chan, u32 dev) {
|
||||
u32 id;
|
||||
|
||||
if (EXIGetID(chan, dev, &id)) {
|
||||
switch (id) {
|
||||
case 0xffffffff:
|
||||
case EXI_MEMORY_CARD_59:
|
||||
case EXI_MEMORY_CARD_123:
|
||||
case EXI_MEMORY_CARD_251:
|
||||
case EXI_MEMORY_CARD_507:
|
||||
case EXI_USB_ADAPTER:
|
||||
case EXI_NPDP_GDEV:
|
||||
case EXI_MODEM:
|
||||
case EXI_MARLIN:
|
||||
case 0x04220000:
|
||||
case 0x04020100:
|
||||
case 0x04020200:
|
||||
case 0x04020300:
|
||||
case 0x04040404:
|
||||
case 0x04060000:
|
||||
case 0x04120000:
|
||||
case 0x04130000:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_59:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_123:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_251:
|
||||
case 0x80000000 | EXI_MEMORY_CARD_507:
|
||||
break;
|
||||
default:
|
||||
if (ProbeBarnacle(chan, dev, &id)) {
|
||||
Chan = chan;
|
||||
Dev = dev;
|
||||
Enabled = BarnacleEnabled = EXI_MAGIC;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80344930-803449A0 33F270 0070+00 0/0 1/1 0/0 .text InitializeUART */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void InitializeUART() {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIUart/InitializeUART.s"
|
||||
u32 InitializeUART(u32 baudRate) {
|
||||
if (BarnacleEnabled == EXI_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) {
|
||||
Enabled = 0;
|
||||
return 2;
|
||||
} else {
|
||||
Chan = 0;
|
||||
Dev = 1;
|
||||
Enabled = EXI_MAGIC;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 ReadUARTN(void* bytes, unsigned long length) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int QueueLength(void) {
|
||||
u32 cmd;
|
||||
|
||||
if (!EXISelect(Chan, Dev, EXI_FREQ_8M))
|
||||
return -1;
|
||||
|
||||
cmd = EXI_TX << 6;
|
||||
EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
EXISync(Chan);
|
||||
|
||||
EXIImm(Chan, &cmd, 1, EXI_READ, NULL);
|
||||
EXISync(Chan);
|
||||
EXIDeselect(Chan);
|
||||
|
||||
return 16 - (int)((cmd >> 24) & 0xff);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 803449A0-80344BA0 33F2E0 0200+00 0/0 1/1 0/0 .text WriteUARTN */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void WriteUARTN() {
|
||||
nofralloc
|
||||
#include "asm/exi/EXIUart/WriteUARTN.s"
|
||||
}
|
||||
#pragma pop
|
||||
u32 WriteUARTN(const void* buf, unsigned long len) {
|
||||
u32 cmd;
|
||||
int qLen;
|
||||
long xLen;
|
||||
char* ptr;
|
||||
BOOL locked;
|
||||
u32 error;
|
||||
|
||||
if (Enabled != EXI_MAGIC)
|
||||
return 2;
|
||||
|
||||
locked = EXILock(Chan, Dev, 0);
|
||||
if (!locked) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ptr = (char*)buf; ptr - buf < len; ptr++) {
|
||||
if (*ptr == '\n')
|
||||
*ptr = '\r';
|
||||
}
|
||||
|
||||
error = 0;
|
||||
cmd = (EXI_TX | 0x2000000) << 6;
|
||||
while (len) {
|
||||
qLen = QueueLength();
|
||||
if (qLen < 0) {
|
||||
error = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (qLen < 12 && qLen < len)
|
||||
continue;
|
||||
|
||||
if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) {
|
||||
error = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
|
||||
EXISync(Chan);
|
||||
|
||||
while (qLen && len) {
|
||||
if (qLen < 4 && qLen < len)
|
||||
break;
|
||||
xLen = (len < 4) ? (long)len : 4;
|
||||
EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL);
|
||||
(u8*)buf += xLen;
|
||||
len -= xLen;
|
||||
qLen -= xLen;
|
||||
EXISync(Chan);
|
||||
}
|
||||
EXIDeselect(Chan);
|
||||
}
|
||||
|
||||
EXIUnlock(Chan);
|
||||
return error;
|
||||
}
|
||||
@@ -10,16 +10,18 @@ LIBEXI_A_O_FILES := \
|
||||
$(BUILD_DIR)/libs/dolphin/exi/EXIBios.o \
|
||||
$(BUILD_DIR)/libs/dolphin/exi/EXIUart.o \
|
||||
|
||||
LIBEXI_A_CFLAGS := \
|
||||
LIBEXI_A_CFLAGS = \
|
||||
-Cpp_exceptions off \
|
||||
-proc gekko \
|
||||
-fp hard \
|
||||
-fp_contract on \
|
||||
-nodefaults \
|
||||
-str reuse \
|
||||
-inline auto \
|
||||
-RTTI off \
|
||||
-maxerrors 5 \
|
||||
-enum int $(INCLUDES) \
|
||||
-O4,p \
|
||||
$(if $(filter %EXIBios.c, $<),-O3,-O4),p \
|
||||
-lang=c \
|
||||
|
||||
LIBEXI_A_LDFLAGS := \
|
||||
@@ -37,10 +39,11 @@ $(BUILD_DIR)/libs/dolphin/exi/%.o: libs/dolphin/exi/%.c $(BUILD_DIR)/libs/dolphi
|
||||
@mkdir -p $(@D)
|
||||
@echo building... $<
|
||||
@$(ICONV) -f UTF-8 -t CP932 < $< > $(basename $@).c
|
||||
@$(FRANK_CC) $(LIBEXI_A_CFLAGS) -c -o $(@:.o=.po) $(basename $@).c
|
||||
@$(DOLPHIN_LIB_CC) $(LIBEXI_A_CFLAGS) $(DEPFLAGS) -c -o $(dir $@) $(basename $@).c
|
||||
@if [ -z '$(DISABLE_DEPS)' ]; then tools/transform-dep.py '$(basename $@).d' '$(basename $@).d'; touch -c $@; fi
|
||||
@echo Frank is fixing $@
|
||||
@$(PYTHON) $(FRANK) $@ $@ $@
|
||||
@$(PYTHON) $(FRANK) $@ $(@:.o=.po) $@
|
||||
|
||||
ifndef DISABLE_DEPS
|
||||
LIBEXI_A_D_FILES := $(LIBEXI_A_O_FILES:.o=.d)
|
||||
|
||||
@@ -58,6 +58,7 @@ LIBOS_A_CFLAGS := \
|
||||
-fp hard \
|
||||
-nodefaults \
|
||||
-str reuse \
|
||||
-inline auto \
|
||||
-RTTI off \
|
||||
-maxerrors 5 \
|
||||
-enum int $(INCLUDES) \
|
||||
@@ -79,10 +80,11 @@ $(BUILD_DIR)/libs/dolphin/os/%.o: libs/dolphin/os/%.c $(BUILD_DIR)/libs/dolphin/
|
||||
@mkdir -p $(@D)
|
||||
@echo building... $<
|
||||
@$(ICONV) -f UTF-8 -t CP932 < $< > $(basename $@).c
|
||||
@$(FRANK_CC) $(LIBOS_A_CFLAGS) -c -o $(@:.o=.po) $(basename $@).c
|
||||
@$(DOLPHIN_LIB_CC) $(LIBOS_A_CFLAGS) $(DEPFLAGS) -c -o $(dir $@) $(basename $@).c
|
||||
@if [ -z '$(DISABLE_DEPS)' ]; then tools/transform-dep.py '$(basename $@).d' '$(basename $@).d'; touch -c $@; fi
|
||||
@echo Frank is fixing $@
|
||||
@$(PYTHON) $(FRANK) $@ $@ $@
|
||||
@$(PYTHON) $(FRANK) $@ $(@:.o=.po) $@
|
||||
|
||||
ifndef DISABLE_DEPS
|
||||
LIBOS_A_D_FILES := $(LIBOS_A_O_FILES:.o=.d)
|
||||
|
||||
+85
-113
@@ -5,6 +5,9 @@
|
||||
|
||||
#include "dolphin/os/OSCache.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/base/PPCArch.h"
|
||||
#include "dolphin/db/db.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
#include "dolphin/os/OSError.h"
|
||||
#include "dolphin/os/OSInterrupt.h"
|
||||
|
||||
@@ -12,18 +15,6 @@
|
||||
// External References:
|
||||
//
|
||||
|
||||
void OSReport();
|
||||
void PPCMfmsr();
|
||||
void PPCMtmsr();
|
||||
void PPCMfhid0();
|
||||
void PPCMfl2cr();
|
||||
void PPCMtl2cr();
|
||||
void PPCHalt();
|
||||
void PPCMfhid2();
|
||||
void PPCMthid2();
|
||||
void OSDumpContext();
|
||||
void DBPrintf();
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
//
|
||||
@@ -334,7 +325,7 @@ do_invalidate:
|
||||
|
||||
/* 8033B814-8033B838 336154 0024+00 1/1 0/0 0/0 .text LCStoreBlocks */
|
||||
static asm void LCStoreBlocks(register void* destAddr, register void* srcAddr,
|
||||
register u32 blockNum) {
|
||||
register u32 blockNum){
|
||||
// clang-format off
|
||||
nofralloc
|
||||
|
||||
@@ -349,8 +340,7 @@ static asm void LCStoreBlocks(register void* destAddr, register void* srcAddr,
|
||||
|
||||
blr
|
||||
// clang-format on
|
||||
}
|
||||
/* 8033B838-8033B8E4 336178 00AC+00 0/0 0/0 3/3 .text LCStoreData */
|
||||
} /* 8033B838-8033B8E4 336178 00AC+00 0/0 0/0 3/3 .text LCStoreData */
|
||||
u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) {
|
||||
u32 blocks = (nBytes + 31) / 32;
|
||||
u32 ret = (blocks + 127) / 128;
|
||||
@@ -372,7 +362,7 @@ u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) {
|
||||
}
|
||||
|
||||
/* 8033B8E4-8033B8F8 336224 0014+00 0/0 0/0 3/3 .text LCQueueWait */
|
||||
asm void LCQueueWait(register u32 len){
|
||||
asm void LCQueueWait(register u32 len) {
|
||||
// clang-format off
|
||||
nofralloc
|
||||
|
||||
@@ -386,116 +376,98 @@ asm void LCQueueWait(register u32 len){
|
||||
}
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803CF510-803CF53C 02C630 0029+03 3/3 0/0 0/0 .data @63 */
|
||||
SECTION_DATA static char lit_63[] = ">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n";
|
||||
|
||||
static void L2Disable(void) {
|
||||
__sync();
|
||||
PPCMtl2cr(PPCMfl2cr() & ~0x80000000);
|
||||
__sync();
|
||||
}
|
||||
|
||||
/* 8033B8F8-8033B990 336238 0098+00 1/1 0/0 0/0 .text L2GlobalInvalidate */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void L2GlobalInvalidate(void) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSCache/L2GlobalInvalidate.s"
|
||||
void L2GlobalInvalidate(void) {
|
||||
L2Disable();
|
||||
PPCMtl2cr(PPCMfl2cr() | 0x00200000);
|
||||
while (PPCMfl2cr() & 0x00000001u)
|
||||
;
|
||||
PPCMtl2cr(PPCMfl2cr() & ~0x00200000);
|
||||
while (PPCMfl2cr() & 0x00000001u) {
|
||||
DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n");
|
||||
}
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803CF53C-803CF554 02C65C 0018+00 0/1 0/0 0/0 .data @84 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_84[] = "Machine check received\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF554-803CF570 02C674 001B+01 0/1 0/0 0/0 .data @85 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_85[] = "HID2 = 0x%x SRR1 = 0x%x\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF570-803CF5A0 02C690 0030+00 0/1 0/0 0/0 .data @86 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_86[] = "Machine check was not DMA/locked cache related\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF5A0-803CF5DC 02C6C0 003C+00 0/1 0/0 0/0 .data @87 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_87[] = "DMAErrorHandler(): An error occurred while processing DMA.\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF5DC-803CF614 02C6FC 0037+01 0/1 0/0 0/0 .data @88 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_88[] = "The following errors have been detected and cleared :\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF614-803CF654 02C734 003F+01 0/1 0/0 0/0 .data @89 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_89[] =
|
||||
"\t- Requested a locked cache tag that was already in the cache\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF654-803CF680 02C774 0029+03 0/1 0/0 0/0 .data @90 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_90[] = "\t- DMA attempted to access normal cache\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF680-803CF6A0 02C7A0 001D+03 0/1 0/0 0/0 .data @91 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_91[] = "\t- DMA missed in data cache\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF6A0-803CF6BC 02C7C0 0019+03 0/1 0/0 0/0 .data @92 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_92[] = "\t- DMA queue overflowed\n";
|
||||
#pragma pop
|
||||
|
||||
/* 8033B990-8033BAF0 3362D0 0160+00 1/1 0/0 0/0 .text DMAErrorHandler */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void DMAErrorHandler(s32 error, OSContext* context) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSCache/DMAErrorHandler.s"
|
||||
void DMAErrorHandler(u16 error, OSContext* context, ...) {
|
||||
u32 hid2 = PPCMfhid2();
|
||||
|
||||
OSReport("Machine check received\n");
|
||||
OSReport("HID2 = 0x%x SRR1 = 0x%x\n", hid2, context->srr1);
|
||||
if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) ||
|
||||
!(context->srr1 & SRR1_DMA_BIT)) {
|
||||
OSReport("Machine check was not DMA/locked cache related\n");
|
||||
OSDumpContext(context);
|
||||
PPCHalt();
|
||||
}
|
||||
|
||||
OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n");
|
||||
OSReport("The following errors have been detected and cleared :\n");
|
||||
|
||||
if (hid2 & HID2_DCHERR) {
|
||||
OSReport("\t- Requested a locked cache tag that was already in the cache\n");
|
||||
}
|
||||
|
||||
if (hid2 & HID2_DNCERR) {
|
||||
OSReport("\t- DMA attempted to access normal cache\n");
|
||||
}
|
||||
|
||||
if (hid2 & HID2_DCMERR) {
|
||||
OSReport("\t- DMA missed in data cache\n");
|
||||
}
|
||||
|
||||
if (hid2 & HID2_DQOERR) {
|
||||
OSReport("\t- DMA queue overflowed\n");
|
||||
}
|
||||
|
||||
// write hid2 back to clear the error bits
|
||||
PPCMthid2(hid2);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803CF6BC-803CF6D8 02C7DC 0019+03 0/1 0/0 0/0 .data @104 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_104[] = "L1 i-caches initialized\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF6D8-803CF6F4 02C7F8 0019+03 0/1 0/0 0/0 .data @105 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_105[] = "L1 d-caches initialized\n";
|
||||
#pragma pop
|
||||
static void L2Init(void) {
|
||||
u32 oldMSR;
|
||||
oldMSR = PPCMfmsr();
|
||||
__sync();
|
||||
PPCMtmsr(MSR_IR | MSR_DR);
|
||||
__sync();
|
||||
L2Disable();
|
||||
L2GlobalInvalidate();
|
||||
PPCMtmsr(oldMSR);
|
||||
}
|
||||
|
||||
/* 803CF6F4-803CF70C 02C814 0016+02 0/1 0/0 0/0 .data @106 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_106[] = "L2 cache initialized\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF70C-803CF740 02C82C 002E+06 0/1 0/0 0/0 .data @107 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_107[] = "Locked cache machine check handler installed\n";
|
||||
#pragma pop
|
||||
void L2Enable(void) {
|
||||
PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I);
|
||||
}
|
||||
|
||||
/* 8033BAF0-8033BBE4 336430 00F4+00 0/0 2/2 0/0 .text __OSCacheInit */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm void __OSCacheInit(void) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSCache/__OSCacheInit.s"
|
||||
void __OSCacheInit() {
|
||||
if (!(PPCMfhid0() & HID0_ICE)) {
|
||||
ICEnable();
|
||||
DBPrintf("L1 i-caches initialized\n");
|
||||
}
|
||||
if (!(PPCMfhid0() & HID0_DCE)) {
|
||||
DCEnable();
|
||||
DBPrintf("L1 d-caches initialized\n");
|
||||
}
|
||||
|
||||
if (!(PPCMfl2cr() & L2CR_L2E)) {
|
||||
L2Init();
|
||||
L2Enable();
|
||||
DBPrintf("L2 cache initialized\n");
|
||||
}
|
||||
|
||||
OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler);
|
||||
DBPrintf("Locked cache machine check handler installed\n");
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
+72
-16
@@ -6,8 +6,9 @@
|
||||
#include "dolphin/os/OSError.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/base/PPCArch.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
#include "dolphin/dsp/dsp.h"
|
||||
#include "dolphin/dvd/dvdlow.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
|
||||
OSThread* __OSCurrentThread : (OS_BASE_CACHED | 0x00E4);
|
||||
OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC);
|
||||
@@ -17,10 +18,9 @@ volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8);
|
||||
// External References:
|
||||
//
|
||||
|
||||
extern u8 __OSLastInterruptSrr0[4];
|
||||
extern u8 __OSLastInterrupt[2 + 6 /* padding */];
|
||||
extern u8 __OSLastInterruptTime[4];
|
||||
extern u8 data_80451684[4];
|
||||
extern u32 __OSLastInterruptSrr0;
|
||||
extern s16 __OSLastInterrupt[4];
|
||||
extern OSTime __OSLastInterruptTime;
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
@@ -36,26 +36,82 @@ OSErrorHandler __OSErrorTable[17];
|
||||
SECTION_SDATA extern u32 __OSFpscrEnableBits = FPSCR_ENABLE;
|
||||
|
||||
/* 8033C580-8033C798 336EC0 0218+00 0/0 4/4 0/0 .text OSSetErrorHandler */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSError/OSSetErrorHandler.s"
|
||||
OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) {
|
||||
OSErrorHandler oldHandler;
|
||||
BOOL enabled;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
oldHandler = __OSErrorTable[error];
|
||||
__OSErrorTable[error] = handler;
|
||||
|
||||
if (error == EXCEPTION_FLOATING_POINT_EXCEPTION) {
|
||||
u32 msr;
|
||||
u32 fpscr;
|
||||
OSThread* thread;
|
||||
|
||||
msr = PPCMfmsr();
|
||||
PPCMtmsr(msr | MSR_FP);
|
||||
fpscr = PPCMffpscr();
|
||||
if (handler) {
|
||||
for (thread = __OSActiveThreadQueue.head; thread;
|
||||
thread = thread->active_threads_link.next)
|
||||
{
|
||||
thread->context.srr1 |= MSR_FE0 | MSR_FE1;
|
||||
if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) {
|
||||
int i;
|
||||
thread->context.state |= OS_CONTEXT_STATE_FPSAVED;
|
||||
for (i = 0; i < 32; ++i) {
|
||||
*(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL;
|
||||
*(u64*)&thread->context.ps[i] = (u64)0xffffffffffffffffLL;
|
||||
}
|
||||
thread->context.fpscr = FPSCR_NI;
|
||||
}
|
||||
thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE;
|
||||
thread->context.fpscr &=
|
||||
~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI |
|
||||
FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX |
|
||||
FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI);
|
||||
}
|
||||
fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE;
|
||||
msr |= MSR_FE0 | MSR_FE1;
|
||||
} else {
|
||||
for (thread = __OSActiveThreadQueue.head; thread;
|
||||
thread = thread->active_threads_link.next)
|
||||
{
|
||||
thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1);
|
||||
thread->context.fpscr &= ~FPSCR_ENABLE;
|
||||
thread->context.fpscr &=
|
||||
~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI |
|
||||
FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX |
|
||||
FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI);
|
||||
}
|
||||
fpscr &= ~FPSCR_ENABLE;
|
||||
msr &= ~(MSR_FE0 | MSR_FE1);
|
||||
}
|
||||
|
||||
fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI |
|
||||
FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX |
|
||||
FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI);
|
||||
|
||||
PPCMtfpscr(fpscr);
|
||||
PPCMtmsr(msr);
|
||||
}
|
||||
|
||||
OSRestoreInterrupts(enabled);
|
||||
return oldHandler;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803CF918-803CF930 02CA38 0016+02 1/1 0/0 0/0 .data @13 */
|
||||
SECTION_DATA static char lit_13[] = " in \"%s\" on line %d.\n";
|
||||
SECTION_DATA static char lit_13[] = " in \"%s\" on line %d.\n";
|
||||
|
||||
/* 803CF930-803CF958 02CA50 0026+02 0/0 0/0 0/0 .data @14 */
|
||||
// /* 803CF930-803CF958 02CA50 0026+02 0/0 0/0 0/0 .data @14 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_14[] = "\nAddress: Back Chain LR Save\n";
|
||||
#pragma pop
|
||||
|
||||
/* 803CF958-803CF974 02CA78 001C+00 0/0 0/0 0/0 .data @15 */
|
||||
// /* 803CF958-803CF974 02CA78 001C+00 0/0 0/0 0/0 .data @15 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_15[] = "0x%08x: 0x%08x 0x%08x\n";
|
||||
@@ -265,7 +321,7 @@ void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsi
|
||||
break;
|
||||
}
|
||||
|
||||
OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt,
|
||||
OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt[0],
|
||||
__OSLastInterruptSrr0, __OSLastInterruptTime);
|
||||
|
||||
PPCHalt();
|
||||
|
||||
@@ -16,6 +16,7 @@ LIBSI_A_CFLAGS := \
|
||||
-fp hard \
|
||||
-nodefaults \
|
||||
-str reuse \
|
||||
-inline auto \
|
||||
-RTTI off \
|
||||
-maxerrors 5 \
|
||||
-enum int $(INCLUDES) \
|
||||
@@ -37,10 +38,11 @@ $(BUILD_DIR)/libs/dolphin/si/%.o: libs/dolphin/si/%.c $(BUILD_DIR)/libs/dolphin/
|
||||
@mkdir -p $(@D)
|
||||
@echo building... $<
|
||||
@$(ICONV) -f UTF-8 -t CP932 < $< > $(basename $@).c
|
||||
@$(FRANK_CC) $(LIBSI_A_CFLAGS) -c -o $(@:.o=.po) $(basename $@).c
|
||||
@$(DOLPHIN_LIB_CC) $(LIBSI_A_CFLAGS) $(DEPFLAGS) -c -o $(dir $@) $(basename $@).c
|
||||
@if [ -z '$(DISABLE_DEPS)' ]; then tools/transform-dep.py '$(basename $@).d' '$(basename $@).d'; touch -c $@; fi
|
||||
@echo Frank is fixing $@
|
||||
@$(PYTHON) $(FRANK) $@ $@ $@
|
||||
@$(PYTHON) $(FRANK) $@ $(@:.o=.po) $@
|
||||
|
||||
ifndef DISABLE_DEPS
|
||||
LIBSI_A_D_FILES := $(LIBSI_A_O_FILES:.o=.d)
|
||||
|
||||
+78
-94
@@ -259,8 +259,6 @@ static asm void SIInterruptHandler(OSInterrupt interrupt, OSContext* context) {
|
||||
#endif
|
||||
|
||||
/* 8034523C-803452D4 33FB7C 0098+00 2/2 0/0 0/0 .text SIEnablePollingInterrupt */
|
||||
// lwz and mr swapped
|
||||
#ifdef NONMATCHING
|
||||
static BOOL SIEnablePollingInterrupt(BOOL enable) {
|
||||
BOOL enabled;
|
||||
BOOL rc;
|
||||
@@ -283,16 +281,6 @@ static BOOL SIEnablePollingInterrupt(BOOL enable) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm BOOL SIEnablePollingInterrupt(BOOL enable) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SIEnablePollingInterrupt.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 803452D4-803453A0 33FC14 00CC+00 0/0 1/1 0/0 .text SIRegisterPollingHandler */
|
||||
BOOL SIRegisterPollingHandler(OSInterruptHandler handler) {
|
||||
@@ -413,8 +401,6 @@ static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u
|
||||
}
|
||||
|
||||
/* 80345754-803457D0 340094 007C+00 1/1 1/1 0/0 .text SIGetStatus */
|
||||
// lwz and mr swap
|
||||
#ifdef NONMATCHING
|
||||
u32 SIGetStatus(s32 chan) {
|
||||
BOOL enabled;
|
||||
u32 sr;
|
||||
@@ -432,16 +418,6 @@ u32 SIGetStatus(s32 chan) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return sr;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm u32 SIGetStatus(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SIGetStatus.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 803457D0-803457E4 340110 0014+00 0/0 4/4 0/0 .text SISetCommand */
|
||||
void SISetCommand(s32 chan, u32 command) {
|
||||
@@ -455,7 +431,6 @@ void SITransferCommands(void) {
|
||||
|
||||
/* 803457F4-80345860 340134 006C+00 0/0 1/1 0/0 .text SISetXY */
|
||||
// needs compiler epilogue patch
|
||||
#ifdef NONMATCHING
|
||||
u32 SISetXY(u32 x, u32 y) {
|
||||
u32 poll;
|
||||
BOOL enabled;
|
||||
@@ -471,19 +446,8 @@ u32 SISetXY(u32 x, u32 y) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return poll;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm u32 SISetXY(u32 x, u32 y) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SISetXY.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 80345860-803458FC 3401A0 009C+00 0/0 3/3 0/0 .text SIEnablePolling */
|
||||
#ifdef NONMATCHING
|
||||
u32 SIEnablePolling(u32 poll) {
|
||||
BOOL enabled;
|
||||
u32 en;
|
||||
@@ -515,16 +479,6 @@ u32 SIEnablePolling(u32 poll) {
|
||||
|
||||
return poll;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm u32 SIEnablePolling(u32 poll) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SIEnablePolling.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 803458FC-80345968 34023C 006C+00 0/0 6/6 0/0 .text SIDisablePolling */
|
||||
u32 SIDisablePolling(u32 poll) {
|
||||
@@ -549,7 +503,6 @@ u32 SIDisablePolling(u32 poll) {
|
||||
}
|
||||
|
||||
/* 80345968-80345A3C 3402A8 00D4+00 1/1 0/0 0/0 .text SIGetResponseRaw */
|
||||
#ifdef NONMATCHING
|
||||
static BOOL SIGetResponseRaw(s32 chan) {
|
||||
u32 sr;
|
||||
|
||||
@@ -562,19 +515,8 @@ static BOOL SIGetResponseRaw(s32 chan) {
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm BOOL SIGetResponseRaw(s32 chan) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SIGetResponseRaw.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 80345A3C-80345B00 34037C 00C4+00 0/0 4/4 0/0 .text SIGetResponse */
|
||||
#ifdef NONMATCHING
|
||||
BOOL SIGetResponse(s32 chan, void* data) {
|
||||
BOOL rc;
|
||||
BOOL enabled;
|
||||
@@ -590,16 +532,6 @@ BOOL SIGetResponse(s32 chan, void* data) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL SIGetResponse(s32 chan, void* data) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SIGetResponse.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* 80345B00-80345B8C 340440 008C+00 1/1 0/0 0/0 .text AlarmHandler */
|
||||
static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
|
||||
@@ -664,15 +596,85 @@ static u8 cmdTypeAndStatus_372[4];
|
||||
extern u32 __PADFixBits;
|
||||
u32 __PADFixBits;
|
||||
|
||||
/* 80345CF8-80345F90 340638 0298+00 2/2 0/0 0/0 .text GetTypeCallback */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm void GetTypeCallback(s32 chan, u32 error, OSContext* context) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/GetTypeCallback.s"
|
||||
static inline void CallTypeAndStatusCallback(s32 chan, u32 type) {
|
||||
SITypeAndStatusCallback callback;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
callback = TypeCallback[chan][i];
|
||||
if (callback) {
|
||||
TypeCallback[chan][i] = 0;
|
||||
callback(chan, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 80345CF8-80345F90 340638 0298+00 2/2 0/0 0/0 .text GetTypeCallback */
|
||||
static void GetTypeCallback(s32 chan, u32 error, OSContext* context) {
|
||||
static u32 cmdFixDevice[SI_MAX_CHAN];
|
||||
u32 type;
|
||||
u32 chanBit;
|
||||
BOOL fix;
|
||||
u32 id;
|
||||
|
||||
Type[chan] &= ~SI_ERROR_BUSY;
|
||||
Type[chan] |= error;
|
||||
TypeTime[chan] = __OSGetSystemTime();
|
||||
|
||||
type = Type[chan];
|
||||
|
||||
chanBit = SI_CHAN0_BIT >> chan;
|
||||
fix = (BOOL)(__PADFixBits & chanBit);
|
||||
__PADFixBits &= ~chanBit;
|
||||
|
||||
if ((error &
|
||||
(SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) ||
|
||||
(type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN || !(type & SI_GC_WIRELESS) ||
|
||||
(type & SI_WIRELESS_IR))
|
||||
{
|
||||
OSSetWirelessID(chan, 0);
|
||||
CallTypeAndStatusCallback(chan, Type[chan]);
|
||||
return;
|
||||
}
|
||||
|
||||
id = (u32)(OSGetWirelessID(chan) << 8);
|
||||
|
||||
if (fix && (id & SI_WIRELESS_FIX_ID)) {
|
||||
cmdFixDevice[chan] = 0x4Eu << 24 | (id & SI_WIRELESS_TYPE_ID) | SI_WIRELESS_FIX_ID;
|
||||
Type[chan] = SI_ERROR_BUSY;
|
||||
SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type & SI_WIRELESS_FIX_ID) {
|
||||
if ((id & SI_WIRELESS_TYPE_ID) != (type & SI_WIRELESS_TYPE_ID)) {
|
||||
if (!(id & SI_WIRELESS_FIX_ID)) {
|
||||
id = type & SI_WIRELESS_TYPE_ID;
|
||||
id |= SI_WIRELESS_FIX_ID;
|
||||
OSSetWirelessID(chan, (u16)((id >> 8) & 0xffff));
|
||||
}
|
||||
|
||||
cmdFixDevice[chan] = 0x4E << 24 | id;
|
||||
Type[chan] = SI_ERROR_BUSY;
|
||||
SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0);
|
||||
return;
|
||||
}
|
||||
} else if (type & SI_WIRELESS_RECEIVED) {
|
||||
id = type & SI_WIRELESS_TYPE_ID;
|
||||
id |= SI_WIRELESS_FIX_ID;
|
||||
|
||||
OSSetWirelessID(chan, (u16)((id >> 8) & 0xffff));
|
||||
|
||||
cmdFixDevice[chan] = 0x4E << 24 | id;
|
||||
Type[chan] = SI_ERROR_BUSY;
|
||||
SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0);
|
||||
return;
|
||||
} else {
|
||||
OSSetWirelessID(chan, 0);
|
||||
}
|
||||
|
||||
CallTypeAndStatusCallback(chan, Type[chan]);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 80345F90-80346154 3408D0 01C4+00 2/2 3/3 0/0 .text SIGetType */
|
||||
#ifdef NONMATCHING
|
||||
@@ -722,8 +724,6 @@ asm u32 SIGetType(s32 chan) {
|
||||
#endif
|
||||
|
||||
/* 80346154-80346290 340A94 013C+00 0/0 6/6 0/0 .text SIGetTypeAsync */
|
||||
// needs compiler epilogue patch
|
||||
#ifdef NONMATCHING
|
||||
u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) {
|
||||
BOOL enabled;
|
||||
u32 type;
|
||||
@@ -748,16 +748,6 @@ u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) {
|
||||
OSRestoreInterrupts(enabled);
|
||||
return type;
|
||||
}
|
||||
#else
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/si/SIBios/SIGetTypeAsync.s"
|
||||
}
|
||||
#pragma pop
|
||||
#endif
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D1220-803D122C 02E340 000C+00 0/0 0/0 0/0 .data @457 */
|
||||
@@ -827,9 +817,3 @@ SECTION_DATA static char lit_467[] = "Keyboard";
|
||||
#pragma force_active on
|
||||
SECTION_DATA static char lit_468[] = "Steering";
|
||||
#pragma pop
|
||||
|
||||
/* 8044C820-8044C830 079540 0010+00 0/0 0/0 0/0 .bss cmdFixDevice$327 */
|
||||
#pragma push
|
||||
#pragma force_active on
|
||||
static u8 cmdFixDevice[16];
|
||||
#pragma pop
|
||||
|
||||
Reference in New Issue
Block a user