Link in arq and most of dvd

This commit is contained in:
gamemasterplc 2024-11-10 18:27:13 -06:00
parent 92bc9d78fe
commit 53fba73d33
10 changed files with 1487 additions and 10 deletions

View file

@ -0,0 +1,56 @@
#include "dolphin/DVDPriv.h"
#include "dolphin/OSRtcPriv.h"
static u32 ErrorTable[] = {
0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000,
0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01,
0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0,
};
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;
}
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);
}

356
src/dolphin/dvd/dvdfs.c Normal file
View file

@ -0,0 +1,356 @@
#include "dolphin/DVDPriv.h"
#include "dolphin/os.h"
#include "dolphin/os/OSBootInfo.h"
typedef struct FSTEntry FSTEntry;
struct FSTEntry {
unsigned int isDirAndStringOff;
unsigned int parentOrPosition;
unsigned int nextEntryOrLength;
};
static OSBootInfo* BootInfo;
static FSTEntry* FstStart;
static char* FstStringStart;
static u32 MaxEntryNum;
static u32 currentDirectory = 0;
OSThreadQueue __DVDThreadQueue;
u32 __DVDLongFileNameFlag = 0;
static void cbForReadAsync(s32 result, DVDCommandBlock* block);
static void cbForReadSync(s32 result, DVDCommandBlock* block);
static void cbForSeekAsync(s32 result, DVDCommandBlock* block);
static void cbForSeekSync(s32 result, DVDCommandBlock* block);
static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block);
static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block);
void __DVDFSInit() {
BootInfo = (OSBootInfo*)OSPhysicalToCached(0);
FstStart = (FSTEntry*)BootInfo->FSTLocation;
if (FstStart) {
MaxEntryNum = FstStart[0].nextEntryOrLength;
FstStringStart = (char*)&(FstStart[MaxEntryNum]);
}
}
/* 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 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;
}
s32 DVDConvertPathToEntrynum(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(__FILE__, 376,
"DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): "
"specified directory or file (%s) doesn't match standard 8.3 format. This is a "
"temporary restriction and will be removed soon\n",
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;
}
}
BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) {
if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) {
return FALSE;
}
fileInfo->startAddr = filePosition(entrynum);
fileInfo->length = fileLength(entrynum);
fileInfo->callback = (DVDCallback)NULL;
fileInfo->cb.state = DVD_STATE_END;
return TRUE;
}
BOOL DVDOpen(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->startAddr = filePosition(entry);
fileInfo->length = fileLength(entry);
fileInfo->callback = (DVDCallback)NULL;
fileInfo->cb.state = DVD_STATE_END;
return TRUE;
}
BOOL DVDClose(DVDFileInfo* fileInfo) {
DVDCancel(&(fileInfo->cb));
return TRUE;
}
static u32 myStrncpy(char* dest, char* src, u32 maxlen) {
u32 i = maxlen;
while ((i > 0) && (*src != 0)) {
*dest++ = *src++;
i--;
}
return (maxlen - i);
}
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;
}
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;
}
BOOL DVDGetCurrentDir(char* path, u32 maxlen) {
return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen);
}
BOOL DVDChangeDir(char* dirName) {
s32 entry;
entry = DVDConvertPathToEntrynum(dirName);
if ((entry < 0) || (entryIsDir(entry) == FALSE)) {
return FALSE;
}
currentDirectory = (u32)entry;
return TRUE;
}
BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
DVDCallback callback, s32 prio) {
if (!((0 <= offset) && (offset < fileInfo->length))) {
OSPanic(__FILE__, 739, "DVDReadAsync(): specified area is out of the file ");
}
if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
OSPanic(__FILE__, 745, "DVDReadAsync(): specified area is out of the file ");
}
fileInfo->callback = callback;
DVDReadAbsAsyncPrio(&(fileInfo->cb), addr, length, (s32)(fileInfo->startAddr + offset),
cbForReadAsync, prio);
return TRUE;
}
#ifndef offsetof
#define offsetof(type, memb) ((u32) & ((type*)0)->memb)
#endif
static void cbForReadAsync(s32 result, DVDCommandBlock* block) {
DVDFileInfo* fileInfo;
fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb));
if (fileInfo->callback) {
(fileInfo->callback)(result, fileInfo);
}
}
/* This is based on the revolution SDK, these may not match in all cases I have also left the line numbers at 0 */
BOOL DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) {
BOOL result;
DVDCommandBlock* block;
s32 state;
BOOL enabled;
s32 retVal;
if (!((0 <= offset) && (offset < fileInfo->length))) {
OSPanic(__FILE__, 809, "DVDRead(): specified area is out of the file ");
}
if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
OSPanic(__FILE__, 815, "DVDRead(): specified area is out of the file ");
}
block = &(fileInfo->cb);
result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->startAddr + 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->transferredSize;
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;
}
/* This is based on the revolution SDK, these may not match in all cases */
static void cbForReadSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); }

436
src/dolphin/dvd/dvdlow.c Normal file
View file

@ -0,0 +1,436 @@
#include "dolphin/DVDPriv.h"
#include "dolphin/os.h"
extern DVDDiskID* DVDGetCurrentDiskID();
extern OSTime __OSGetSystemTime();
static BOOL FirstRead = TRUE;
static volatile BOOL StopAtNextInt = FALSE;
static u32 LastLength = 0;
static DVDLowCallback Callback = NULL;
static DVDLowCallback ResetCoverCallback = NULL;
static volatile OSTime LastResetEnd = 0;
static volatile u32 ResetOccurred = FALSE;
static volatile BOOL WaitingCoverClose = FALSE;
static BOOL Breaking = FALSE;
static volatile u32 WorkAroundType = 0;
static u32 WorkAroundSeekLocation = 0;
static volatile OSTime LastReadFinished = 0;
static OSTime LastReadIssued = 0;
static volatile BOOL LastCommandWasRead = FALSE;
static vu32 NextCommandNumber = 0;
typedef struct DVDBuffer {
void* addr;
u32 length;
u32 offset;
} DVDBuffer;
typedef struct DVDCommand {
s32 cmd;
void* addr;
u32 length;
u32 offset;
DVDLowCallback callback;
} DVDCommand;
static DVDCommand CommandList[3];
static OSAlarm AlarmForWA;
static OSAlarm AlarmForTimeout;
static OSAlarm AlarmForBreak;
static DVDBuffer Prev;
static DVDBuffer Curr;
void __DVDInitWA() {
NextCommandNumber = 0;
CommandList[0].cmd = -1;
__DVDLowSetWAType(0, 0);
OSInitAlarm();
}
static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback);
static BOOL ProcessNextCommand() {
s32 n = NextCommandNumber;
ASSERT(n < 3);
if (CommandList[n].cmd == 1) {
++NextCommandNumber;
Read(CommandList[n].addr, CommandList[n].length, CommandList[n].offset,
CommandList[n].callback);
return TRUE;
} else if (CommandList[n].cmd == 2) {
++NextCommandNumber;
DVDLowSeek(CommandList[n].offset, CommandList[n].callback);
return TRUE;
}
return FALSE;
}
void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
DVDLowCallback cb;
OSContext exceptionContext;
u32 cause = 0;
u32 reg;
u32 intr;
u32 mask;
OSCancelAlarm(&AlarmForTimeout);
if (LastCommandWasRead) {
LastReadFinished = __OSGetSystemTime();
FirstRead = FALSE;
Prev.addr = Curr.addr;
Prev.length = Curr.length;
Prev.offset = Curr.offset;
if (StopAtNextInt == TRUE) {
cause |= 8;
}
}
LastCommandWasRead = FALSE;
StopAtNextInt = FALSE;
reg = __DIRegs[0];
mask = reg & 0x2a;
intr = (reg & 0x54) & (mask << 1);
if (intr & 0x40) {
cause |= 8;
}
if (intr & 0x10) {
cause |= 1;
}
if (intr & 4) {
cause |= 2;
}
if (cause) {
ResetOccurred = FALSE;
}
__DIRegs[0] = intr | mask;
if (ResetOccurred && (__OSGetSystemTime() - LastResetEnd) < OSMillisecondsToTicks(200)) {
reg = __DIRegs[1];
mask = reg & 0x2;
intr = (reg & 4) & (mask << 1);
if (intr & 4) {
if (ResetCoverCallback) {
ResetCoverCallback(4);
}
ResetCoverCallback = NULL;
}
__DIRegs[1] = __DIRegs[1];
} else if (WaitingCoverClose) {
reg = __DIRegs[1];
mask = reg & 2;
intr = (reg & 4) & (mask << 1);
if (intr & 4) {
cause |= 4;
}
__DIRegs[1] = intr | mask;
WaitingCoverClose = FALSE;
} else {
__DIRegs[1] = 0;
}
if ((cause & 8) && !Breaking) {
cause &= ~8;
}
if ((cause & 1)) {
if (ProcessNextCommand()) {
return;
}
} else {
CommandList[0].cmd = -1;
NextCommandNumber = 0;
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
if (cause) {
cb = Callback;
Callback = NULL;
if (cb) {
cb(cause);
}
Breaking = FALSE;
}
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
BOOL error = ProcessNextCommand();
ASSERTMSG(error != FALSE, "Failed assertion processed");
}
static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) {
OSContext tmpContext;
DVDLowCallback callback;
__OSMaskInterrupts(0x400);
OSClearContext(&tmpContext);
OSSetCurrentContext(&tmpContext);
callback = Callback;
Callback = NULL;
if (callback != NULL) {
callback(0x10);
}
OSClearContext(&tmpContext);
OSSetCurrentContext(context);
}
static void SetTimeoutAlarm(OSTime timeout) {
OSCreateAlarm(&AlarmForTimeout);
OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout);
}
static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
StopAtNextInt = FALSE;
LastCommandWasRead = TRUE;
Callback = callback;
LastReadIssued = __OSGetSystemTime();
__DIRegs[2] = 0xa8000000;
__DIRegs[3] = offset / 4;
__DIRegs[4] = length;
__DIRegs[5] = (u32)addr;
__DIRegs[6] = length;
LastLength = length;
__DIRegs[7] = 3;
if (length > 0xa00000) {
SetTimeoutAlarm(OSSecondsToTicks(20));
} else {
SetTimeoutAlarm(OSSecondsToTicks(10));
}
}
BOOL HitCache(DVDBuffer* cur, DVDBuffer* prev) {
u32 uVar1 = (prev->offset + prev->length - 1) >> 15;
u32 uVar2 = (cur->offset >> 15);
u32 iVar3 = (DVDGetCurrentDiskID()->streaming ? TRUE : FALSE) ? 5 : 15;
if ((uVar2 > uVar1 - 2) || (uVar2 < uVar1 + iVar3 + 3)) {
return TRUE;
}
return FALSE;
}
static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
CommandList[0].cmd = -1;
NextCommandNumber = 0;
Read(addr, length, offset, callback);
}
static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
u32 newOffset = offset & ~0x7FFF;
if (!newOffset) {
newOffset = 0;
} else {
newOffset += WorkAroundSeekLocation;
}
CommandList[0].cmd = 2;
CommandList[0].offset = newOffset;
CommandList[0].callback = callback;
CommandList[1].cmd = 1;
CommandList[1].addr = addr;
CommandList[1].length = length;
CommandList[1].offset = offset;
CommandList[1].callback = callback;
CommandList[2].cmd = -1;
NextCommandNumber = 0;
DVDLowSeek(newOffset, callback);
}
static void WaitBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback,
OSTime timeout) {
CommandList[0].cmd = 1;
CommandList[0].addr = addr;
CommandList[0].length = length;
CommandList[0].offset = offset;
CommandList[0].callback = callback;
CommandList[1].cmd = -1;
NextCommandNumber = 0;
OSCreateAlarm(&AlarmForWA);
OSSetAlarm(&AlarmForWA, timeout, AlarmHandler);
}
BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
OSTime diff;
u32 prev;
__DIRegs[6] = length;
Curr.addr = addr;
Curr.length = length;
Curr.offset = offset;
if (WorkAroundType == 0) {
DoJustRead(addr, length, offset, callback);
} else if (WorkAroundType == 1) {
if (FirstRead) {
SeekTwiceBeforeRead(addr, length, offset, callback);
} else {
if (!HitCache(&Curr, &Prev)) {
DoJustRead(addr, length, offset, callback);
} else {
prev = (Prev.offset + Prev.length - 1) >> 15;
if (prev == Curr.offset >> 15 || prev + 1 == Curr.offset >> 15) {
diff = __OSGetSystemTime() - LastReadFinished;
if (OSMillisecondsToTicks(5) < diff) {
DoJustRead(addr, length, offset, callback);
} else {
WaitBeforeRead(addr, length, offset, callback,
OSMillisecondsToTicks(5) - diff + OSMicrosecondsToTicks(500));
}
} else {
SeekTwiceBeforeRead(addr, length, offset, callback);
}
}
}
}
return TRUE;
}
BOOL DVDLowSeek(u32 offset, DVDLowCallback callback) {
ASSERTMSG(offset & 3, "DVDLowSeek(): offset must be a multiple of 4.");
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = 0xab000000;
__DIRegs[3] = offset / 4;
__DIRegs[7] = 1;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowWaitCoverClose(DVDLowCallback callback) {
Callback = callback;
WaitingCoverClose = TRUE;
StopAtNextInt = FALSE;
__DIRegs[1] = 2;
return TRUE;
}
BOOL DVDLowReadDiskID(DVDDiskID* diskID, DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = 0xa8000040;
__DIRegs[3] = 0;
__DIRegs[4] = sizeof(DVDDiskID);
__DIRegs[5] = (u32)diskID;
__DIRegs[6] = sizeof(DVDDiskID);
__DIRegs[7] = 3;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowStopMotor(DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = 0xe3000000;
__DIRegs[7] = 1;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowRequestError(DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = 0xe0000000;
__DIRegs[7] = 1;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowInquiry(DVDDriveInfo* info, DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = 0x12000000;
__DIRegs[4] = sizeof(DVDDriveInfo);
__DIRegs[5] = (u32)info;
__DIRegs[6] = sizeof(DVDDriveInfo);
__DIRegs[7] = 3;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowAudioStream(u32 subcmd, u32 length, u32 offset, DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = subcmd | 0xe1000000;
__DIRegs[3] = offset >> 2;
__DIRegs[4] = length;
__DIRegs[7] = 1;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowRequestAudioStatus(u32 subcmd, DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = subcmd | 0xe2000000;
__DIRegs[7] = 1;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) {
StopAtNextInt = FALSE;
Callback = callback;
__DIRegs[2] = 0xe4000000 | (enable != 0 ? 0x10000 : 0) | size;
__DIRegs[7] = 1;
SetTimeoutAlarm(OSSecondsToTicks(10));
return TRUE;
}
void DVDLowReset() {
u32 reg;
OSTime resetStart;
__DIRegs[1] = 2;
reg = __PIRegs[9];
__PIRegs[9] = (reg & ~4) | 1;
resetStart = __OSGetSystemTime();
while ((__OSGetSystemTime() - resetStart) < OSMicrosecondsToTicks(12))
;
__PIRegs[9] = reg | 5;
ResetOccurred = TRUE;
LastResetEnd = __OSGetSystemTime();
}
BOOL DVDLowBreak() {
StopAtNextInt = TRUE;
Breaking = TRUE;
return TRUE;
}
DVDLowCallback DVDLowClearCallback() {
DVDLowCallback old;
__DIRegs[1] = 0;
old = Callback;
Callback = NULL;
return old;
}
void __DVDLowSetWAType(u32 type, u32 location) {
BOOL enabled;
enabled = OSDisableInterrupts();
WorkAroundType = type;
WorkAroundSeekLocation = location;
OSRestoreInterrupts(enabled);
}

142
src/dolphin/dvd/dvdqueue.c Normal file
View file

@ -0,0 +1,142 @@
#include "dolphin/DVDPriv.h"
#define MAX_QUEUES 4
typedef struct {
DVDCommandBlock* next;
DVDCommandBlock* prev;
} DVDQueue;
static DVDQueue WaitingQueue[MAX_QUEUES];
void __DVDClearWaitingQueue(void) {
u32 i;
for (i = 0; i < MAX_QUEUES; i++) {
DVDCommandBlock* q;
q = (DVDCommandBlock*)&(WaitingQueue[i]);
q->next = q;
q->prev = q;
}
}
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 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;
}
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;
}
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;
}
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;
}
BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock* block) {
u32 i;
DVDCommandBlock* start;
DVDCommandBlock* q;
for (i = 0; i < MAX_QUEUES; i++) {
start = (DVDCommandBlock*)&(WaitingQueue[i]);
if (start->next != start) {
for (q = start->next; q != start; q = q->next) {
if (q == block)
return TRUE;
}
}
}
return FALSE;
}

68
src/dolphin/dvd/fstload.c Normal file
View file

@ -0,0 +1,68 @@
#include <dolphin/DVDPriv.h>
#include <dolphin/dvd.h>
#include <dolphin/hw_regs.h>
#include <dolphin/os.h>
#include <dolphin/os/OSBootInfo.h>
#include <string.h>
static s32 status = 0;
static u8 bb2Buf[OSRoundUp32B(sizeof(DVDBB2)) + 31];
static DVDBB2* bb2 = 0;
static DVDDiskID* idTmp = NULL;
static void cb(s32 result, DVDCommandBlock* block) {
if (result > 0) {
switch (status) {
case 0:
status = 1;
DVDReadAbsAsyncForBS(block, bb2, OSRoundUp32B(sizeof(bb2)), 0x420, cb);
break;
case 1:
status = 2;
DVDReadAbsAsyncForBS(block, bb2->FSTAddress, OSRoundUp32B(bb2->FSTLength), bb2->FSTPosition,
cb);
}
} else if (result == -1) {
} else if (result == -4) {
status = 0;
DVDReset();
DVDReadDiskID(block, idTmp, cb);
}
}
void __fstLoad() {
OSBootInfo* bootInfo;
DVDDiskID* id;
u8 idTmpBuf[sizeof(DVDDiskID) + 31];
static DVDCommandBlock block;
void* arenaHi;
arenaHi = OSGetArenaHi();
bootInfo = (OSBootInfo*)OSPhysicalToCached(0);
idTmp = (DVDDiskID*)(OSRoundUp32B(idTmpBuf));
bb2 = (DVDBB2*)(OSRoundUp32B(bb2Buf));
DVDReset();
DVDReadDiskID(&block, idTmp, cb);
while (DVDGetDriveStatus() != 0);
bootInfo->FSTLocation = bb2->FSTAddress;
bootInfo->FSTMaxLength = bb2->FSTMaxLength;
id = &bootInfo->DVDDiskID;
memcpy(id, idTmp, sizeof(DVDDiskID));
OSReport("\n");
OSReport(" Game Name ... %c%c%c%c\n", id->gameName[0], id->gameName[1], id->gameName[2],
id->gameName[3]);
OSReport(" Company ..... %c%c\n", id->company[0], id->company[1]);
OSReport(" Disk # ...... %d\n", id->diskNumber);
OSReport(" Game ver .... %d\n", id->gameVersion);
OSReport(" Streaming ... %s\n", (id->streaming == 0) ? "OFF" : "ON");
OSReport("\n");
OSSetArenaHi(bb2->FSTAddress);
}