diff --git a/asm/Dolphin/os/OSResetSW.s b/asm/Dolphin/os/OSResetSW.s index dc665d7e..210a3d0c 100644 --- a/asm/Dolphin/os/OSResetSW.s +++ b/asm/Dolphin/os/OSResetSW.s @@ -2,27 +2,22 @@ .section .sbss .balign 8 -.global lbl_805A9900 -lbl_805A9900: +.global ResetCallback +ResetCallback: .skip 0x4 -.global lbl_805A9904 -lbl_805A9904: +.global Down +Down: .skip 0x4 -.global lbl_805A9908 -lbl_805A9908: +.global LastState +LastState: + .skip 0x4 + .skip 0x4 +.global HoldUp +HoldUp: + .skip 0x8 +.global HoldDown +HoldDown: .skip 0x8 -.global lbl_805A9910 -lbl_805A9910: - .skip 0x4 -.global lbl_805A9914 -lbl_805A9914: - .skip 0x4 -.global lbl_805A9918 -lbl_805A9918: - .skip 0x4 -.global lbl_805A991C -lbl_805A991C: - .skip 0x4 .section .text, "ax" @@ -37,11 +32,11 @@ __OSResetSWInterruptHandler: /* 803834B0 00380410 93 A1 00 1C */ stw r29, 0x1c(r1) /* 803834B4 00380414 48 00 1F 15 */ bl __OSGetSystemTime /* 803834B8 00380418 3C A0 80 00 */ lis r5, 0x800000F8@ha -/* 803834BC 0038041C 90 8D AD 5C */ stw r4, lbl_805A991C@sda21(r13) +/* 803834BC 0038041C 90 8D AD 5C */ stw r4, HoldDown+4@sda21(r13) /* 803834C0 00380420 80 05 00 F8 */ lwz r0, 0x800000F8@l(r5) /* 803834C4 00380424 3C 80 43 1C */ lis r4, 0x431BDE83@ha /* 803834C8 00380428 38 84 DE 83 */ addi r4, r4, 0x431BDE83@l -/* 803834CC 0038042C 90 6D AD 58 */ stw r3, lbl_805A9918@sda21(r13) +/* 803834CC 0038042C 90 6D AD 58 */ stw r3, HoldDown@sda21(r13) /* 803834D0 00380430 54 00 F0 BE */ srwi r0, r0, 2 /* 803834D4 00380434 7C 04 00 16 */ mulhwu r0, r4, r0 /* 803834D8 00380438 54 00 8B FE */ srwi r0, r0, 0xf @@ -51,9 +46,9 @@ __OSResetSWInterruptHandler: /* 803834E8 00380448 3F E0 CC 00 */ lis r31, 0xcc00 lbl_803834EC: /* 803834EC 0038044C 48 00 1E DD */ bl __OSGetSystemTime -/* 803834F0 00380450 80 CD AD 5C */ lwz r6, lbl_805A991C@sda21(r13) +/* 803834F0 00380450 80 CD AD 5C */ lwz r6, HoldDown+4@sda21(r13) /* 803834F4 00380454 6F C5 80 00 */ xoris r5, r30, 0x8000 -/* 803834F8 00380458 80 0D AD 58 */ lwz r0, lbl_805A9918@sda21(r13) +/* 803834F8 00380458 80 0D AD 58 */ lwz r0, HoldDown@sda21(r13) /* 803834FC 0038045C 7C 86 20 10 */ subfc r4, r6, r4 /* 80383500 00380460 7C 00 19 10 */ subfe r0, r0, r3 /* 80383504 00380464 6C 03 80 00 */ xoris r3, r0, 0x8000 @@ -71,16 +66,16 @@ lbl_80383528: /* 80383530 00380490 54 00 03 DF */ rlwinm. r0, r0, 0, 0xf, 0xf /* 80383534 00380494 40 82 00 34 */ bne lbl_80383568 /* 80383538 00380498 38 00 00 01 */ li r0, 1 -/* 8038353C 0038049C 90 0D AD 44 */ stw r0, lbl_805A9904@sda21(r13) +/* 8038353C 0038049C 90 0D AD 44 */ stw r0, Down@sda21(r13) /* 80383540 003804A0 38 60 02 00 */ li r3, 0x200 -/* 80383544 003804A4 90 0D AD 48 */ stw r0, lbl_805A9908@sda21(r13) +/* 80383544 003804A4 90 0D AD 48 */ stw r0, LastState@sda21(r13) /* 80383548 003804A8 4B FF E4 E1 */ bl __OSMaskInterrupts -/* 8038354C 003804AC 81 8D AD 40 */ lwz r12, lbl_805A9900@sda21(r13) +/* 8038354C 003804AC 81 8D AD 40 */ lwz r12, ResetCallback@sda21(r13) /* 80383550 003804B0 28 0C 00 00 */ cmplwi r12, 0 /* 80383554 003804B4 41 82 00 14 */ beq lbl_80383568 /* 80383558 003804B8 38 00 00 00 */ li r0, 0 /* 8038355C 003804BC 7D 88 03 A6 */ mtlr r12 -/* 80383560 003804C0 90 0D AD 40 */ stw r0, lbl_805A9900@sda21(r13) +/* 80383560 003804C0 90 0D AD 40 */ stw r0, ResetCallback@sda21(r13) /* 80383564 003804C4 4E 80 00 21 */ blrl lbl_80383568: /* 80383568 003804C8 38 00 00 02 */ li r0, 2 @@ -109,41 +104,41 @@ OSGetResetButtonState: /* 803835B8 00380518 80 05 30 00 */ lwz r0, 0xCC003000@l(r5) /* 803835BC 0038051C 54 00 03 DF */ rlwinm. r0, r0, 0, 0xf, 0xf /* 803835C0 00380520 40 82 00 DC */ bne lbl_8038369C -/* 803835C4 00380524 80 0D AD 44 */ lwz r0, lbl_805A9904@sda21(r13) +/* 803835C4 00380524 80 0D AD 44 */ lwz r0, Down@sda21(r13) /* 803835C8 00380528 2C 00 00 00 */ cmpwi r0, 0 /* 803835CC 0038052C 40 82 00 40 */ bne lbl_8038360C -/* 803835D0 00380530 80 0D AD 50 */ lwz r0, lbl_805A9910@sda21(r13) +/* 803835D0 00380530 80 0D AD 50 */ lwz r0, HoldUp@sda21(r13) /* 803835D4 00380534 38 C0 00 00 */ li r6, 0 -/* 803835D8 00380538 80 AD AD 54 */ lwz r5, lbl_805A9914@sda21(r13) +/* 803835D8 00380538 80 AD AD 54 */ lwz r5, HoldUp+4@sda21(r13) /* 803835DC 0038053C 38 E0 00 01 */ li r7, 1 /* 803835E0 00380540 7C 00 32 78 */ xor r0, r0, r6 /* 803835E4 00380544 7C A5 32 78 */ xor r5, r5, r6 -/* 803835E8 00380548 90 ED AD 44 */ stw r7, lbl_805A9904@sda21(r13) +/* 803835E8 00380548 90 ED AD 44 */ stw r7, Down@sda21(r13) /* 803835EC 0038054C 7C A0 03 79 */ or. r0, r5, r0 /* 803835F0 00380550 41 82 00 08 */ beq lbl_803835F8 /* 803835F4 00380554 48 00 00 08 */ b lbl_803835FC lbl_803835F8: /* 803835F8 00380558 7C C7 33 78 */ mr r7, r6 lbl_803835FC: -/* 803835FC 0038055C 90 8D AD 5C */ stw r4, lbl_805A991C@sda21(r13) +/* 803835FC 0038055C 90 8D AD 5C */ stw r4, HoldDown+4@sda21(r13) /* 80383600 00380560 7C FD 3B 78 */ mr r29, r7 -/* 80383604 00380564 90 6D AD 58 */ stw r3, lbl_805A9918@sda21(r13) +/* 80383604 00380564 90 6D AD 58 */ stw r3, HoldDown@sda21(r13) /* 80383608 00380568 48 00 01 48 */ b lbl_80383750 lbl_8038360C: -/* 8038360C 0038056C 80 0D AD 50 */ lwz r0, lbl_805A9910@sda21(r13) +/* 8038360C 0038056C 80 0D AD 50 */ lwz r0, HoldUp@sda21(r13) /* 80383610 00380570 39 20 00 00 */ li r9, 0 -/* 80383614 00380574 80 AD AD 54 */ lwz r5, lbl_805A9914@sda21(r13) +/* 80383614 00380574 80 AD AD 54 */ lwz r5, HoldUp+4@sda21(r13) /* 80383618 00380578 39 40 00 01 */ li r10, 1 /* 8038361C 0038057C 7C 00 4A 78 */ xor r0, r0, r9 /* 80383620 00380580 7C A5 4A 78 */ xor r5, r5, r9 /* 80383624 00380584 7C A0 03 79 */ or. r0, r5, r0 /* 80383628 00380588 40 82 00 58 */ bne lbl_80383680 /* 8038362C 0038058C 3C C0 80 00 */ lis r6, 0x800000F8@ha -/* 80383630 00380590 80 AD AD 5C */ lwz r5, lbl_805A991C@sda21(r13) +/* 80383630 00380590 80 AD AD 5C */ lwz r5, HoldDown+4@sda21(r13) /* 80383634 00380594 80 E6 00 F8 */ lwz r7, 0x800000F8@l(r6) /* 80383638 00380598 3C C0 43 1C */ lis r6, 0x431BDE83@ha /* 8038363C 0038059C 39 06 DE 83 */ addi r8, r6, 0x431BDE83@l -/* 80383640 003805A0 80 0D AD 58 */ lwz r0, lbl_805A9918@sda21(r13) +/* 80383640 003805A0 80 0D AD 58 */ lwz r0, HoldDown@sda21(r13) /* 80383644 003805A4 54 E6 F0 BE */ srwi r6, r7, 2 /* 80383648 003805A8 7C C8 30 16 */ mulhwu r6, r8, r6 /* 8038364C 003805AC 54 C6 8B FE */ srwi r6, r6, 0xf @@ -170,26 +165,26 @@ lbl_80383694: /* 80383694 003805F4 7C 1D 03 78 */ mr r29, r0 /* 80383698 003805F8 48 00 00 B8 */ b lbl_80383750 lbl_8038369C: -/* 8038369C 003805FC 80 0D AD 44 */ lwz r0, lbl_805A9904@sda21(r13) +/* 8038369C 003805FC 80 0D AD 44 */ lwz r0, Down@sda21(r13) /* 803836A0 00380600 2C 00 00 00 */ cmpwi r0, 0 /* 803836A4 00380604 41 82 00 34 */ beq lbl_803836D8 -/* 803836A8 00380608 80 AD AD 48 */ lwz r5, lbl_805A9908@sda21(r13) +/* 803836A8 00380608 80 AD AD 48 */ lwz r5, LastState@sda21(r13) /* 803836AC 0038060C 38 00 00 00 */ li r0, 0 -/* 803836B0 00380610 90 0D AD 44 */ stw r0, lbl_805A9904@sda21(r13) +/* 803836B0 00380610 90 0D AD 44 */ stw r0, Down@sda21(r13) /* 803836B4 00380614 2C 05 00 00 */ cmpwi r5, 0 /* 803836B8 00380618 3B A5 00 00 */ addi r29, r5, 0 /* 803836BC 0038061C 41 82 00 10 */ beq lbl_803836CC -/* 803836C0 00380620 90 8D AD 54 */ stw r4, lbl_805A9914@sda21(r13) -/* 803836C4 00380624 90 6D AD 50 */ stw r3, lbl_805A9910@sda21(r13) +/* 803836C0 00380620 90 8D AD 54 */ stw r4, HoldUp+4@sda21(r13) +/* 803836C4 00380624 90 6D AD 50 */ stw r3, HoldUp@sda21(r13) /* 803836C8 00380628 48 00 00 88 */ b lbl_80383750 lbl_803836CC: -/* 803836CC 0038062C 90 0D AD 54 */ stw r0, lbl_805A9914@sda21(r13) -/* 803836D0 00380630 90 0D AD 50 */ stw r0, lbl_805A9910@sda21(r13) +/* 803836CC 0038062C 90 0D AD 54 */ stw r0, HoldUp+4@sda21(r13) +/* 803836D0 00380630 90 0D AD 50 */ stw r0, HoldUp@sda21(r13) /* 803836D4 00380634 48 00 00 7C */ b lbl_80383750 lbl_803836D8: -/* 803836D8 00380638 80 CD AD 50 */ lwz r6, lbl_805A9910@sda21(r13) +/* 803836D8 00380638 80 CD AD 50 */ lwz r6, HoldUp@sda21(r13) /* 803836DC 0038063C 39 00 00 00 */ li r8, 0 -/* 803836E0 00380640 80 ED AD 54 */ lwz r7, lbl_805A9914@sda21(r13) +/* 803836E0 00380640 80 ED AD 54 */ lwz r7, HoldUp+4@sda21(r13) /* 803836E4 00380644 7C C0 42 78 */ xor r0, r6, r8 /* 803836E8 00380648 7C E5 42 78 */ xor r5, r7, r8 /* 803836EC 0038064C 7C A0 03 79 */ or. r0, r5, r0 @@ -215,12 +210,12 @@ lbl_803836D8: /* 8038373C 0038069C 48 00 00 14 */ b lbl_80383750 lbl_80383740: /* 80383740 003806A0 38 00 00 00 */ li r0, 0 -/* 80383744 003806A4 90 0D AD 54 */ stw r0, lbl_805A9914@sda21(r13) +/* 80383744 003806A4 90 0D AD 54 */ stw r0, HoldUp+4@sda21(r13) /* 80383748 003806A8 3B A0 00 00 */ li r29, 0 -/* 8038374C 003806AC 90 0D AD 50 */ stw r0, lbl_805A9910@sda21(r13) +/* 8038374C 003806AC 90 0D AD 50 */ stw r0, HoldUp@sda21(r13) lbl_80383750: /* 80383750 003806B0 3C A0 80 00 */ lis r5, 0x800030E3@ha -/* 80383754 003806B4 93 AD AD 48 */ stw r29, lbl_805A9908@sda21(r13) +/* 80383754 003806B4 93 AD AD 48 */ stw r29, LastState@sda21(r13) /* 80383758 003806B8 88 05 30 E3 */ lbz r0, 0x800030E3@l(r5) /* 8038375C 003806BC 54 00 06 BF */ clrlwi. r0, r0, 0x1a /* 80383760 003806C0 41 82 00 A0 */ beq lbl_80383800 diff --git a/configure.py b/configure.py index b0da209c..5239d1fa 100755 --- a/configure.py +++ b/configure.py @@ -820,7 +820,7 @@ LIBS = [ ["Dolphin/os/OSMutex", True], "Dolphin/os/OSReboot", ["Dolphin/os/OSReset", True], - "Dolphin/os/OSResetSW", + ["Dolphin/os/OSResetSW", True], ["Dolphin/os/OSRtc", True], ["Dolphin/os/OSSync", True], ["Dolphin/os/OSThread", True], diff --git a/include/dolphin/os.h b/include/dolphin/os.h index e72c6693..c6779109 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -164,6 +164,7 @@ void OSFatal(GXColor fg, GXColor bg, const char* msg); #include #include #include +#include #include #include #endif // _DOLPHIN_OS diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h new file mode 100644 index 00000000..5551f68c --- /dev/null +++ b/include/dolphin/os/OSResetSW.h @@ -0,0 +1,22 @@ +#ifndef _DOLPHIN_OSRESETSW +#define _DOLPHIN_OSRESETSW + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*OSResetCallback)(void); + +BOOL OSGetResetButtonState(void); + +BOOL OSGetResetSwitchState(void); +OSResetCallback OSSetResetCallback(OSResetCallback callback); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSRESETSW diff --git a/src/Dolphin/os/OSResetSW.c b/src/Dolphin/os/OSResetSW.c new file mode 100644 index 00000000..8abb8b87 --- /dev/null +++ b/src/Dolphin/os/OSResetSW.c @@ -0,0 +1,281 @@ +#include + +extern OSTime __OSGetSystemTime(); + +u8 GameChoice : (OS_BASE_CACHED | 0x30E3); + +vu32 __PIRegs[12] : 0xCC003000; + +extern OSTime __OSStartTime; + +static OSResetCallback ResetCallback; +static BOOL Down; +static BOOL LastState; +static OSTime HoldUp; +static OSTime HoldDown; + +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) { + OSResetCallback callback; + + HoldDown = __OSGetSystemTime(); + while (__OSGetSystemTime() - HoldDown < OSMicrosecondsToTicks(100) && + !(__PIRegs[0] & 0x00010000)) { + ; + } + if (!(__PIRegs[0] & 0x00010000)) { + LastState = Down = TRUE; + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_RSW); + if (ResetCallback) { + callback = ResetCallback; + ResetCallback = NULL; + callback(); + } + } + __PIRegs[0] = 2; +} + +#if NONMATCHING +BOOL OSGetResetButtonState(void) { + BOOL enabled; + BOOL state; + u32 reg; + OSTime now; + + enabled = OSDisableInterrupts(); + + now = __OSGetSystemTime(); + + reg = __PIRegs[0]; + if (!(reg & 0x00010000)) { + if (!Down) { + Down = TRUE; + state = HoldUp ? TRUE : FALSE; + HoldDown = now; + } else { + state = (HoldUp || (OSMicrosecondsToTicks(100) < now - HoldDown)) ? TRUE : FALSE; + } + } else if (Down) { + Down = FALSE; + state = LastState; + if (state) { + HoldUp = now; + } else { + HoldUp = 0; + } + } else if (HoldUp && (now - HoldUp < OSMillisecondsToTicks(40))) { + state = TRUE; + } else { + state = FALSE; + HoldUp = 0; + } + + LastState = state; + + if (GameChoice & 0x3f) { + OSTime fire = (GameChoice & 0x3f) * 60; + fire = __OSStartTime + OSSecondsToTicks(fire); + if (fire < now) { + now -= fire; + now = OSTicksToSeconds(now) / 2; + if ((now & 1) == 0) { + state = TRUE; + } else { + state = FALSE; + } + } + } + + OSRestoreInterrupts(enabled); + return state; +} +#else +extern void __div2i(void); +/* clang-format off */ +#pragma push +#pragma optimization_level +#pragma optimizewithasm off +asm BOOL OSGetResetButtonState(void) { + nofralloc + mflr r0 + stw r0, 4(r1) + stwu r1, -0x18(r1) + stw r31, 0x14(r1) + stw r30, 0x10(r1) + stw r29, 0xc(r1) + bl OSDisableInterrupts + mr r30, r3 + bl __OSGetSystemTime + lis r5, __PIRegs@ha + lwz r0, __PIRegs@l(r5) + rlwinm. r0, r0, 0, 0xf, 0xf + bne lbl_8038369C + lwz r0, Down + cmpwi r0, 0 + bne lbl_8038360C + lwz r0, HoldUp + li r6, 0 + lwz r5, HoldUp+4 + li r7, 1 + xor r0, r0, r6 + xor r5, r5, r6 + stw r7, Down + or. r0, r5, r0 + beq lbl_803835F8 + b lbl_803835FC +lbl_803835F8: + mr r7, r6 +lbl_803835FC: + stw r4, HoldDown+4 + mr r29, r7 + stw r3, HoldDown + b lbl_80383750 +lbl_8038360C: + lwz r0, HoldUp + li r9, 0 + lwz r5, HoldUp+4 + li r10, 1 + xor r0, r0, r9 + xor r5, r5, r9 + or. r0, r5, r0 + bne lbl_80383680 + lis r6, __OSBusClock@ha + lwz r5, HoldDown+4 + lwz r7, __OSBusClock@l(r6) + lis r6, 0x431BDE83@ha + addi r8, r6, 0x431BDE83@l + lwz r0, HoldDown + srwi r6, r7, 2 + mulhwu r6, r8, r6 + srwi r6, r6, 0xf + mulli r6, r6, 0x64 + subfc r7, r5, r4 + subfe r0, r0, r3 + srwi r8, r6, 3 + xoris r5, r0, 0x8000 + xoris r6, r9, 0x8000 + subfc r0, r7, r8 + subfe r5, r5, r6 + subfe r5, r6, r6 + neg. r5, r5 + bne lbl_80383680 + mr r10, r9 +lbl_80383680: + cmpwi r10, 0 + beq lbl_80383690 + li r0, 1 + b lbl_80383694 +lbl_80383690: + li r0, 0 +lbl_80383694: + mr r29, r0 + b lbl_80383750 +lbl_8038369C: + lwz r0, Down + cmpwi r0, 0 + beq lbl_803836D8 + lwz r5, LastState + li r0, 0 + stw r0, Down + cmpwi r5, 0 + addi r29, r5, 0 + beq lbl_803836CC + stw r4, HoldUp+4 + stw r3, HoldUp + b lbl_80383750 +lbl_803836CC: + stw r0, HoldUp+4 + stw r0, HoldUp + b lbl_80383750 +lbl_803836D8: + lwz r6, HoldUp + li r8, 0 + lwz r7, HoldUp+4 + xor r0, r6, r8 + xor r5, r7, r8 + or. r0, r5, r0 + beq lbl_80383740 + lis r5, __OSBusClock@ha + lwz r0, __OSBusClock@l(r5) + lis r5, 0x10624DD3@ha + addi r5, r5, 0x10624DD3@l + srwi r0, r0, 2 + mulhwu r0, r5, r0 + srwi r0, r0, 6 + mulli r0, r0, 0x28 + subfc r7, r7, r4 + subfe r5, r6, r3 + xoris r6, r5, 0x8000 + xoris r5, r8, 0x8000 + subfc r0, r0, r7 + subfe r5, r5, r6 + subfe r5, r6, r6 + neg. r5, r5 + beq lbl_80383740 + li r29, 1 + b lbl_80383750 +lbl_80383740: + li r0, 0 + stw r0, HoldUp+4 + li r29, 0 + stw r0, HoldUp +lbl_80383750: + lis r5, GameChoice@ha + stw r29, LastState + lbz r0, GameChoice@l(r5) + clrlwi. r0, r0, 0x1a + beq lbl_80383800 + mulli r10, r0, 0x3c + lwz r0, 0xf8(r5) + lwz r9, __OSStartTime+4 + lwz r8, __OSStartTime + srwi r6, r0, 2 + srawi r0, r10, 0x1f + mullw r7, r0, r6 + mulhwu r0, r10, r6 + mullw r5, r10, r6 + addc r9, r9, r5 + li r31, 0 + add r7, r7, r0 + mullw r0, r10, r31 + add r0, r7, r0 + adde r8, r8, r0 + xoris r7, r8, 0x8000 + xoris r5, r3, 0x8000 + subfc r0, r4, r9 + subfe r5, r5, r7 + subfe r5, r7, r7 + neg. r5, r5 + beq lbl_80383800 + subfc r4, r9, r4 + subfe r3, r8, r3 + li r5, 0 + bl __div2i + li r5, 0 + li r6, 2 + bl __div2i + li r0, 1 + and r4, r4, r0 + and r0, r3, r31 + xor r3, r4, r31 + xor r0, r0, r31 + or. r0, r3, r0 + bne lbl_803837FC + li r29, 1 + b lbl_80383800 +lbl_803837FC: + li r29, 0 +lbl_80383800: + mr r3, r30 + bl OSRestoreInterrupts + mr r3, r29 + lwz r0, 0x1c(r1) + lwz r31, 0x14(r1) + lwz r30, 0x10(r1) + lwz r29, 0xc(r1) + addi r1, r1, 0x18 + mtlr r0 + blr +} +#pragma pop +/* clang-format on */ +#endif