summaryrefslogtreecommitdiff
path: root/src/Dolphin/os/OSResetSW.c
blob: 97522133e3ca5863f1dd96a310bb34a9d29833d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#include <dolphin/os.h>

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;
}

#ifdef FULL_FRANK
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