Match and link OSAlarm

Former-commit-id: 438bf9053c
This commit is contained in:
Phillip Stephens 2022-11-03 09:17:03 -07:00
parent 3d299fc132
commit 0bffff2eb5
9 changed files with 430 additions and 74 deletions

View File

@ -25,7 +25,9 @@
"__ppc_eabi_linker.h": "c",
"hack.h": "c",
"db.h": "c",
"ppcarch.h": "c"
"ppcarch.h": "c",
"osalarm.h": "c",
"ospriv.h": "c"
},
"files.autoSave": "onFocusChange",
"files.insertFinalNewline": true,

View File

@ -2,8 +2,8 @@
.section .sbss
.balign 8
.global lbl_805A98B0
lbl_805A98B0:
.global AlarmQueue
AlarmQueue:
.skip 0x8
.section .text, "ax"
@ -20,10 +20,10 @@ OSInitAlarm:
/* 8037E080 0037AFE0 7C 03 20 40 */ cmplw r3, r4
/* 8037E084 0037AFE4 41 82 00 1C */ beq lbl_8037E0A0
/* 8037E088 0037AFE8 38 00 00 00 */ li r0, 0
/* 8037E08C 0037AFEC 38 6D AC F0 */ addi r3, r13, lbl_805A98B0@sda21
/* 8037E08C 0037AFEC 38 6D AC F0 */ addi r3, r13, AlarmQueue@sda21
/* 8037E090 0037AFF0 90 03 00 04 */ stw r0, 4(r3)
/* 8037E094 0037AFF4 38 60 00 08 */ li r3, 8
/* 8037E098 0037AFF8 90 0D AC F0 */ stw r0, lbl_805A98B0@sda21(r13)
/* 8037E098 0037AFF8 90 0D AC F0 */ stw r0, AlarmQueue@sda21(r13)
/* 8037E09C 0037AFFC 4B FF FE 2D */ bl __OSSetExceptionHandler
lbl_8037E0A0:
/* 8037E0A0 0037B000 80 01 00 0C */ lwz r0, 0xc(r1)
@ -93,7 +93,7 @@ lbl_8037E180:
/* 8037E184 0037B0E4 6F 24 80 00 */ xoris r4, r25, 0x8000
/* 8037E188 0037B0E8 93 DD 00 0C */ stw r30, 0xc(r29)
/* 8037E18C 0037B0EC 93 3D 00 08 */ stw r25, 8(r29)
/* 8037E190 0037B0F0 80 CD AC F0 */ lwz r6, lbl_805A98B0@sda21(r13)
/* 8037E190 0037B0F0 80 CD AC F0 */ lwz r6, AlarmQueue@sda21(r13)
/* 8037E194 0037B0F4 48 00 00 C4 */ b lbl_8037E258
lbl_8037E198:
/* 8037E198 0037B0F8 80 06 00 08 */ lwz r0, 8(r6)
@ -114,7 +114,7 @@ lbl_8037E198:
/* 8037E1D4 0037B134 93 A3 00 14 */ stw r29, 0x14(r3)
/* 8037E1D8 0037B138 48 00 01 24 */ b lbl_8037E2FC
lbl_8037E1DC:
/* 8037E1DC 0037B13C 93 AD AC F0 */ stw r29, lbl_805A98B0@sda21(r13)
/* 8037E1DC 0037B13C 93 AD AC F0 */ stw r29, AlarmQueue@sda21(r13)
/* 8037E1E0 0037B140 48 00 71 E9 */ bl __OSGetSystemTime
/* 8037E1E4 0037B144 80 DD 00 0C */ lwz r6, 0xc(r29)
/* 8037E1E8 0037B148 38 E0 00 00 */ li r7, 0
@ -153,7 +153,7 @@ lbl_8037E258:
/* 8037E25C 0037B1BC 40 82 FF 3C */ bne lbl_8037E198
/* 8037E260 0037B1C0 3B C0 00 00 */ li r30, 0
/* 8037E264 0037B1C4 93 DD 00 14 */ stw r30, 0x14(r29)
/* 8037E268 0037B1C8 38 6D AC F0 */ addi r3, r13, lbl_805A98B0@sda21
/* 8037E268 0037B1C8 38 6D AC F0 */ addi r3, r13, AlarmQueue@sda21
/* 8037E26C 0037B1CC 80 83 00 04 */ lwz r4, 4(r3)
/* 8037E270 0037B1D0 97 A3 00 04 */ stwu r29, 4(r3)
/* 8037E274 0037B1D4 28 04 00 00 */ cmplwi r4, 0
@ -163,7 +163,7 @@ lbl_8037E258:
/* 8037E284 0037B1E4 48 00 00 78 */ b lbl_8037E2FC
lbl_8037E288:
/* 8037E288 0037B1E8 93 A3 00 00 */ stw r29, 0(r3)
/* 8037E28C 0037B1EC 93 AD AC F0 */ stw r29, lbl_805A98B0@sda21(r13)
/* 8037E28C 0037B1EC 93 AD AC F0 */ stw r29, AlarmQueue@sda21(r13)
/* 8037E290 0037B1F0 48 00 71 39 */ bl __OSGetSystemTime
/* 8037E294 0037B1F4 80 DD 00 0C */ lwz r6, 0xc(r29)
/* 8037E298 0037B1F8 6F C5 80 00 */ xoris r5, r30, 0x8000
@ -285,7 +285,7 @@ lbl_8037E430:
/* 8037E434 0037B394 28 1D 00 00 */ cmplwi r29, 0
/* 8037E438 0037B398 40 82 00 14 */ bne lbl_8037E44C
/* 8037E43C 0037B39C 80 1E 00 10 */ lwz r0, 0x10(r30)
/* 8037E440 0037B3A0 38 6D AC F0 */ addi r3, r13, lbl_805A98B0@sda21
/* 8037E440 0037B3A0 38 6D AC F0 */ addi r3, r13, AlarmQueue@sda21
/* 8037E444 0037B3A4 90 03 00 04 */ stw r0, 4(r3)
/* 8037E448 0037B3A8 48 00 00 0C */ b lbl_8037E454
lbl_8037E44C:
@ -299,7 +299,7 @@ lbl_8037E454:
/* 8037E464 0037B3C4 48 00 00 80 */ b lbl_8037E4E4
lbl_8037E468:
/* 8037E468 0037B3C8 28 1D 00 00 */ cmplwi r29, 0
/* 8037E46C 0037B3CC 93 AD AC F0 */ stw r29, lbl_805A98B0@sda21(r13)
/* 8037E46C 0037B3CC 93 AD AC F0 */ stw r29, AlarmQueue@sda21(r13)
/* 8037E470 0037B3D0 41 82 00 74 */ beq lbl_8037E4E4
/* 8037E474 0037B3D4 48 00 6F 55 */ bl __OSGetSystemTime
/* 8037E478 0037B3D8 80 DD 00 0C */ lwz r6, 0xc(r29)
@ -356,7 +356,7 @@ DecrementerExceptionCallback:
/* 8037E528 0037B488 7C 9D 23 78 */ mr r29, r4
/* 8037E52C 0037B48C 93 81 02 E0 */ stw r28, 0x2e0(r1)
/* 8037E530 0037B490 48 00 6E 99 */ bl __OSGetSystemTime
/* 8037E534 0037B494 80 0D AC F0 */ lwz r0, lbl_805A98B0@sda21(r13)
/* 8037E534 0037B494 80 0D AC F0 */ lwz r0, AlarmQueue@sda21(r13)
/* 8037E538 0037B498 3B 84 00 00 */ addi r28, r4, 0
/* 8037E53C 0037B49C 3B C3 00 00 */ addi r30, r3, 0
/* 8037E540 0037B4A0 28 00 00 00 */ cmplwi r0, 0
@ -410,10 +410,10 @@ lbl_8037E5E8:
lbl_8037E5F0:
/* 8037E5F0 0037B550 80 7F 00 14 */ lwz r3, 0x14(r31)
/* 8037E5F4 0037B554 28 03 00 00 */ cmplwi r3, 0
/* 8037E5F8 0037B558 90 6D AC F0 */ stw r3, lbl_805A98B0@sda21(r13)
/* 8037E5F8 0037B558 90 6D AC F0 */ stw r3, AlarmQueue@sda21(r13)
/* 8037E5FC 0037B55C 40 82 00 14 */ bne lbl_8037E610
/* 8037E600 0037B560 38 00 00 00 */ li r0, 0
/* 8037E604 0037B564 38 6D AC F0 */ addi r3, r13, lbl_805A98B0@sda21
/* 8037E604 0037B564 38 6D AC F0 */ addi r3, r13, AlarmQueue@sda21
/* 8037E608 0037B568 90 03 00 04 */ stw r0, 4(r3)
/* 8037E60C 0037B56C 48 00 00 0C */ b lbl_8037E618
lbl_8037E610:
@ -438,7 +438,7 @@ lbl_8037E618:
/* 8037E654 0037B5B4 38 A0 00 00 */ li r5, 0
/* 8037E658 0037B5B8 4B FF FA 69 */ bl InsertAlarm
lbl_8037E65C:
/* 8037E65C 0037B5BC 83 8D AC F0 */ lwz r28, lbl_805A98B0@sda21(r13)
/* 8037E65C 0037B5BC 83 8D AC F0 */ lwz r28, AlarmQueue@sda21(r13)
/* 8037E660 0037B5C0 28 1C 00 00 */ cmplwi r28, 0
/* 8037E664 0037B5C4 41 82 00 74 */ beq lbl_8037E6D8
/* 8037E668 0037B5C8 48 00 6D 61 */ bl __OSGetSystemTime

View File

@ -7,6 +7,130 @@
extern "C" {
#endif
#define __OS_CONTEXT_FRAME 768
#define OS_CONTEXT_R0 0
#define OS_CONTEXT_R1 4
#define OS_CONTEXT_R2 8
#define OS_CONTEXT_R3 12
#define OS_CONTEXT_R4 16
#define OS_CONTEXT_R5 20
#define OS_CONTEXT_R6 24
#define OS_CONTEXT_R7 28
#define OS_CONTEXT_R8 32
#define OS_CONTEXT_R9 36
#define OS_CONTEXT_R10 40
#define OS_CONTEXT_R11 44
#define OS_CONTEXT_R12 48
#define OS_CONTEXT_R13 52
#define OS_CONTEXT_R14 56
#define OS_CONTEXT_R15 60
#define OS_CONTEXT_R16 64
#define OS_CONTEXT_R17 68
#define OS_CONTEXT_R18 72
#define OS_CONTEXT_R19 76
#define OS_CONTEXT_R20 80
#define OS_CONTEXT_R21 84
#define OS_CONTEXT_R22 88
#define OS_CONTEXT_R23 92
#define OS_CONTEXT_R24 96
#define OS_CONTEXT_R25 100
#define OS_CONTEXT_R26 104
#define OS_CONTEXT_R27 108
#define OS_CONTEXT_R28 112
#define OS_CONTEXT_R29 116
#define OS_CONTEXT_R30 120
#define OS_CONTEXT_R31 124
#define OS_CONTEXT_CR 128
#define OS_CONTEXT_LR 132
#define OS_CONTEXT_CTR 136
#define OS_CONTEXT_XER 140
#define OS_CONTEXT_FPR0 144
#define OS_CONTEXT_FPR1 152
#define OS_CONTEXT_FPR2 160
#define OS_CONTEXT_FPR3 168
#define OS_CONTEXT_FPR4 176
#define OS_CONTEXT_FPR5 184
#define OS_CONTEXT_FPR6 192
#define OS_CONTEXT_FPR7 200
#define OS_CONTEXT_FPR8 208
#define OS_CONTEXT_FPR9 216
#define OS_CONTEXT_FPR10 224
#define OS_CONTEXT_FPR11 232
#define OS_CONTEXT_FPR12 240
#define OS_CONTEXT_FPR13 248
#define OS_CONTEXT_FPR14 256
#define OS_CONTEXT_FPR15 264
#define OS_CONTEXT_FPR16 272
#define OS_CONTEXT_FPR17 280
#define OS_CONTEXT_FPR18 288
#define OS_CONTEXT_FPR19 296
#define OS_CONTEXT_FPR20 304
#define OS_CONTEXT_FPR21 312
#define OS_CONTEXT_FPR22 320
#define OS_CONTEXT_FPR23 328
#define OS_CONTEXT_FPR24 336
#define OS_CONTEXT_FPR25 344
#define OS_CONTEXT_FPR26 352
#define OS_CONTEXT_FPR27 360
#define OS_CONTEXT_FPR28 368
#define OS_CONTEXT_FPR29 376
#define OS_CONTEXT_FPR30 384
#define OS_CONTEXT_FPR31 392
#define OS_CONTEXT_FPSCR 400
#define OS_CONTEXT_SRR0 408
#define OS_CONTEXT_SRR1 412
#define OS_CONTEXT_MODE 416
#define OS_CONTEXT_STATE 418
#define OS_CONTEXT_GQR0 420
#define OS_CONTEXT_GQR1 424
#define OS_CONTEXT_GQR2 428
#define OS_CONTEXT_GQR3 432
#define OS_CONTEXT_GQR4 436
#define OS_CONTEXT_GQR5 440
#define OS_CONTEXT_GQR6 444
#define OS_CONTEXT_GQR7 448
#define __OSCONTEXT_PADDING 452
#define OS_CONTEXT_PSF0 456
#define OS_CONTEXT_PSF1 464
#define OS_CONTEXT_PSF2 472
#define OS_CONTEXT_PSF3 480
#define OS_CONTEXT_PSF4 488
#define OS_CONTEXT_PSF5 496
#define OS_CONTEXT_PSF6 504
#define OS_CONTEXT_PSF7 512
#define OS_CONTEXT_PSF8 520
#define OS_CONTEXT_PSF9 528
#define OS_CONTEXT_PSF10 536
#define OS_CONTEXT_PSF11 544
#define OS_CONTEXT_PSF12 552
#define OS_CONTEXT_PSF13 560
#define OS_CONTEXT_PSF14 568
#define OS_CONTEXT_PSF15 576
#define OS_CONTEXT_PSF16 584
#define OS_CONTEXT_PSF17 592
#define OS_CONTEXT_PSF18 600
#define OS_CONTEXT_PSF19 608
#define OS_CONTEXT_PSF20 616
#define OS_CONTEXT_PSF21 624
#define OS_CONTEXT_PSF22 632
#define OS_CONTEXT_PSF23 640
#define OS_CONTEXT_PSF24 648
#define OS_CONTEXT_PSF25 656
#define OS_CONTEXT_PSF26 664
#define OS_CONTEXT_PSF27 672
#define OS_CONTEXT_PSF28 680
#define OS_CONTEXT_PSF29 688
#define OS_CONTEXT_PSF30 696
#define OS_CONTEXT_PSF31 704
typedef struct OSContext {
u32 gpr[32];
u32 cr;

View File

@ -11,6 +11,26 @@ extern "C" {
typedef u8 __OSException;
typedef void (*__OSExceptionHandler)(__OSException exception, OSContext* context);
#define OS_EXCEPTION_SAVE_GPRS(context) \
stw r0, OS_CONTEXT_R0(context); \
stw r1, OS_CONTEXT_R1(context); \
stw r2, OS_CONTEXT_R2(context); \
stmw r6, OS_CONTEXT_R6(context); \
mfspr r0, GQR1; \
stw r0, OS_CONTEXT_GQR1(context); \
mfspr r0, GQR2; \
stw r0, OS_CONTEXT_GQR2(context); \
mfspr r0, GQR3; \
stw r0, OS_CONTEXT_GQR3(context); \
mfspr r0, GQR4; \
stw r0, OS_CONTEXT_GQR4(context); \
mfspr r0, GQR5; \
stw r0, OS_CONTEXT_GQR5(context); \
mfspr r0, GQR6; \
stw r0, OS_CONTEXT_GQR6(context); \
mfspr r0, GQR7; \
stw r0, OS_CONTEXT_GQR7(context);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,18 @@
#ifndef _DOLPHIN_OSPRIV
#define _DOLPHIN_OSPRIV
#include "dolphin/os.h"
#ifdef __cplusplus
extern "C" {
#endif
__OSExceptionHandler __OSGetExceptionHandler(__OSException exception);
OSTime __OSGetSystemTime();
OSTime __OSTimeToSystemTime(OSTime);
#ifdef __cplusplus
extern "C" {
#endif
#endif // _DOLPHIN_OSPRIV

View File

@ -7,15 +7,24 @@
extern "C" {
#endif
#define OS_RESETCODE_RESTART 0x80000000
#define OS_RESETCODE_SYSTEM 0x40000000
#define OS_RESETCODE_RESTART 0x80000000
#define OS_RESETCODE_SYSTEM 0x40000000
#define OS_RESETCODE_EXEC 0xC0000000
#define OS_RESETCODE_NETCONFIG 0xC0010000
#define OS_RESETCODE_EXEC 0xC0000000
#define OS_RESETCODE_NETCONFIG 0xC0010000
#define OS_RESET_RESTART 0
#define OS_RESET_HOTRESET 1
#define OS_RESET_SHUTDOWN 2
#define OS_RESET_TIMEOUT OSMillisecondsToTicks(1000)
#define OS_RESET_RESTART 0
#define OS_RESET_HOTRESET 1
#define OS_RESET_SHUTDOWN 2
#define OS_RESET_PRIO_SO 110
#define OS_RESET_PRIO_IP 111
#define OS_RESET_PRIO_CARD 127
#define OS_RESET_PRIO_PAD 127
#define OS_RESET_PRIO_GX 127
#define OS_RESET_PRIO_ALARM 4294967295
typedef BOOL (*OSResetFunction)(BOOL final);
typedef struct OSResetFunctionInfo OSResetFunctionInfo;

View File

@ -689,7 +689,7 @@ MTX_FILES :=\
OS_FILES :=\
$(BUILD_DIR)/src/Dolphin/os/__start.ep.o\
$(BUILD_DIR)/asm/Dolphin/os/OS.o\
$(BUILD_DIR)/asm/Dolphin/os/OSAlarm.o\
$(BUILD_DIR)/src/Dolphin/os/OSAlarm.ep.o\
$(BUILD_DIR)/asm/Dolphin/os/OSArena.o\
$(BUILD_DIR)/src/Dolphin/os/OSAudioSystem.ep.o\
$(BUILD_DIR)/src/Dolphin/os/OSCache.ep.o\

183
src/Dolphin/os/OSAlarm.c Normal file
View File

@ -0,0 +1,183 @@
#include "dolphin/PPCArch.h"
#include "dolphin/os/OSPriv.h"
static struct OSAlarmQueue {
OSAlarm* head;
OSAlarm* tail;
} AlarmQueue;
static void DecrementerExceptionHandler(__OSException exception, OSContext* context);
static BOOL OnReset(BOOL final);
void OSInitAlarm(void) {
if (__OSGetExceptionHandler(8) != DecrementerExceptionHandler) {
AlarmQueue.head = AlarmQueue.tail = NULL;
__OSSetExceptionHandler(8, DecrementerExceptionHandler);
}
}
void OSCreateAlarm(OSAlarm* alarm) {
alarm->handler = 0;
alarm->tag = 0;
}
static void SetTimer(OSAlarm* alarm) {
OSTime delta;
delta = alarm->fire - __OSGetSystemTime();
if (delta < 0) {
PPCMtdec(0);
} else if (delta < 0x80000000) {
PPCMtdec((u32)delta);
} else {
PPCMtdec(0x7fffffff);
}
}
static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler) {
OSAlarm* next;
OSAlarm* prev;
if (0 < alarm->period) {
OSTime time = __OSGetSystemTime();
fire = alarm->start;
if (alarm->start < time) {
fire += alarm->period * ((time - alarm->start) / alarm->period + 1);
}
}
alarm->handler = handler;
alarm->fire = fire;
for (next = AlarmQueue.head; next; next = next->next) {
if (next->fire <= fire) {
continue;
}
alarm->prev = next->prev;
next->prev = alarm;
alarm->next = next;
prev = alarm->prev;
if (prev) {
prev->next = alarm;
} else {
AlarmQueue.head = alarm;
SetTimer(alarm);
}
return;
}
alarm->next = 0;
prev = AlarmQueue.tail;
AlarmQueue.tail = alarm;
alarm->prev = prev;
if (prev) {
prev->next = alarm;
} else {
AlarmQueue.head = AlarmQueue.tail = alarm;
SetTimer(alarm);
}
}
void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler) {
BOOL enabled;
enabled = OSDisableInterrupts();
alarm->period = 0;
InsertAlarm(alarm, __OSGetSystemTime() + tick, handler);
OSRestoreInterrupts(enabled);
}
void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler) {
BOOL enabled;
enabled = OSDisableInterrupts();
alarm->period = period;
alarm->start = __OSTimeToSystemTime(start);
InsertAlarm(alarm, 0, handler);
OSRestoreInterrupts(enabled);
}
void OSCancelAlarm(OSAlarm* alarm) {
OSAlarm* next;
BOOL enabled;
enabled = OSDisableInterrupts();
if (alarm->handler == 0) {
OSRestoreInterrupts(enabled);
return;
}
next = alarm->next;
if (next == 0) {
AlarmQueue.tail = alarm->prev;
} else {
next->prev = alarm->prev;
}
if (alarm->prev) {
alarm->prev->next = next;
} else {
AlarmQueue.head = next;
if (next) {
SetTimer(next);
}
}
alarm->handler = 0;
OSRestoreInterrupts(enabled);
}
static void DecrementerExceptionCallback(register __OSException exception,
register OSContext* context) {
OSAlarm* alarm;
OSAlarm* next;
OSAlarmHandler handler;
OSTime time;
OSContext exceptionContext;
time = __OSGetSystemTime();
alarm = AlarmQueue.head;
if (alarm == 0) {
OSLoadContext(context);
}
if (time < alarm->fire) {
SetTimer(alarm);
OSLoadContext(context);
}
next = alarm->next;
AlarmQueue.head = next;
if (next == 0) {
AlarmQueue.tail = 0;
} else {
next->prev = 0;
}
handler = alarm->handler;
alarm->handler = 0;
if (0 < alarm->period) {
InsertAlarm(alarm, 0, handler);
}
if (AlarmQueue.head) {
SetTimer(AlarmQueue.head);
}
OSDisableScheduler();
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
handler(alarm, context);
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
OSEnableScheduler();
__OSReschedule();
OSLoadContext(context);
}
static asm void DecrementerExceptionHandler(register __OSException exception,
register OSContext* context) {
nofralloc
OS_EXCEPTION_SAVE_GPRS(context)
stwu r1, -8(r1)
b DecrementerExceptionCallback
}

View File

@ -171,64 +171,64 @@ asm void ICEnable() {
asm void __LCEnable() {
nofralloc
mfmsr r5
ori r5, r5, 0x1000
mtmsr r5
mfmsr r5
ori r5, r5, 0x1000
mtmsr r5
lis r3, OS_CACHED_REGION_PREFIX
li r4, CACHE_LINES
mtctr r4
lis r3, OS_CACHED_REGION_PREFIX
li r4, CACHE_LINES
mtctr r4
_touchloop:
dcbt 0,r3
dcbst 0,r3
addi r3,r3,32
bdnz _touchloop
mfspr r4, HID2
oris r4, r4, 0x100F
mtspr HID2, r4
dcbt 0,r3
dcbst 0,r3
addi r3,r3,32
bdnz _touchloop
mfspr r4, HID2
oris r4, r4, 0x100F
mtspr HID2, r4
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
lis r3, LC_BASE_PREFIX
ori r3, r3, 0x0002
mtspr DBAT3L, r3
ori r3, r3, 0x01fe
mtspr DBAT3U, r3
isync
lis r3, LC_BASE_PREFIX
li r6, LC_LINES
mtctr r6
li r6, 0
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
lis r3, LC_BASE_PREFIX
ori r3, r3, 0x0002
mtspr DBAT3L, r3
ori r3, r3, 0x01fe
mtspr DBAT3U, r3
isync
lis r3, LC_BASE_PREFIX
li r6, LC_LINES
mtctr r6
li r6, 0
_lockloop:
dcbz_l r6, r3
addi r3, r3, 32
bdnz+ _lockloop
dcbz_l r6, r3
addi r3, r3, 32
bdnz+ _lockloop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
blr
blr
}
void LCEnable() {