Work on dvd, si, os and exi (#249)

This commit is contained in:
hatal175
2023-01-23 17:02:24 +02:00
committed by GitHub
parent 3c75397776
commit 4e9dcd14ef
75 changed files with 1701 additions and 4480 deletions
+192 -191
View File
@@ -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 */
+6 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+6 -3
View File
@@ -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)
+3 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+3 -1
View File
@@ -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
View File
@@ -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