More dvdlow progress

Former-commit-id: e83f40d9ec
This commit is contained in:
Phillip Stephens 2023-02-06 09:21:29 -08:00
parent 9b99045882
commit 92fdc5d033
1 changed files with 91 additions and 25 deletions

View File

@ -10,7 +10,7 @@ static u32 LastLength = 0;
static DVDLowCallback Callback = NULL; static DVDLowCallback Callback = NULL;
static DVDLowCallback ResetCoverCallback = NULL; static DVDLowCallback ResetCoverCallback = NULL;
static volatile OSTime LastResetEnd = 0; static volatile OSTime LastResetEnd = 0;
static volatile BOOL ResetOccurred = FALSE; static volatile u32 ResetOccurred = FALSE;
static volatile BOOL WaitingCoverClose = FALSE; static volatile BOOL WaitingCoverClose = FALSE;
static BOOL Breaking = FALSE; static BOOL Breaking = FALSE;
static u32 WorkAroundType = 0; static u32 WorkAroundType = 0;
@ -72,9 +72,13 @@ static BOOL ProcessNextCommand() {
} }
void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
DVDLowCallback cb;
OSContext exceptionContext;
u32 cause = 0;
u32 reg; u32 reg;
u32 status; u32 intr;
u32 flags = 0; u32 mask;
if (LastCommandWasRead) { if (LastCommandWasRead) {
LastReadFinished = __OSGetSystemTime(); LastReadFinished = __OSGetSystemTime();
FirstRead = FALSE; FirstRead = FALSE;
@ -82,36 +86,90 @@ void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
Prev.length = Curr.length; Prev.length = Curr.length;
Prev.offset = Curr.offset; Prev.offset = Curr.offset;
if (StopAtNextInt == TRUE) { if (StopAtNextInt == TRUE) {
flags |= 8; cause |= 8;
} }
} }
LastCommandWasRead = FALSE; LastCommandWasRead = FALSE;
StopAtNextInt = FALSE; StopAtNextInt = FALSE;
reg = __DIRegs[0]; reg = __DIRegs[0];
status = ((reg & 0x2a) << 1) & (reg & 0x54); mask = reg & 0x2a;
intr = (reg & 0x54) & (mask << 1);
if (status & 0x40) { if (intr & 0x40) {
flags |= 8; cause |= 8;
} }
if (status & 0x10) { if (intr & 0x10) {
flags |= 1; cause |= 1;
} }
if (status & 4) { if (intr & 4) {
flags |= 2; cause |= 2;
} }
if (flags) { if (cause) {
ResetOccurred = FALSE; ResetOccurred = FALSE;
OSCancelAlarm(&AlarmForWA); OSCancelAlarm(&AlarmForTimeout);
} }
__DIRegs[0] = status | (reg & 0x2a); __DIRegs[0] = intr | mask;
if (ResetOccurred) { 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) { static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
@ -153,7 +211,6 @@ static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
LastLength = length; LastLength = length;
__DIRegs[7] = 3; __DIRegs[7] = 3;
if (length > 0xa00000) { if (length > 0xa00000) {
SetTimeoutAlarm(OSSecondsToTicks(20)); SetTimeoutAlarm(OSSecondsToTicks(20));
} else { } else {
@ -169,18 +226,23 @@ static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callba
#pragma dont_inline on #pragma dont_inline on
static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
CommandList[0].offset = !(offset & ~0x7FFF) ? 0 : (offset & ~0x7FFF) + WorkAroundSeekLocation; u32 newOffset = offset & ~0x7FFF;
CommandList[0].callback = callback; if (!newOffset) {
newOffset = 0;
} else {
newOffset += WorkAroundSeekLocation;
}
CommandList[0].cmd = 2; CommandList[0].cmd = 2;
CommandList[1].cmd = 2; CommandList[0].offset = newOffset;
CommandList[2].cmd = -1; CommandList[0].callback = callback;
CommandList[1].cmd = 1;
CommandList[1].addr = addr; CommandList[1].addr = addr;
CommandList[1].length = length; CommandList[1].length = length;
CommandList[1].offset = offset; CommandList[1].offset = offset;
CommandList[1].callback = callback; CommandList[1].callback = callback;
offset = CommandList[0].offset; CommandList[2].cmd = -1;
NextCommandNumber = 0; NextCommandNumber = 0;
DVDLowSeek(offset, callback); DVDLowSeek(newOffset, callback);
} }
#pragma dont_inline reset #pragma dont_inline reset
@ -192,8 +254,12 @@ BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) {
if (WorkAroundType == 0) { if (WorkAroundType == 0) {
DoJustRead(addr, length, offset, callback); DoJustRead(addr, length, offset, callback);
} else { } else if (WorkAroundType == 1) {
SeekTwiceBeforeRead(addr, length, offset, callback); if (FirstRead) {
SeekTwiceBeforeRead(addr, length, offset, callback);
} else {
}
} }
return TRUE; return TRUE;
} }
@ -292,7 +358,7 @@ BOOL DVDLowAudioBufferConfig(BOOL enable, u32 size, DVDLowCallback callback) {
void DVDLowReset() { void DVDLowReset() {
u32 reg; u32 reg;
OSTime resetStart; OSTime resetStart;
__DIRegs[1] = 2; __DIRegs[1] = 2;
reg = __PIRegs[9]; reg = __PIRegs[9];
__PIRegs[9] = (reg & ~4) | 1; __PIRegs[9] = (reg & ~4) | 1;