diff --git a/asm/Dolphin/dvd/dvdlow.s b/asm/Dolphin/dvd/dvdlow.s index cde2b322..81a64fc6 100644 --- a/asm/Dolphin/dvd/dvdlow.s +++ b/asm/Dolphin/dvd/dvdlow.s @@ -11,10 +11,29 @@ FirstRead: .section .bss .balign 8 -CommandList: - .skip 0x68 -lbl_80540AE8: - .skip 0x78 +.obj CommandList, local + .skip 0x3c +.endobj CommandList +.balign 8 +.obj AlarmForWA, local + .skip 0x28 +.endobj AlarmForWA + +.obj AlarmForTimeout, local + .skip 0x28 +.endobj AlarmForTimeout + +.obj AlarmForBreak, local + .skip 0x28 +.endobj AlarmForBreak + +.obj Prev, local + .skip 0xc +.endobj Prev + +.obj Curr, local + .skip 0xc +.endobj Curr .section .sbss .balign 8 @@ -670,10 +689,10 @@ DVDLowSeek: /* 80370D08 0036DC68 3C 00 AB 00 */ lis r0, 0xab00 /* 80370D0C 0036DC6C 90 04 00 08 */ stw r0, 8(r4) /* 80370D10 0036DC70 54 60 F0 BE */ srwi r0, r3, 2 -/* 80370D14 0036DC74 3C 60 80 54 */ lis r3, lbl_80540AE8@ha +/* 80370D14 0036DC74 3C 60 80 54 */ lis r3, AlarmForTimeout@ha /* 80370D18 0036DC78 90 04 00 0C */ stw r0, 0xc(r4) /* 80370D1C 0036DC7C 38 00 00 01 */ li r0, 1 -/* 80370D20 0036DC80 3B E3 0A E8 */ addi r31, r3, lbl_80540AE8@l +/* 80370D20 0036DC80 3B E3 0A E8 */ addi r31, r3, AlarmForTimeout@l /* 80370D24 0036DC84 90 04 00 1C */ stw r0, 0x1c(r4) /* 80370D28 0036DC88 3C 80 80 00 */ lis r4, 0x800000F8@ha /* 80370D2C 0036DC8C 38 7F 00 00 */ addi r3, r31, 0 @@ -726,10 +745,10 @@ DVDLowReadDiskID: /* 80370DD0 0036DD30 38 E4 60 00 */ addi r7, r4, 0xCC006000@l /* 80370DD4 0036DD34 91 0D AB A8 */ stw r8, StopAtNextInt@sda21(r13) /* 80370DD8 0036DD38 90 04 60 08 */ stw r0, 0x6008(r4) -/* 80370DDC 0036DD3C 3C 80 80 54 */ lis r4, lbl_80540AE8@ha +/* 80370DDC 0036DD3C 3C 80 80 54 */ lis r4, AlarmForTimeout@ha /* 80370DE0 0036DD40 38 00 00 03 */ li r0, 3 /* 80370DE4 0036DD44 91 07 00 0C */ stw r8, 0xc(r7) -/* 80370DE8 0036DD48 3B E4 0A E8 */ addi r31, r4, lbl_80540AE8@l +/* 80370DE8 0036DD48 3B E4 0A E8 */ addi r31, r4, AlarmForTimeout@l /* 80370DEC 0036DD4C 90 C7 00 10 */ stw r6, 0x10(r7) /* 80370DF0 0036DD50 90 67 00 14 */ stw r3, 0x14(r7) /* 80370DF4 0036DD54 7F E3 FB 78 */ mr r3, r31 @@ -768,10 +787,10 @@ DVDLowStopMotor: /* 80370E6C 0036DDCC 3C 00 E3 00 */ lis r0, 0xe300 /* 80370E70 0036DDD0 90 03 60 08 */ stw r0, 0x6008(r3) /* 80370E74 0036DDD4 38 00 00 01 */ li r0, 1 -/* 80370E78 0036DDD8 3C 60 80 54 */ lis r3, lbl_80540AE8@ha +/* 80370E78 0036DDD8 3C 60 80 54 */ lis r3, AlarmForTimeout@ha /* 80370E7C 0036DDDC 90 04 00 1C */ stw r0, 0x1c(r4) /* 80370E80 0036DDE0 3C 80 80 00 */ lis r4, 0x800000F8@ha -/* 80370E84 0036DDE4 3B E3 0A E8 */ addi r31, r3, lbl_80540AE8@l +/* 80370E84 0036DDE4 3B E3 0A E8 */ addi r31, r3, AlarmForTimeout@l /* 80370E88 0036DDE8 80 04 00 F8 */ lwz r0, 0x800000F8@l(r4) /* 80370E8C 0036DDEC 38 7F 00 00 */ addi r3, r31, 0 /* 80370E90 0036DDF0 54 00 F0 BE */ srwi r0, r0, 2 @@ -806,10 +825,10 @@ DVDLowRequestError: /* 80370EF8 0036DE58 3C 00 E0 00 */ lis r0, 0xe000 /* 80370EFC 0036DE5C 90 03 60 08 */ stw r0, 0x6008(r3) /* 80370F00 0036DE60 38 00 00 01 */ li r0, 1 -/* 80370F04 0036DE64 3C 60 80 54 */ lis r3, lbl_80540AE8@ha +/* 80370F04 0036DE64 3C 60 80 54 */ lis r3, AlarmForTimeout@ha /* 80370F08 0036DE68 90 04 00 1C */ stw r0, 0x1c(r4) /* 80370F0C 0036DE6C 3C 80 80 00 */ lis r4, 0x800000F8@ha -/* 80370F10 0036DE70 3B E3 0A E8 */ addi r31, r3, lbl_80540AE8@l +/* 80370F10 0036DE70 3B E3 0A E8 */ addi r31, r3, AlarmForTimeout@l /* 80370F14 0036DE74 80 04 00 F8 */ lwz r0, 0x800000F8@l(r4) /* 80370F18 0036DE78 38 7F 00 00 */ addi r3, r31, 0 /* 80370F1C 0036DE7C 54 00 F0 BE */ srwi r0, r0, 2 @@ -845,10 +864,10 @@ DVDLowInquiry: /* 80370F88 0036DEE8 90 0D AB A8 */ stw r0, StopAtNextInt@sda21(r13) /* 80370F8C 0036DEEC 3C 00 12 00 */ lis r0, 0x1200 /* 80370F90 0036DEF0 90 04 60 08 */ stw r0, 0x6008(r4) -/* 80370F94 0036DEF4 3C 80 80 54 */ lis r4, lbl_80540AE8@ha +/* 80370F94 0036DEF4 3C 80 80 54 */ lis r4, AlarmForTimeout@ha /* 80370F98 0036DEF8 38 00 00 03 */ li r0, 3 /* 80370F9C 0036DEFC 90 C7 00 10 */ stw r6, 0x10(r7) -/* 80370FA0 0036DF00 3B E4 0A E8 */ addi r31, r4, lbl_80540AE8@l +/* 80370FA0 0036DF00 3B E4 0A E8 */ addi r31, r4, AlarmForTimeout@l /* 80370FA4 0036DF04 90 67 00 14 */ stw r3, 0x14(r7) /* 80370FA8 0036DF08 38 7F 00 00 */ addi r3, r31, 0 /* 80370FAC 0036DF0C 90 C7 00 18 */ stw r6, 0x18(r7) @@ -884,10 +903,10 @@ DVDLowAudioStream: /* 80371018 0036DF78 38 C6 60 00 */ addi r6, r6, 0xCC006000@l /* 8037101C 0036DF7C 90 0D AB A8 */ stw r0, StopAtNextInt@sda21(r13) /* 80371020 0036DF80 64 60 E1 00 */ oris r0, r3, 0xe100 -/* 80371024 0036DF84 3C 60 80 54 */ lis r3, lbl_80540AE8@ha +/* 80371024 0036DF84 3C 60 80 54 */ lis r3, AlarmForTimeout@ha /* 80371028 0036DF88 90 06 00 08 */ stw r0, 8(r6) /* 8037102C 0036DF8C 54 A0 F0 BE */ srwi r0, r5, 2 -/* 80371030 0036DF90 3B E3 0A E8 */ addi r31, r3, lbl_80540AE8@l +/* 80371030 0036DF90 3B E3 0A E8 */ addi r31, r3, AlarmForTimeout@l /* 80371034 0036DF94 90 06 00 0C */ stw r0, 0xc(r6) /* 80371038 0036DF98 38 00 00 01 */ li r0, 1 /* 8037103C 0036DF9C 38 7F 00 00 */ addi r3, r31, 0 @@ -925,10 +944,10 @@ DVDLowRequestAudioStatus: /* 803710B0 0036E010 38 84 60 00 */ addi r4, r4, 0xCC006000@l /* 803710B4 0036E014 90 0D AB A8 */ stw r0, StopAtNextInt@sda21(r13) /* 803710B8 0036E018 64 60 E2 00 */ oris r0, r3, 0xe200 -/* 803710BC 0036E01C 3C 60 80 54 */ lis r3, lbl_80540AE8@ha +/* 803710BC 0036E01C 3C 60 80 54 */ lis r3, AlarmForTimeout@ha /* 803710C0 0036E020 90 04 00 08 */ stw r0, 8(r4) /* 803710C4 0036E024 38 00 00 01 */ li r0, 1 -/* 803710C8 0036E028 3B E3 0A E8 */ addi r31, r3, lbl_80540AE8@l +/* 803710C8 0036E028 3B E3 0A E8 */ addi r31, r3, AlarmForTimeout@l /* 803710CC 0036E02C 90 04 00 1C */ stw r0, 0x1c(r4) /* 803710D0 0036E030 3C 80 80 00 */ lis r4, 0x800000F8@ha /* 803710D4 0036E034 38 7F 00 00 */ addi r3, r31, 0 @@ -972,8 +991,8 @@ lbl_80371148: /* 8037115C 0036E0BC 38 00 00 01 */ li r0, 1 /* 80371160 0036E0C0 3C 80 80 00 */ lis r4, 0x800000F8@ha /* 80371164 0036E0C4 90 03 00 1C */ stw r0, 0x1c(r3) -/* 80371168 0036E0C8 3C 60 80 54 */ lis r3, lbl_80540AE8@ha -/* 8037116C 0036E0CC 3B E3 0A E8 */ addi r31, r3, lbl_80540AE8@l +/* 80371168 0036E0C8 3C 60 80 54 */ lis r3, AlarmForTimeout@ha +/* 8037116C 0036E0CC 3B E3 0A E8 */ addi r31, r3, AlarmForTimeout@l /* 80371170 0036E0D0 80 04 00 F8 */ lwz r0, 0x800000F8@l(r4) /* 80371174 0036E0D4 38 7F 00 00 */ addi r3, r31, 0 /* 80371178 0036E0D8 54 00 F0 BE */ srwi r0, r0, 2 diff --git a/include/dolphin/DVDPriv.h b/include/dolphin/DVDPriv.h index 654e4fcd..f49b8ca8 100644 --- a/include/dolphin/DVDPriv.h +++ b/include/dolphin/DVDPriv.h @@ -39,7 +39,7 @@ typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, void (*cb)(u32 typedef void (*DVDLowCallback)(u32 intType); DVDLowCallback DVDLowClearCallback(); -void DVDLowSeek(u32 offset, DVDLowCallback callback); +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback); void __DVDLowSetWAType(u32 type, u32 location); DVDCommandBlock* __DVDPopWaitingQueue(); diff --git a/include/dolphin/os.h b/include/dolphin/os.h index c6779109..e39bf846 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -8,9 +8,6 @@ extern "C" { #endif -// TODO OSInerrupt.h -typedef s16 __OSInterrupt; - // Upper words of the masks, since UIMM is only 16 bits #define OS_CACHED_REGION_PREFIX 0x8000 #define OS_UNCACHED_REGION_PREFIX 0xC000 @@ -141,6 +138,73 @@ BOOL OSDisableInterrupts(void); BOOL OSEnableInterrupts(void); BOOL OSRestoreInterrupts(BOOL level); +#define OSHalt(msg) OSPanic(__FILE__, __LINE__, msg) + +#ifdef _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) (void)((exp) || (OSPanic(__FILE__, __LINE__, "Failed assertion " #exp), 0)) +#endif + +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ + defined(__SN__) +#define ASSERTMSG(exp, ...) (void)((exp) || (OSPanic(__FILE__, __LINE__, __VA_ARGS__), 0)) +#else +#define ASSERTMSG(exp, msg) (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg)), 0)) +#endif +#endif + +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1)), 0)) +#endif + +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2)), 0)) +#endif + +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3)), 0)) +#endif + +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3), (param4)), 0)) +#endif + +#else // _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) ((void)0) +#endif + +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || \ + defined(__SN__) +#define ASSERTMSG(exp, ...) ((void)0) +#else +#define ASSERTMSG(exp, msg) ((void)0) +#endif +#endif + +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) ((void)0) +#endif +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) ((void)0) +#endif +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) ((void)0) +#endif +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) ((void)0) +#endif + +#endif // _DEBUG + void OSReport(const char* msg, ...); void OSPanic(const char* file, int line, const char* msg, ...); void OSFatal(GXColor fg, GXColor bg, const char* msg); diff --git a/src/Dolphin/dvd/dvdlow.c b/src/Dolphin/dvd/dvdlow.c index 1a939ba7..62c843ab 100644 --- a/src/Dolphin/dvd/dvdlow.c +++ b/src/Dolphin/dvd/dvdlow.c @@ -1,63 +1,122 @@ #include "dolphin/DVDPriv.h" #include "dolphin/os.h" +extern OSTime __OSGetSystemTime(); +vu32 __PIRegs[12] : 0xCC003000; + static BOOL FirstRead = TRUE; static volatile BOOL StopAtNextInt = FALSE; static u32 LastLength = 0; static DVDLowCallback Callback = NULL; static DVDLowCallback ResetCoverCallback = NULL; -static OSTime LastResetEnd = 0; -static BOOL ResetOccurred = FALSE; +static volatile OSTime LastResetEnd = 0; +static volatile BOOL ResetOccurred = FALSE; static volatile BOOL WaitingCoverClose = FALSE; static BOOL Breaking = FALSE; static u32 WorkAroundType = 0; static u32 WorkAroundSeekLocation = 0; static OSTime LastReadFinished = 0; static OSTime LastReadIssued = 0; -static BOOL LastCommandWasRead = FALSE; -static u32 NextCommandNumber = 0; +static volatile BOOL LastCommandWasRead = FALSE; +static vu32 NextCommandNumber = 0; -typedef struct DVDUnk { - u32 _0; - u32 _4; - u32 _8; -} DVDUnk; +typedef struct DVDBuffer { + void* addr; + u32 length; + u32 offset; +} DVDBuffer; typedef struct DVDCommand { - s32 _0; - u32 _4; - u32 _8; - u32 _c; + s32 cmd; + void* addr; + u32 length; + u32 offset; DVDLowCallback callback; } DVDCommand; -static DVDCommand CommandList[4]; +static DVDCommand CommandList[3]; static OSAlarm AlarmForWA; static OSAlarm AlarmForTimeout; static OSAlarm AlarmForBreak; -static DVDUnk Prev; -static DVDUnk Cur; +static DVDBuffer Prev; +static DVDBuffer Curr; void __DVDInitWA() { NextCommandNumber = 0; - CommandList[0]._0 = -1; + CommandList[0].cmd = -1; __DVDLowSetWAType(0, 0); OSInitAlarm(); } -static void Read(u32 tmp1, u32 tmp2, u32 tmp3, DVDLowCallback tmp4); -void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) {} + +static void Read(void* addr, u32 length, u32 offset, DVDLowCallback callback); + +static BOOL ProcessNextCommand() { + s32 n = NextCommandNumber; + BOOL ret; + ASSERT(n < 3); + + if (CommandList[n].cmd == 1) { + ++NextCommandNumber; + Read(CommandList[n].addr, CommandList[n].length, CommandList[n].offset, + CommandList[n].callback); + ret = TRUE; + } else if (CommandList[n].cmd == 2) { + ++NextCommandNumber; + DVDLowSeek(CommandList[n].offset, CommandList[n].callback); + ret = TRUE; + } else { + ret = FALSE; + } + + return ret; +} + +void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) { + u32 reg; + u32 status; + u32 flags = 0; + if (LastCommandWasRead) { + LastReadFinished = __OSGetSystemTime(); + FirstRead = FALSE; + Prev.addr = Curr.addr; + Prev.length = Curr.length; + Prev.offset = Curr.offset; + if (StopAtNextInt == TRUE) { + flags |= 8; + } + } + + LastCommandWasRead = FALSE; + StopAtNextInt = FALSE; + reg = __DIRegs[0]; + status = ((reg & 0x2a) << 1) & (reg & 0x54); + + if (status & 0x40) { + flags |= 8; + } + + if (status & 0x10) { + flags |= 1; + } + + if (status & 4) { + flags |= 2; + } + + if (flags) { + ResetOccurred = FALSE; + OSCancelAlarm(&AlarmForWA); + } + + __DIRegs[0] = status | (reg & 0x2a); + + if (ResetOccurred) { + } +} static void AlarmHandler(OSAlarm* alarm, OSContext* context) { - DVDCommand* cmd; - cmd = &CommandList[NextCommandNumber]; - - if (cmd->_0 == 1) { - ++NextCommandNumber; - Read(cmd->_4, cmd->_8, cmd->_c, cmd->callback); - } else if (cmd->_0 == 2) { - ++NextCommandNumber; - DVDLowSeek(cmd->_c, cmd->callback); - } + BOOL error = ProcessNextCommand(); + ASSERTMSG(error != FALSE, "Failed assertion processed"); } static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { @@ -75,20 +134,79 @@ static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) { OSSetCurrentContext(context); } -static void Read(u32 tmp1, u32 tmp2, u32 tmp3, DVDLowCallback tmp4) { - +static void SetTimeoutAlarm(OSTime timeout) { + OSCreateAlarm(&AlarmForTimeout); + OSSetAlarm(&AlarmForTimeout, timeout, AlarmHandlerForTimeout); } -static void SeekTwiceBeforeRead() { +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)); + } } -void DVDLowRead(u32 unk, DVDLowCallback callback) { - +static void DoJustRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + CommandList[0].cmd = -1; + NextCommandNumber = 0; + Read(addr, length, offset, callback); } -void DVDLowSeek(u32 offset, DVDLowCallback callback) { +#pragma dont_inline on +static void SeekTwiceBeforeRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + CommandList[0].offset = !(offset & ~0x7FFF) ? 0 : (offset & ~0x7FFF) + WorkAroundSeekLocation; + CommandList[0].callback = callback; + CommandList[0].cmd = 2; + CommandList[1].cmd = 2; + CommandList[2].cmd = -1; + CommandList[1].addr = addr; + CommandList[1].length = length; + CommandList[1].offset = offset; + CommandList[1].callback = callback; + offset = CommandList[0].offset; + NextCommandNumber = 0; + DVDLowSeek(offset, callback); +} +#pragma dont_inline reset +BOOL DVDLowRead(void* addr, u32 length, u32 offset, DVDLowCallback callback) { + Curr.addr = addr; + Curr.length = length; + Curr.offset = offset; + __DIRegs[6] = length; + + if (WorkAroundType == 0) { + DoJustRead(addr, length, offset, callback); + } 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) { @@ -99,6 +217,108 @@ BOOL DVDLowWaitCoverClose(DVDLowCallback callback) { 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] = 32; // sizeof(DVDDriveInfo); + __DIRegs[5] = (u32)info; + __DIRegs[6] = 32; // 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;