mirror of https://github.com/PrimeDecomp/prime.git
parent
9b99045882
commit
92fdc5d033
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue