summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2023-02-01 18:45:02 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2023-02-01 18:50:25 -0400
commit9fa0a7f1da1b70bee995f53c6c96c43189018772 (patch)
tree114548896790eaff23cdca84a025281de86bbb51
parent2ba3289286bbfcf9fcc13fd135d976058d8b6c2e (diff)
global: Import Dolphin SDK
This version comes from the Metroid Prime decompilation project. https://github.com/PrimeDecomp/prime
-rw-r--r--Makefile2
-rw-r--r--asm/Dolphin/base/PPCArch.s127
-rw-r--r--asm/Dolphin/db/db-data.s17
-rw-r--r--asm/Dolphin/db/db.s93
-rw-r--r--asm/Dolphin/os/OS-data.s123
-rw-r--r--asm/Dolphin/os/OS.s746
-rw-r--r--asm/Dolphin/os/OSAlarm.s503
-rw-r--r--asm/Dolphin/os/OSAlloc.s260
-rw-r--r--asm/Dolphin/os/OSAudioSystem-data.s43
-rw-r--r--asm/Dolphin/os/OSAudioSystem.s199
-rw-r--r--asm/Dolphin/os/OSCache-data.s151
-rw-r--r--asm/Dolphin/os/OSCache.s476
-rw-r--r--asm/Dolphin/os/OSContext-data.s135
-rw-r--r--asm/Dolphin/os/OSContext.s643
-rw-r--r--asm/Dolphin/os/OSError-data.s217
-rw-r--r--asm/Dolphin/os/OSError.s329
-rw-r--r--asm/Dolphin/os/OSInit.s263
-rw-r--r--asm/Dolphin/os/OSInterrupt-data.s23
-rw-r--r--asm/Dolphin/os/OSInterrupt.s696
-rw-r--r--asm/Dolphin/os/OSLink-data.s37
-rw-r--r--asm/Dolphin/os/OSLink.s604
-rw-r--r--asm/Dolphin/os/OSMemory-data.s15
-rw-r--r--asm/Dolphin/os/OSMemory.s229
-rw-r--r--asm/Dolphin/os/OSMessages.s159
-rw-r--r--asm/Dolphin/os/OSMutex.s190
-rw-r--r--asm/Dolphin/os/OSReboot.s173
-rw-r--r--asm/Dolphin/os/OSReset.s330
-rw-r--r--asm/Dolphin/os/OSResetSW.s258
-rw-r--r--asm/Dolphin/os/OSRtc.s785
-rw-r--r--asm/Dolphin/os/OSSync.s54
-rw-r--r--asm/Dolphin/os/OSThread.s1413
-rw-r--r--asm/Dolphin/os/OSTime-data.s41
-rw-r--r--asm/Dolphin/os/OSTime.s312
-rw-r--r--include/asm_types.h86
-rw-r--r--include/dolphin/CARDPriv.h132
-rw-r--r--include/dolphin/DVDPriv.h51
-rw-r--r--include/dolphin/GBAPriv.h62
-rw-r--r--include/dolphin/OSReset.h1
-rw-r--r--include/dolphin/OSRtcPriv.h34
-rw-r--r--include/dolphin/PPCArch.h2
-rw-r--r--include/dolphin/__ppc_eabi_init.h2
-rw-r--r--include/dolphin/__start.h48
-rw-r--r--include/dolphin/ai.h36
-rw-r--r--include/dolphin/ar.h45
-rw-r--r--include/dolphin/arq.h48
-rw-r--r--include/dolphin/card.h176
-rw-r--r--include/dolphin/db.h31
-rw-r--r--include/dolphin/dsp.h72
-rw-r--r--include/dolphin/dsp_regs.h9
-rw-r--r--include/dolphin/dtk.h47
-rw-r--r--include/dolphin/dvd.h136
-rw-r--r--include/dolphin/dvd_regs.h6
-rw-r--r--include/dolphin/gba.h65
-rw-r--r--include/dolphin/gx.h26
-rw-r--r--include/dolphin/gx/GXBump.h30
-rw-r--r--include/dolphin/gx/GXCommandList.h35
-rw-r--r--include/dolphin/gx/GXCull.h18
-rw-r--r--include/dolphin/gx/GXDispList.h18
-rw-r--r--include/dolphin/gx/GXDraw.h16
-rw-r--r--include/dolphin/gx/GXEnum.h891
-rw-r--r--include/dolphin/gx/GXExtra.h36
-rw-r--r--include/dolphin/gx/GXFifo.h37
-rw-r--r--include/dolphin/gx/GXFrameBuffer.h62
-rw-r--r--include/dolphin/gx/GXGeometry.h37
-rw-r--r--include/dolphin/gx/GXGet.h28
-rw-r--r--include/dolphin/gx/GXLighting.h32
-rw-r--r--include/dolphin/gx/GXManage.h24
-rw-r--r--include/dolphin/gx/GXPerf.h16
-rw-r--r--include/dolphin/gx/GXPixel.h29
-rw-r--r--include/dolphin/gx/GXPriv.h38
-rw-r--r--include/dolphin/gx/GXStruct.h108
-rw-r--r--include/dolphin/gx/GXTev.h37
-rw-r--r--include/dolphin/gx/GXTexture.h37
-rw-r--r--include/dolphin/gx/GXTransform.h33
-rw-r--r--include/dolphin/gx/GXVert.h141
-rw-r--r--include/dolphin/mtx.h145
-rw-r--r--include/dolphin/os.h175
-rw-r--r--include/dolphin/os/OSAlarm.h39
-rw-r--r--include/dolphin/os/OSArena.h13
-rw-r--r--include/dolphin/os/OSBootInfo.h39
-rw-r--r--include/dolphin/os/OSCache.h37
-rw-r--r--include/dolphin/os/OSContext.h170
-rw-r--r--include/dolphin/os/OSError.h39
-rw-r--r--include/dolphin/os/OSException.h56
-rw-r--r--include/dolphin/os/OSExpansion.h79
-rw-r--r--include/dolphin/os/OSFastCast.h48
-rw-r--r--include/dolphin/os/OSFont.h56
-rw-r--r--include/dolphin/os/OSInterrupt.h115
-rw-r--r--include/dolphin/os/OSMemory.h26
-rw-r--r--include/dolphin/os/OSMessage.h34
-rw-r--r--include/dolphin/os/OSModule.h115
-rw-r--r--include/dolphin/os/OSMutex.h35
-rw-r--r--include/dolphin/os/OSPriv.h18
-rw-r--r--include/dolphin/os/OSReboot.h10
-rw-r--r--include/dolphin/os/OSReset.h48
-rw-r--r--include/dolphin/os/OSResetSW.h22
-rw-r--r--include/dolphin/os/OSSerial.h69
-rw-r--r--include/dolphin/os/OSThread.h113
-rw-r--r--include/dolphin/pad.h128
-rw-r--r--include/dolphin/sipriv.h52
-rw-r--r--include/dolphin/types.h2
-rw-r--r--include/dolphin/vi.h35
-rw-r--r--include/dolphin/vifuncs.h21
-rw-r--r--include/dolphin/vitypes.h16
-rw-r--r--include/libc/ansi_files.h30
-rw-r--r--include/libc/assert.h20
-rw-r--r--include/libc/buffer_io.h14
-rw-r--r--include/libc/console_io.h17
-rw-r--r--include/libc/ctype.h69
-rw-r--r--include/libc/errno.h21
-rw-r--r--include/libc/file_struc.h22
-rw-r--r--include/libc/float.h18
-rw-r--r--include/libc/limits.h24
-rw-r--r--include/libc/locale.h39
-rw-r--r--include/libc/math.h210
-rw-r--r--include/libc/mem_funcs.h22
-rw-r--r--include/libc/stdarg.h39
-rw-r--r--include/libc/stddef.h23
-rw-r--r--include/libc/stdint.h14
-rw-r--r--include/libc/stdio.h135
-rw-r--r--include/libc/stdlib.h25
-rw-r--r--include/libc/string.h27
-rw-r--r--include/libc/wchar.h16
-rw-r--r--src/Dolphin/GBA/GBA.c109
-rw-r--r--src/Dolphin/GBA/GBAGetProcessStatus.c25
-rw-r--r--src/Dolphin/GBA/GBARead.c42
-rw-r--r--src/Dolphin/GBA/GBAWrite.c42
-rw-r--r--src/Dolphin/GBA/GBAXfer.c163
-rw-r--r--src/Dolphin/PPCArch.c563
-rw-r--r--src/Dolphin/ai.c378
-rw-r--r--src/Dolphin/ar/ar.c518
-rw-r--r--src/Dolphin/ar/arq.c170
-rw-r--r--src/Dolphin/card/CARDBios.c775
-rw-r--r--src/Dolphin/card/CARDBlock.c159
-rw-r--r--src/Dolphin/card/CARDCheck.c688
-rw-r--r--src/Dolphin/card/CARDCreate.c115
-rw-r--r--src/Dolphin/card/CARDDelete.c97
-rw-r--r--src/Dolphin/card/CARDDir.c92
-rw-r--r--src/Dolphin/card/CARDFormat.c127
-rw-r--r--src/Dolphin/card/CARDMount.c354
-rw-r--r--src/Dolphin/card/CARDNet.c33
-rw-r--r--src/Dolphin/card/CARDOpen.c123
-rw-r--r--src/Dolphin/card/CARDRdwr.c104
-rw-r--r--src/Dolphin/card/CARDRead.c141
-rw-r--r--src/Dolphin/card/CARDRename.c70
-rw-r--r--src/Dolphin/card/CARDStat.c144
-rw-r--r--src/Dolphin/card/CARDUnlock.c396
-rw-r--r--src/Dolphin/card/CARDWrite.c117
-rw-r--r--src/Dolphin/db.c43
-rw-r--r--src/Dolphin/dsp/dsp.c145
-rw-r--r--src/Dolphin/dsp/dsp_debug.c5
-rw-r--r--src/Dolphin/dsp/dsp_task.c389
-rw-r--r--src/Dolphin/dtk.c357
-rw-r--r--src/Dolphin/dvd/dvd.c1389
-rw-r--r--src/Dolphin/dvd/dvderror.c56
-rw-r--r--src/Dolphin/dvd/dvdfatal.c136
-rw-r--r--src/Dolphin/dvd/dvdfs.c656
-rw-r--r--src/Dolphin/dvd/dvdidutils.c27
-rw-r--r--src/Dolphin/dvd/dvdlow.c109
-rw-r--r--src/Dolphin/dvd/dvdqueue.c142
-rw-r--r--src/Dolphin/dvd/fstload.c67
-rw-r--r--src/Dolphin/exi/EXIBios.c692
-rw-r--r--src/Dolphin/exi/EXIUart.c174
-rw-r--r--src/Dolphin/gx/GXLight.c271
-rw-r--r--src/Dolphin/os/OS.c609
-rw-r--r--src/Dolphin/os/OSAlarm.c183
-rw-r--r--src/Dolphin/os/OSAlloc.c195
-rw-r--r--src/Dolphin/os/OSArena.c39
-rw-r--r--src/Dolphin/os/OSAudioSystem.c115
-rw-r--r--src/Dolphin/os/OSCache.c426
-rw-r--r--src/Dolphin/os/OSContext.c550
-rw-r--r--src/Dolphin/os/OSError.c360
-rw-r--r--src/Dolphin/os/OSFont.c757
-rw-r--r--src/Dolphin/os/OSInterrupt.c433
-rw-r--r--src/Dolphin/os/OSLink.c556
-rw-r--r--src/Dolphin/os/OSMemory.c247
-rw-r--r--src/Dolphin/os/OSMessage.c86
-rw-r--r--src/Dolphin/os/OSMutex.c223
-rw-r--r--src/Dolphin/os/OSReboot.c166
-rw-r--r--src/Dolphin/os/OSReset.c189
-rw-r--r--src/Dolphin/os/OSResetSW.c281
-rw-r--r--src/Dolphin/os/OSRtc.c544
-rw-r--r--src/Dolphin/os/OSSync.c29
-rw-r--r--src/Dolphin/os/OSThread.c852
-rw-r--r--src/Dolphin/os/OSTime.c137
-rw-r--r--src/Dolphin/os/__ppc_eabi_init.cpp70
-rw-r--r--src/Dolphin/os/__start.c165
-rw-r--r--src/Dolphin/pad/PadClamp.c166
-rw-r--r--src/Dolphin/pad/pad.c838
-rw-r--r--src/Dolphin/si/SIBios.c772
-rw-r--r--src/Dolphin/si/SISamplingRate.c54
191 files changed, 24436 insertions, 9813 deletions
diff --git a/Makefile b/Makefile
index c5019b6..1f61024 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ CPP := $(DEVKITPPC)/bin/powerpc-eabi-cpp -P
CC := $(WINE) tools/mwcc_compiler/$(MWCC_VERSION)/mwcceppc.exe
LD := $(WINE) tools/mwcc_compiler/$(MWCC_VERSION)/mwldeppc.exe
-INCLUDES := -i include/
+INCLUDES := -i include -i include/dolphin -i include/libc
ASM_INCLUDES := -I include/
ifdef LD_TEST
diff --git a/asm/Dolphin/base/PPCArch.s b/asm/Dolphin/base/PPCArch.s
deleted file mode 100644
index 45dc04b..0000000
--- a/asm/Dolphin/base/PPCArch.s
+++ /dev/null
@@ -1,127 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036c178
-.type func_8036c178, @function
-func_8036c178:
-/* 8036C178 7C6000A6 */ mfmsr r3
-/* 8036C17C 4E800020 */ blr
-.size func_8036c178, . - func_8036c178
-
-
-.global func_8036c180
-.type func_8036c180, @function
-func_8036c180:
-/* 8036C180 7C600124 */ mtmsr r3
-/* 8036C184 4E800020 */ blr
-.size func_8036c180, . - func_8036c180
-
-
-.global func_8036c188
-.type func_8036c188, @function
-func_8036c188:
-/* 8036C188 7C70FAA6 */ mfspr r3, 0x3f0
-/* 8036C18C 4E800020 */ blr
-.size func_8036c188, . - func_8036c188
-
-
-.global func_8036c190
-.type func_8036c190, @function
-func_8036c190:
-/* 8036C190 7C70FBA6 */ mtspr 0x3f0, r3
-/* 8036C194 4E800020 */ blr
-.size func_8036c190, . - func_8036c190
-
-
-.global func_8036c198
-.type func_8036c198, @function
-func_8036c198:
-/* 8036C198 7C79FAA6 */ mfspr r3, 0x3f9
-/* 8036C19C 4E800020 */ blr
-.size func_8036c198, . - func_8036c198
-
-
-.global func_8036c1a0
-.type func_8036c1a0, @function
-func_8036c1a0:
-/* 8036C1A0 7C79FBA6 */ mtspr 0x3f9, r3
-/* 8036C1A4 4E800020 */ blr
-.size func_8036c1a0, . - func_8036c1a0
-
-
-.global func_8036c1a8
-.type func_8036c1a8, @function
-func_8036c1a8:
-/* 8036C1A8 7C7603A6 */ mtspr 0x16, r3
-/* 8036C1AC 4E800020 */ blr
-.size func_8036c1a8, . - func_8036c1a8
-
-
-.global func_8036c1b0
-.type func_8036c1b0, @function
-func_8036c1b0:
-/* 8036C1B0 44000002 */ sc
-/* 8036C1B4 4E800020 */ blr
-.size func_8036c1b0, . - func_8036c1b0
-
-
-.global func_8036c1b8
-.type func_8036c1b8, @function
-func_8036c1b8:
-/* 8036C1B8 7C0004AC */ sync 0
-lbl_8036c1bc:
-/* 8036C1BC 60000000 */ nop
-/* 8036C1C0 38600000 */ li r3, 0x0
-/* 8036C1C4 60000000 */ nop
-/* 8036C1C8 4BFFFFF4 */ b lbl_8036c1bc
-.size func_8036c1b8, . - func_8036c1b8
-
-
-.global func_8036c1cc
-.type func_8036c1cc, @function
-func_8036c1cc:
-/* 8036C1CC 7C78E2A6 */ mfspr r3, 0x398
-/* 8036C1D0 4E800020 */ blr
-.size func_8036c1cc, . - func_8036c1cc
-
-
-.global func_8036c1d4
-.type func_8036c1d4, @function
-func_8036c1d4:
-/* 8036C1D4 7C78E3A6 */ mtspr 0x398, r3
-/* 8036C1D8 4E800020 */ blr
-.size func_8036c1d4, . - func_8036c1d4
-
-
-.global func_8036c1dc
-.type func_8036c1dc, @function
-func_8036c1dc:
-/* 8036C1DC 7C79E3A6 */ mtspr 0x399, r3
-/* 8036C1E0 4E800020 */ blr
-.size func_8036c1dc, . - func_8036c1dc
-
-
-.global func_8036c1e4
-.type func_8036c1e4, @function
-func_8036c1e4:
-/* 8036C1E4 7C0802A6 */ mflr r0
-/* 8036C1E8 90010004 */ stw r0, 4(r1)
-/* 8036C1EC 9421FFF8 */ stwu r1, -8(r1)
-/* 8036C1F0 4BFFFF99 */ bl func_8036c188
-/* 8036C1F4 60630200 */ ori r3, r3, 0x200
-/* 8036C1F8 4BFFFF99 */ bl func_8036c190
-/* 8036C1FC 8001000C */ lwz r0, 0xc(r1)
-/* 8036C200 38210008 */ addi r1, r1, 0x8
-/* 8036C204 7C0803A6 */ mtlr r0
-/* 8036C208 4E800020 */ blr
-.size func_8036c1e4, . - func_8036c1e4
-
-
-.global func_8036c20c
-.type func_8036c20c, @function
-func_8036c20c:
-/* 8036C20C FFA0004C */ mtfsb1 0x1d
-/* 8036C210 4E800020 */ blr
-.size func_8036c20c, . - func_8036c20c
-
diff --git a/asm/Dolphin/db/db-data.s b/asm/Dolphin/db/db-data.s
deleted file mode 100644
index 5d37baa..0000000
--- a/asm/Dolphin/db/db-data.s
+++ /dev/null
@@ -1,17 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804eeb98
-.type lbl_804eeb98, @object
-lbl_804eeb98:
-/* 804EEB98 44424578 */ .4byte 0x44424578
-/* 804EEB9C 63657074 */ .4byte 0x63657074
-/* 804EEBA0 696F6E44 */ .4byte 0x696f6e44
-/* 804EEBA4 65737469 */ .4byte 0x65737469
-/* 804EEBA8 6E617469 */ .4byte 0x6e617469
-/* 804EEBAC 6F6E0A00 */ .4byte 0x6f6e0a00
-.size lbl_804eeb98, . - lbl_804eeb98
-
diff --git a/asm/Dolphin/db/db.s b/asm/Dolphin/db/db.s
deleted file mode 100644
index 42438f1..0000000
--- a/asm/Dolphin/db/db.s
+++ /dev/null
@@ -1,93 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036c214
-.type func_8036c214, @function
-func_8036c214:
-/* 8036C214 3C808000 */ lis r4, 0x8000
-/* 8036C218 38040040 */ addi r0, r4, 0x40
-/* 8036C21C 3C608037 */ lis r3, func_8036c284@ha
-/* 8036C220 900DC9F0 */ stw r0, lbl_805c6810@sda21(0)
-/* 8036C224 3863C284 */ addi r3, r3, func_8036c284@l
-/* 8036C228 3C038000 */ addis r0, r3, 0x8000
-/* 8036C22C 90040048 */ stw r0, 0x48(r4)
-/* 8036C230 38000001 */ li r0, 0x1
-/* 8036C234 900DC9F4 */ stw r0, lbl_805c6814@sda21(0)
-/* 8036C238 4E800020 */ blr
-.size func_8036c214, . - func_8036c214
-
-
-.global func_8036c23c
-.type func_8036c23c, @function
-func_8036c23c:
-/* 8036C23C 7C0802A6 */ mflr r0
-/* 8036C240 3C60804F */ lis r3, lbl_804eeb98@ha
-/* 8036C244 90010004 */ stw r0, 4(r1)
-/* 8036C248 3863EB98 */ addi r3, r3, lbl_804eeb98@l
-/* 8036C24C 4CC63182 */ crclr 6
-/* 8036C250 9421FFE8 */ stwu r1, -0x18(r1)
-/* 8036C254 93E10014 */ stw r31, 0x14(r1)
-/* 8036C258 808000C0 */ lwz r4, 0xc0(0)
-/* 8036C25C 3FE48000 */ addis r31, r4, 0x8000
-/* 8036C260 48002455 */ bl func_8036e6b4
-/* 8036C264 7FE3FB78 */ mr r3, r31
-/* 8036C268 480020D9 */ bl func_8036e340
-/* 8036C26C 4BFFFF4D */ bl func_8036c1b8
-/* 8036C270 8001001C */ lwz r0, 0x1c(r1)
-/* 8036C274 83E10014 */ lwz r31, 0x14(r1)
-/* 8036C278 38210018 */ addi r1, r1, 0x18
-/* 8036C27C 7C0803A6 */ mtlr r0
-/* 8036C280 4E800020 */ blr
-.size func_8036c23c, . - func_8036c23c
-
-
-.global func_8036c284
-.type func_8036c284, @function
-func_8036c284:
-/* 8036C284 7C6000A6 */ mfmsr r3
-/* 8036C288 60630030 */ ori r3, r3, 0x30
-/* 8036C28C 7C600124 */ mtmsr r3
-/* 8036C290 4BFFFFAC */ b func_8036c23c
-.size func_8036c284, . - func_8036c284
-
-
-.global func_8036c294
-.type func_8036c294, @function
-func_8036c294:
-/* 8036C294 808DC9F0 */ lwz r4, lbl_805c6810@sda21(0)
-/* 8036C298 5460063E */ clrlwi r0, r3, 0x18
-/* 8036C29C 38600001 */ li r3, 0x1
-/* 8036C2A0 80840004 */ lwz r4, 4(r4)
-/* 8036C2A4 7C600030 */ slw r0, r3, r0
-/* 8036C2A8 7C830038 */ and r3, r4, r0
-/* 8036C2AC 4E800020 */ blr
-.size func_8036c294, . - func_8036c294
-
-
-.global func_8036c2b0
-.type func_8036c2b0, @function
-func_8036c2b0:
-/* 8036C2B0 9421FF90 */ stwu r1, -0x70(r1)
-/* 8036C2B4 40860024 */ bne- cr1, lbl_8036c2d8
-/* 8036C2B8 D8210028 */ stfd f1, 0x28(r1)
-/* 8036C2BC D8410030 */ stfd f2, 0x30(r1)
-/* 8036C2C0 D8610038 */ stfd f3, 0x38(r1)
-/* 8036C2C4 D8810040 */ stfd f4, 0x40(r1)
-/* 8036C2C8 D8A10048 */ stfd f5, 0x48(r1)
-/* 8036C2CC D8C10050 */ stfd f6, 0x50(r1)
-/* 8036C2D0 D8E10058 */ stfd f7, 0x58(r1)
-/* 8036C2D4 D9010060 */ stfd f8, 0x60(r1)
-lbl_8036c2d8:
-/* 8036C2D8 90610008 */ stw r3, 8(r1)
-/* 8036C2DC 9081000C */ stw r4, 0xc(r1)
-/* 8036C2E0 90A10010 */ stw r5, 0x10(r1)
-/* 8036C2E4 90C10014 */ stw r6, 0x14(r1)
-/* 8036C2E8 90E10018 */ stw r7, 0x18(r1)
-/* 8036C2EC 9101001C */ stw r8, 0x1c(r1)
-/* 8036C2F0 91210020 */ stw r9, 0x20(r1)
-/* 8036C2F4 91410024 */ stw r10, 0x24(r1)
-/* 8036C2F8 38210070 */ addi r1, r1, 0x70
-/* 8036C2FC 4E800020 */ blr
-.size func_8036c2b0, . - func_8036c2b0
-
diff --git a/asm/Dolphin/os/OS-data.s b/asm/Dolphin/os/OS-data.s
deleted file mode 100644
index 18adc6a..0000000
--- a/asm/Dolphin/os/OS-data.s
+++ /dev/null
@@ -1,123 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804eebb0
-.type lbl_804eebb0, @object
-lbl_804eebb0:
-/* 804EEBB0 0A446F6C */ .4byte 0x0a446f6c
-/* 804EEBB4 7068696E */ .4byte 0x7068696e
-/* 804EEBB8 204F5320 */ .4byte 0x204f5320
-/* 804EEBBC 24526576 */ .4byte 0x24526576
-/* 804EEBC0 6973696F */ .4byte 0x6973696f
-/* 804EEBC4 6E3A2035 */ .4byte 0x6e3a2035
-/* 804EEBC8 3420242E */ .4byte 0x3420242e
-/* 804EEBCC 0A000000 */ .4byte 0x0a000000
-/* 804EEBD0 4B65726E */ .4byte 0x4b65726e
-/* 804EEBD4 656C2062 */ .4byte 0x656c2062
-/* 804EEBD8 75696C74 */ .4byte 0x75696c74
-/* 804EEBDC 203A2025 */ .4byte 0x203a2025
-/* 804EEBE0 73202573 */ .4byte 0x73202573
-/* 804EEBE4 0A000000 */ .4byte 0x0a000000
-/* 804EEBE8 4A756E20 */ .4byte 0x4a756e20
-/* 804EEBEC 20352032 */ .4byte 0x20352032
-/* 804EEBF0 30303200 */ .4byte 0x30303200
-/* 804EEBF4 30323A30 */ .4byte 0x30323a30
-/* 804EEBF8 393A3132 */ .4byte 0x393a3132
-/* 804EEBFC 00000000 */ .4byte 0x00000000
-/* 804EEC00 436F6E73 */ .4byte 0x436f6e73
-/* 804EEC04 6F6C6520 */ .4byte 0x6f6c6520
-/* 804EEC08 54797065 */ .4byte 0x54797065
-/* 804EEC0C 203A2000 */ .4byte 0x203a2000
-/* 804EEC10 52657461 */ .4byte 0x52657461
-/* 804EEC14 696C2025 */ .4byte 0x696c2025
-/* 804EEC18 640A0000 */ .4byte 0x640a0000
-/* 804EEC1C 4D616320 */ .4byte 0x4d616320
-/* 804EEC20 456D756C */ .4byte 0x456d756c
-/* 804EEC24 61746F72 */ .4byte 0x61746f72
-/* 804EEC28 0A000000 */ .4byte 0x0a000000
-/* 804EEC2C 50432045 */ .4byte 0x50432045
-/* 804EEC30 6D756C61 */ .4byte 0x6d756c61
-/* 804EEC34 746F720A */ .4byte 0x746f720a
-/* 804EEC38 00000000 */ .4byte 0x00000000
-/* 804EEC3C 45505043 */ .4byte 0x45505043
-/* 804EEC40 20417274 */ .4byte 0x20417274
-/* 804EEC44 6875720A */ .4byte 0x6875720a
-/* 804EEC48 00000000 */ .4byte 0x00000000
-/* 804EEC4C 45505043 */ .4byte 0x45505043
-/* 804EEC50 204D696E */ .4byte 0x204d696e
-/* 804EEC54 6E6F770A */ .4byte 0x6e6f770a
-/* 804EEC58 00000000 */ .4byte 0x00000000
-/* 804EEC5C 44657665 */ .4byte 0x44657665
-/* 804EEC60 6C6F706D */ .4byte 0x6c6f706d
-/* 804EEC64 656E7420 */ .4byte 0x656e7420
-/* 804EEC68 48572564 */ .4byte 0x48572564
-/* 804EEC6C 0A000000 */ .4byte 0x0a000000
-/* 804EEC70 4D656D6F */ .4byte 0x4d656d6f
-/* 804EEC74 72792025 */ .4byte 0x72792025
-/* 804EEC78 64204D42 */ .4byte 0x64204d42
-/* 804EEC7C 0A000000 */ .4byte 0x0a000000
-/* 804EEC80 4172656E */ .4byte 0x4172656e
-/* 804EEC84 61203A20 */ .4byte 0x61203a20
-/* 804EEC88 30782578 */ .4byte 0x30782578
-/* 804EEC8C 202D2030 */ .4byte 0x202d2030
-/* 804EEC90 7825780A */ .4byte 0x7825780a
-/* 804EEC94 00000000 */ .4byte 0x00000000
-/* 804EEC98 00000100 */ .4byte 0x00000100
-/* 804EEC9C 00000200 */ .4byte 0x00000200
-/* 804EECA0 00000300 */ .4byte 0x00000300
-/* 804EECA4 00000400 */ .4byte 0x00000400
-/* 804EECA8 00000500 */ .4byte 0x00000500
-/* 804EECAC 00000600 */ .4byte 0x00000600
-/* 804EECB0 00000700 */ .4byte 0x00000700
-/* 804EECB4 00000800 */ .4byte 0x00000800
-/* 804EECB8 00000900 */ .4byte 0x00000900
-/* 804EECBC 00000C00 */ .4byte 0x00000c00
-/* 804EECC0 00000D00 */ .4byte 0x00000d00
-/* 804EECC4 00000F00 */ .4byte 0x00000f00
-/* 804EECC8 00001300 */ .4byte 0x00001300
-/* 804EECCC 00001400 */ .4byte 0x00001400
-/* 804EECD0 00001700 */ .4byte 0x00001700
-/* 804EECD4 496E7374 */ .4byte 0x496e7374
-/* 804EECD8 616C6C69 */ .4byte 0x616c6c69
-/* 804EECDC 6E67204F */ .4byte 0x6e67204f
-/* 804EECE0 53444249 */ .4byte 0x53444249
-/* 804EECE4 6E746567 */ .4byte 0x6e746567
-/* 804EECE8 7261746F */ .4byte 0x7261746f
-/* 804EECEC 720A0000 */ .4byte 0x720a0000
-/* 804EECF0 3E3E3E20 */ .4byte 0x3e3e3e20
-/* 804EECF4 4F53494E */ .4byte 0x4f53494e
-/* 804EECF8 49543A20 */ .4byte 0x49543a20
-/* 804EECFC 65786365 */ .4byte 0x65786365
-/* 804EED00 7074696F */ .4byte 0x7074696f
-/* 804EED04 6E202564 */ .4byte 0x6e202564
-/* 804EED08 20636F6D */ .4byte 0x20636f6d
-/* 804EED0C 6D616E64 */ .4byte 0x6d616e64
-/* 804EED10 65657265 */ .4byte 0x65657265
-/* 804EED14 64206279 */ .4byte 0x64206279
-/* 804EED18 2054524B */ .4byte 0x2054524b
-/* 804EED1C 0A000000 */ .4byte 0x0a000000
-/* 804EED20 3E3E3E20 */ .4byte 0x3e3e3e20
-/* 804EED24 4F53494E */ .4byte 0x4f53494e
-/* 804EED28 49543A20 */ .4byte 0x49543a20
-/* 804EED2C 65786365 */ .4byte 0x65786365
-/* 804EED30 7074696F */ .4byte 0x7074696f
-/* 804EED34 6E202564 */ .4byte 0x6e202564
-/* 804EED38 20766563 */ .4byte 0x20766563
-/* 804EED3C 746F7265 */ .4byte 0x746f7265
-/* 804EED40 6420746F */ .4byte 0x6420746f
-/* 804EED44 20646562 */ .4byte 0x20646562
-/* 804EED48 75676765 */ .4byte 0x75676765
-/* 804EED4C 720A0000 */ .4byte 0x720a0000
-/* 804EED50 45786365 */ .4byte 0x45786365
-/* 804EED54 7074696F */ .4byte 0x7074696f
-/* 804EED58 6E732069 */ .4byte 0x6e732069
-/* 804EED5C 6E697469 */ .4byte 0x6e697469
-/* 804EED60 616C697A */ .4byte 0x616c697a
-/* 804EED64 65642E2E */ .4byte 0x65642e2e
-/* 804EED68 2E0A0000 */ .4byte 0x2e0a0000
-/* 804EED6C 00000000 */ .4byte 0x00000000
-.size lbl_804eebb0, . - lbl_804eebb0
-
diff --git a/asm/Dolphin/os/OS.s b/asm/Dolphin/os/OS.s
deleted file mode 100644
index 8d30064..0000000
--- a/asm/Dolphin/os/OS.s
+++ /dev/null
@@ -1,746 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036c300
-.type func_8036c300, @function
-func_8036c300:
-/* 8036C300 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C304 28030000 */ cmplwi r3, 0
-/* 8036C308 41820010 */ beq- lbl_8036c318
-/* 8036C30C 8063002C */ lwz r3, 0x2c(r3)
-/* 8036C310 28030000 */ cmplwi r3, 0
-/* 8036C314 40820010 */ bne- lbl_8036c324
-lbl_8036c318:
-/* 8036C318 3C601000 */ lis r3, 0x1000
-/* 8036C31C 38630002 */ addi r3, r3, 0x2
-/* 8036C320 48000004 */ b lbl_8036c324
-lbl_8036c324:
-/* 8036C324 4E800020 */ blr
-.size func_8036c300, . - func_8036c300
-
-
-.global func_8036c328
-.type func_8036c328, @function
-func_8036c328:
-/* 8036C328 7C0802A6 */ mflr r0
-/* 8036C32C 90010004 */ stw r0, 4(r1)
-/* 8036C330 9421FFF0 */ stwu r1, -0x10(r1)
-/* 8036C334 93E1000C */ stw r31, 0xc(r1)
-/* 8036C338 4800447D */ bl func_803707b4
-/* 8036C33C 3C038000 */ addis r0, r3, 0x8000
-/* 8036C340 28000000 */ cmplwi r0, 0
-/* 8036C344 41820034 */ beq- lbl_8036c378
-/* 8036C348 38000000 */ li r0, 0x0
-/* 8036C34C 900DCA14 */ stw r0, lbl_805c6834@sda21(0)
-/* 8036C350 900DCA10 */ stw r0, lbl_805c6830@sda21(0)
-/* 8036C354 480012C5 */ bl func_8036d618
-/* 8036C358 7C7F1B78 */ mr r31, r3
-/* 8036C35C 480012C5 */ bl func_8036d620
-/* 8036C360 7FE3F850 */ subf r31, r3, r31
-/* 8036C364 480012BD */ bl func_8036d620
-/* 8036C368 7FE5FB78 */ mr r5, r31
-/* 8036C36C 38800000 */ li r4, 0x0
-/* 8036C370 4BCA1FC5 */ bl func_8000e334
-/* 8036C374 480000C8 */ b lbl_8036c43c
-lbl_8036c378:
-/* 8036C378 3C808130 */ lis r4, 0x8130
-/* 8036C37C 8064DFF0 */ lwz r3, -0x2010(r4)
-/* 8036C380 8004DFEC */ lwz r0, -0x2014(r4)
-/* 8036C384 28030000 */ cmplwi r3, 0
-/* 8036C388 906DCA14 */ stw r3, lbl_805c6834@sda21(0)
-/* 8036C38C 900DCA10 */ stw r0, lbl_805c6830@sda21(0)
-/* 8036C390 40820028 */ bne- lbl_8036c3b8
-/* 8036C394 48001285 */ bl func_8036d618
-/* 8036C398 7C7F1B78 */ mr r31, r3
-/* 8036C39C 48001285 */ bl func_8036d620
-/* 8036C3A0 7FE3F850 */ subf r31, r3, r31
-/* 8036C3A4 4800127D */ bl func_8036d620
-/* 8036C3A8 7FE5FB78 */ mr r5, r31
-/* 8036C3AC 38800000 */ li r4, 0x0
-/* 8036C3B0 4BCA1F85 */ bl func_8000e334
-/* 8036C3B4 48000088 */ b lbl_8036c43c
-lbl_8036c3b8:
-/* 8036C3B8 48001269 */ bl func_8036d620
-/* 8036C3BC 800DCA14 */ lwz r0, lbl_805c6834@sda21(0)
-/* 8036C3C0 7C030040 */ cmplw r3, r0
-/* 8036C3C4 40800078 */ bge- lbl_8036c43c
-/* 8036C3C8 48001251 */ bl func_8036d618
-/* 8036C3CC 800DCA14 */ lwz r0, lbl_805c6834@sda21(0)
-/* 8036C3D0 7C030040 */ cmplw r3, r0
-/* 8036C3D4 41810028 */ bgt- lbl_8036c3fc
-/* 8036C3D8 48001241 */ bl func_8036d618
-/* 8036C3DC 7C7F1B78 */ mr r31, r3
-/* 8036C3E0 48001241 */ bl func_8036d620
-/* 8036C3E4 7FE3F850 */ subf r31, r3, r31
-/* 8036C3E8 48001239 */ bl func_8036d620
-/* 8036C3EC 7FE5FB78 */ mr r5, r31
-/* 8036C3F0 38800000 */ li r4, 0x0
-/* 8036C3F4 4BCA1F41 */ bl func_8000e334
-/* 8036C3F8 48000044 */ b lbl_8036c43c
-lbl_8036c3fc:
-/* 8036C3FC 48001225 */ bl func_8036d620
-/* 8036C400 800DCA14 */ lwz r0, lbl_805c6834@sda21(0)
-/* 8036C404 7FE30050 */ subf r31, r3, r0
-/* 8036C408 48001219 */ bl func_8036d620
-/* 8036C40C 7FE5FB78 */ mr r5, r31
-/* 8036C410 38800000 */ li r4, 0x0
-/* 8036C414 4BCA1F21 */ bl func_8000e334
-/* 8036C418 48001201 */ bl func_8036d618
-/* 8036C41C 83EDCA10 */ lwz r31, lbl_805c6830@sda21(0)
-/* 8036C420 7C03F840 */ cmplw r3, r31
-/* 8036C424 40810018 */ ble- lbl_8036c43c
-/* 8036C428 480011F1 */ bl func_8036d618
-/* 8036C42C 7CBF1850 */ subf r5, r31, r3
-/* 8036C430 7FE3FB78 */ mr r3, r31
-/* 8036C434 38800000 */ li r4, 0x0
-/* 8036C438 4BCA1EFD */ bl func_8000e334
-lbl_8036c43c:
-/* 8036C43C 80010014 */ lwz r0, 0x14(r1)
-/* 8036C440 83E1000C */ lwz r31, 0xc(r1)
-/* 8036C444 38210010 */ addi r1, r1, 0x10
-/* 8036C448 7C0803A6 */ mtlr r0
-/* 8036C44C 4E800020 */ blr
-.size func_8036c328, . - func_8036c328
-
-
-.global func_8036c450
-.type func_8036c450, @function
-func_8036c450:
-/* 8036C450 8004000C */ lwz r0, 0xc(r4)
-/* 8036C454 2C000000 */ cmpwi r0, 0x0
-/* 8036C458 41820008 */ beq- lbl_8036c460
-/* 8036C45C 48000020 */ b lbl_8036c47c
-lbl_8036c460:
-/* 8036C460 3C608054 */ lis r3, lbl_8053ebe0@ha
-/* 8036C464 3863EBE0 */ addi r3, r3, lbl_8053ebe0@l
-/* 8036C468 A0030002 */ lhz r0, 2(r3)
-/* 8036C46C 3C608000 */ lis r3, 0x8000
-/* 8036C470 60008000 */ ori r0, r0, 0x8000
-/* 8036C474 B00330E6 */ sth r0, 0x30e6(r3)
-/* 8036C478 48000010 */ b lbl_8036c488
-lbl_8036c47c:
-/* 8036C47C 38000001 */ li r0, 0x1
-/* 8036C480 3C608000 */ lis r3, 0x8000
-/* 8036C484 B00330E6 */ sth r0, 0x30e6(r3)
-lbl_8036c488:
-/* 8036C488 4E800020 */ blr
-.size func_8036c450, . - func_8036c450
-
-
-.global func_8036c48c
-.type func_8036c48c, @function
-func_8036c48c:
-/* 8036C48C 7C0802A6 */ mflr r0
-/* 8036C490 90010004 */ stw r0, 4(r1)
-/* 8036C494 9421FFE8 */ stwu r1, -0x18(r1)
-/* 8036C498 93E10014 */ stw r31, 0x14(r1)
-/* 8036C49C 93C10010 */ stw r30, 0x10(r1)
-/* 8036C4A0 93A1000C */ stw r29, 0xc(r1)
-/* 8036C4A4 800DCA08 */ lwz r0, lbl_805c6828@sda21(0)
-/* 8036C4A8 3C808054 */ lis r4, lbl_8053ebe0@ha
-/* 8036C4AC 3C60804F */ lis r3, lbl_804eebb0@ha
-/* 8036C4B0 2C000000 */ cmpwi r0, 0x0
-/* 8036C4B4 3BC4EBE0 */ addi r30, r4, lbl_8053ebe0@l
-/* 8036C4B8 3BE3EBB0 */ addi r31, r3, lbl_804eebb0@l
-/* 8036C4BC 4082036C */ bne- lbl_8036c828
-/* 8036C4C0 38000001 */ li r0, 0x1
-/* 8036C4C4 900DCA08 */ stw r0, lbl_805c6828@sda21(0)
-/* 8036C4C8 4800631D */ bl func_803727e4
-/* 8036C4CC 908DCA24 */ stw r4, lbl_805c6844@sda21(0)
-/* 8036C4D0 906DCA20 */ stw r3, lbl_805c6840@sda21(0)
-/* 8036C4D4 48002601 */ bl func_8036ead4
-/* 8036C4D8 4BFFFD0D */ bl func_8036c1e4
-/* 8036C4DC 4BFFFD31 */ bl func_8036c20c
-/* 8036C4E0 38000000 */ li r0, 0x0
-/* 8036C4E4 3C808000 */ lis r4, 0x8000
-/* 8036C4E8 900DC9FC */ stw r0, lbl_805c681c@sda21(0)
-/* 8036C4EC 908DC9F8 */ stw r4, lbl_805c6818@sda21(0)
-/* 8036C4F0 900DCB04 */ stw r0, lbl_805c6924@sda21(0)
-/* 8036C4F4 806400F4 */ lwz r3, 0xf4(r4)
-/* 8036C4F8 28030000 */ cmplwi r3, 0
-/* 8036C4FC 41820034 */ beq- lbl_8036c530
-/* 8036C500 3803000C */ addi r0, r3, 0xc
-/* 8036C504 900DC9FC */ stw r0, lbl_805c681c@sda21(0)
-/* 8036C508 80030024 */ lwz r0, 0x24(r3)
-/* 8036C50C 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C510 900DCBDC */ stw r0, lbl_805c69fc@sda21(0)
-/* 8036C514 80030000 */ lwz r0, 0(r3)
-/* 8036C518 5400063E */ clrlwi r0, r0, 0x18
-/* 8036C51C 980430E8 */ stb r0, 0x30e8(r4)
-/* 8036C520 800DCBDC */ lwz r0, lbl_805c69fc@sda21(0)
-/* 8036C524 5400063E */ clrlwi r0, r0, 0x18
-/* 8036C528 980430E9 */ stb r0, 0x30e9(r4)
-/* 8036C52C 48000028 */ b lbl_8036c554
-lbl_8036c530:
-/* 8036C530 80040034 */ lwz r0, 0x34(r4)
-/* 8036C534 28000000 */ cmplwi r0, 0
-/* 8036C538 4182001C */ beq- lbl_8036c554
-/* 8036C53C 886430E8 */ lbz r3, 0x30e8(r4)
-/* 8036C540 380DCA00 */ addi r0, 0, lbl_805c6820@sda21
-/* 8036C544 906DCA00 */ stw r3, lbl_805c6820@sda21(0)
-/* 8036C548 900DC9FC */ stw r0, lbl_805c681c@sda21(0)
-/* 8036C54C 880430E9 */ lbz r0, 0x30e9(r4)
-/* 8036C550 900DCBDC */ stw r0, lbl_805c69fc@sda21(0)
-lbl_8036c554:
-/* 8036C554 38000001 */ li r0, 0x1
-/* 8036C558 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C55C 900DCB04 */ stw r0, lbl_805c6924@sda21(0)
-/* 8036C560 80630030 */ lwz r3, 0x30(r3)
-/* 8036C564 28030000 */ cmplwi r3, 0
-/* 8036C568 40820010 */ bne- lbl_8036c578
-/* 8036C56C 3C60805E */ lis r3, 0x805e
-/* 8036C570 386329E0 */ addi r3, r3, 0x29e0
-/* 8036C574 48000004 */ b lbl_8036c578
-lbl_8036c578:
-/* 8036C578 480010B9 */ bl func_8036d630
-/* 8036C57C 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C580 80030030 */ lwz r0, 0x30(r3)
-/* 8036C584 28000000 */ cmplwi r0, 0
-/* 8036C588 40820030 */ bne- lbl_8036c5b8
-/* 8036C58C 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C590 28030000 */ cmplwi r3, 0
-/* 8036C594 41820024 */ beq- lbl_8036c5b8
-/* 8036C598 80030000 */ lwz r0, 0(r3)
-/* 8036C59C 28000002 */ cmplwi r0, 2
-/* 8036C5A0 40800018 */ bge- lbl_8036c5b8
-/* 8036C5A4 3C60805E */ lis r3, 0x805e
-/* 8036C5A8 386309C8 */ addi r3, r3, 0x9c8
-/* 8036C5AC 3803001F */ addi r0, r3, 0x1f
-/* 8036C5B0 54030034 */ rlwinm r3, r0, 0, 0, 0x1a
-/* 8036C5B4 4800107D */ bl func_8036d630
-lbl_8036c5b8:
-/* 8036C5B8 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C5BC 80630034 */ lwz r3, 0x34(r3)
-/* 8036C5C0 28030000 */ cmplwi r3, 0
-/* 8036C5C4 40820010 */ bne- lbl_8036c5d4
-/* 8036C5C8 3C608170 */ lis r3, 0x8170
-/* 8036C5CC 38630000 */ addi r3, r3, 0x0
-/* 8036C5D0 48000004 */ b lbl_8036c5d4
-lbl_8036c5d4:
-/* 8036C5D4 48001055 */ bl func_8036d628
-/* 8036C5D8 4800026D */ bl func_8036c844
-/* 8036C5DC 48004FE1 */ bl func_803715bc
-/* 8036C5E0 4800067D */ bl func_8036cc5c
-/* 8036C5E4 480034C9 */ bl func_8036faac
-/* 8036C5E8 48002569 */ bl func_8036eb50
-/* 8036C5EC 3C608037 */ lis r3, func_803707e4@ha
-/* 8036C5F0 388307E4 */ addi r4, r3, func_803707e4@l
-/* 8036C5F4 38600016 */ li r3, 0x16
-/* 8036C5F8 48002529 */ bl func_8036eb20
-/* 8036C5FC 48002071 */ bl func_8036e66c
-/* 8036C600 48001759 */ bl func_8036dd58
-/* 8036C604 480C0065 */ bl func_8042c668
-/* 8036C608 480C1315 */ bl func_8042d91c
-/* 8036C60C 480046DD */ bl func_80370ce8
-/* 8036C610 48005011 */ bl func_80371620
-/* 8036C614 48001025 */ bl func_8036d638
-/* 8036C618 4BFFFBB5 */ bl func_8036c1cc
-/* 8036C61C 54630080 */ rlwinm r3, r3, 0, 2, 0
-/* 8036C620 4BFFFBB5 */ bl func_8036c1d4
-/* 8036C624 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C628 3883002C */ addi r4, r3, 0x2c
-/* 8036C62C 80040000 */ lwz r0, 0(r4)
-/* 8036C630 540000C6 */ rlwinm r0, r0, 0, 3, 3
-/* 8036C634 28000000 */ cmplwi r0, 0
-/* 8036C638 41820014 */ beq- lbl_8036c64c
-/* 8036C63C 3C601000 */ lis r3, 0x1000
-/* 8036C640 38030004 */ addi r0, r3, 0x4
-/* 8036C644 90040000 */ stw r0, 0(r4)
-/* 8036C648 4800000C */ b lbl_8036c654
-lbl_8036c64c:
-/* 8036C64C 38000001 */ li r0, 0x1
-/* 8036C650 90040000 */ stw r0, 0(r4)
-lbl_8036c654:
-/* 8036C654 3C60CC00 */ lis r3, 0xcc00
-/* 8036C658 808DC9F8 */ lwz r4, lbl_805c6818@sda21(0)
-/* 8036C65C 38633000 */ addi r3, r3, 0x3000
-/* 8036C660 8003002C */ lwz r0, 0x2c(r3)
-/* 8036C664 8064002C */ lwz r3, 0x2c(r4)
-/* 8036C668 54000006 */ rlwinm r0, r0, 0, 0, 3
-/* 8036C66C 5400273E */ srwi r0, r0, 0x1c
-/* 8036C670 7C030214 */ add r0, r3, r0
-/* 8036C674 9004002C */ stw r0, 0x2c(r4)
-/* 8036C678 800DCA18 */ lwz r0, lbl_805c6838@sda21(0)
-/* 8036C67C 2C000000 */ cmpwi r0, 0x0
-/* 8036C680 40820008 */ bne- lbl_8036c688
-/* 8036C684 48003805 */ bl func_8036fe88
-lbl_8036c688:
-/* 8036C688 7FE3FB78 */ mr r3, r31
-/* 8036C68C 4CC63182 */ crclr 6
-/* 8036C690 48002025 */ bl func_8036e6b4
-/* 8036C694 387F0020 */ addi r3, r31, 0x20
-/* 8036C698 4CC63182 */ crclr 6
-/* 8036C69C 389F0038 */ addi r4, r31, 0x38
-/* 8036C6A0 38BF0044 */ addi r5, r31, 0x44
-/* 8036C6A4 48002011 */ bl func_8036e6b4
-/* 8036C6A8 387F0050 */ addi r3, r31, 0x50
-/* 8036C6AC 4CC63182 */ crclr 6
-/* 8036C6B0 48002005 */ bl func_8036e6b4
-/* 8036C6B4 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C6B8 28030000 */ cmplwi r3, 0
-/* 8036C6BC 41820010 */ beq- lbl_8036c6cc
-/* 8036C6C0 8083002C */ lwz r4, 0x2c(r3)
-/* 8036C6C4 28040000 */ cmplwi r4, 0
-/* 8036C6C8 40820010 */ bne- lbl_8036c6d8
-lbl_8036c6cc:
-/* 8036C6CC 3C601000 */ lis r3, 0x1000
-/* 8036C6D0 38830002 */ addi r4, r3, 0x2
-/* 8036C6D4 48000004 */ b lbl_8036c6d8
-lbl_8036c6d8:
-/* 8036C6D8 548000C6 */ rlwinm r0, r4, 0, 3, 3
-/* 8036C6DC 28000000 */ cmplwi r0, 0
-/* 8036C6E0 40820014 */ bne- lbl_8036c6f4
-/* 8036C6E4 4CC63182 */ crclr 6
-/* 8036C6E8 387F0060 */ addi r3, r31, 0x60
-/* 8036C6EC 48001FC9 */ bl func_8036e6b4
-/* 8036C6F0 4800008C */ b lbl_8036c77c
-lbl_8036c6f4:
-/* 8036C6F4 3C601000 */ lis r3, 0x1000
-/* 8036C6F8 38030002 */ addi r0, r3, 0x2
-/* 8036C6FC 7C040000 */ cmpw r4, r0
-/* 8036C700 41820048 */ beq- lbl_8036c748
-/* 8036C704 40800014 */ bge- lbl_8036c718
-/* 8036C708 7C041800 */ cmpw r4, r3
-/* 8036C70C 4182001C */ beq- lbl_8036c728
-/* 8036C710 40800028 */ bge- lbl_8036c738
-/* 8036C714 48000054 */ b lbl_8036c768
-lbl_8036c718:
-/* 8036C718 38030004 */ addi r0, r3, 0x4
-/* 8036C71C 7C040000 */ cmpw r4, r0
-/* 8036C720 40800048 */ bge- lbl_8036c768
-/* 8036C724 48000034 */ b lbl_8036c758
-lbl_8036c728:
-/* 8036C728 387F006C */ addi r3, r31, 0x6c
-/* 8036C72C 4CC63182 */ crclr 6
-/* 8036C730 48001F85 */ bl func_8036e6b4
-/* 8036C734 48000048 */ b lbl_8036c77c
-lbl_8036c738:
-/* 8036C738 387F007C */ addi r3, r31, 0x7c
-/* 8036C73C 4CC63182 */ crclr 6
-/* 8036C740 48001F75 */ bl func_8036e6b4
-/* 8036C744 48000038 */ b lbl_8036c77c
-lbl_8036c748:
-/* 8036C748 387F008C */ addi r3, r31, 0x8c
-/* 8036C74C 4CC63182 */ crclr 6
-/* 8036C750 48001F65 */ bl func_8036e6b4
-/* 8036C754 48000028 */ b lbl_8036c77c
-lbl_8036c758:
-/* 8036C758 387F009C */ addi r3, r31, 0x9c
-/* 8036C75C 4CC63182 */ crclr 6
-/* 8036C760 48001F55 */ bl func_8036e6b4
-/* 8036C764 48000018 */ b lbl_8036c77c
-lbl_8036c768:
-/* 8036C768 3C84F000 */ addis r4, r4, 0xf000
-/* 8036C76C 4CC63182 */ crclr 6
-/* 8036C770 387F00AC */ addi r3, r31, 0xac
-/* 8036C774 3884FFFD */ addi r4, r4, -0x3
-/* 8036C778 48001F3D */ bl func_8036e6b4
-lbl_8036c77c:
-/* 8036C77C 808DC9F8 */ lwz r4, lbl_805c6818@sda21(0)
-/* 8036C780 387F00C0 */ addi r3, r31, 0xc0
-/* 8036C784 4CC63182 */ crclr 6
-/* 8036C788 80040028 */ lwz r0, 0x28(r4)
-/* 8036C78C 5404653E */ srwi r4, r0, 0x14
-/* 8036C790 48001F25 */ bl func_8036e6b4
-/* 8036C794 48000E85 */ bl func_8036d618
-/* 8036C798 7C7D1B78 */ mr r29, r3
-/* 8036C79C 48000E85 */ bl func_8036d620
-/* 8036C7A0 7C641B78 */ mr r4, r3
-/* 8036C7A4 4CC63182 */ crclr 6
-/* 8036C7A8 7FA5EB78 */ mr r5, r29
-/* 8036C7AC 387F00D0 */ addi r3, r31, 0xd0
-/* 8036C7B0 48001F05 */ bl func_8036e6b4
-/* 8036C7B4 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C7B8 28030000 */ cmplwi r3, 0
-/* 8036C7BC 41820014 */ beq- lbl_8036c7d0
-/* 8036C7C0 80030000 */ lwz r0, 0(r3)
-/* 8036C7C4 28000002 */ cmplwi r0, 2
-/* 8036C7C8 41800008 */ blt- lbl_8036c7d0
-/* 8036C7CC 48025B45 */ bl func_80392310
-lbl_8036c7d0:
-/* 8036C7D0 4BFFFB59 */ bl func_8036c328
-/* 8036C7D4 48002315 */ bl func_8036eae8
-/* 8036C7D8 800DCA18 */ lwz r0, lbl_805c6838@sda21(0)
-/* 8036C7DC 2C000000 */ cmpwi r0, 0x0
-/* 8036C7E0 40820048 */ bne- lbl_8036c828
-/* 8036C7E4 48008929 */ bl func_8037510c
-/* 8036C7E8 800DCA04 */ lwz r0, lbl_805c6824@sda21(0)
-/* 8036C7EC 2C000000 */ cmpwi r0, 0x0
-/* 8036C7F0 41820018 */ beq- lbl_8036c808
-/* 8036C7F4 3C600001 */ lis r3, 1
-/* 8036C7F8 38039000 */ addi r0, r3, -0x7000
-/* 8036C7FC 3C608000 */ lis r3, 0x8000
-/* 8036C800 B00330E6 */ sth r0, 0x30e6(r3)
-/* 8036C804 48000024 */ b lbl_8036c828
-lbl_8036c808:
-/* 8036C808 7FC3F378 */ mr r3, r30
-/* 8036C80C 38800020 */ li r4, 0x20
-/* 8036C810 480010D1 */ bl func_8036d8e0
-/* 8036C814 3C608037 */ lis r3, func_8036c450@ha
-/* 8036C818 38A3C450 */ addi r5, r3, func_8036c450@l
-/* 8036C81C 7FC4F378 */ mr r4, r30
-/* 8036C820 387E0020 */ addi r3, r30, 0x20
-/* 8036C824 4800A609 */ bl func_80376e2c
-lbl_8036c828:
-/* 8036C828 8001001C */ lwz r0, 0x1c(r1)
-/* 8036C82C 83E10014 */ lwz r31, 0x14(r1)
-/* 8036C830 83C10010 */ lwz r30, 0x10(r1)
-/* 8036C834 83A1000C */ lwz r29, 0xc(r1)
-/* 8036C838 38210018 */ addi r1, r1, 0x18
-/* 8036C83C 7C0803A6 */ mtlr r0
-/* 8036C840 4E800020 */ blr
-.size func_8036c48c, . - func_8036c48c
-
-
-.global func_8036c844
-.type func_8036c844, @function
-func_8036c844:
-/* 8036C844 7C0802A6 */ mflr r0
-/* 8036C848 90010004 */ stw r0, 4(r1)
-/* 8036C84C 9421FFC8 */ stwu r1, -0x38(r1)
-/* 8036C850 BE810008 */ stmw r20, 8(r1)
-/* 8036C854 3C608000 */ lis r3, 0x8000
-/* 8036C858 80030060 */ lwz r0, 0x60(r3)
-/* 8036C85C 3C808037 */ lis r4, func_8036cb84@ha
-/* 8036C860 3BC4CB84 */ addi r30, r4, func_8036cb84@l
-/* 8036C864 3CA08037 */ lis r5, func_8036cb1c@ha
-/* 8036C868 833E0000 */ lwz r25, 0(r30)
-/* 8036C86C 3C808037 */ lis r4, func_8036cbb4@ha
-/* 8036C870 38A5CB1C */ addi r5, r5, func_8036cb1c@l
-/* 8036C874 3884CBB4 */ addi r4, r4, func_8036cbb4@l
-/* 8036C878 3CC0804F */ lis r6, lbl_804eebb0@ha
-/* 8036C87C 28000000 */ cmplwi r0, 0
-/* 8036C880 7CB82B78 */ mr r24, r5
-/* 8036C884 3BA6EBB0 */ addi r29, r6, lbl_804eebb0@l
-/* 8036C888 7EE52050 */ subf r23, r5, r4
-/* 8036C88C 3A830060 */ addi r20, r3, 0x60
-/* 8036C890 4082004C */ bne- lbl_8036c8dc
-/* 8036C894 387D0124 */ addi r3, r29, 0x124
-/* 8036C898 4CC63182 */ crclr 6
-/* 8036C89C 4BFFFA15 */ bl func_8036c2b0
-/* 8036C8A0 3C808037 */ lis r4, func_8036cac4@ha
-/* 8036C8A4 3C608037 */ lis r3, func_8036cae8@ha
-/* 8036C8A8 3803CAE8 */ addi r0, r3, func_8036cae8@l
-/* 8036C8AC 3884CAC4 */ addi r4, r4, func_8036cac4@l
-/* 8036C8B0 7EA40050 */ subf r21, r4, r0
-/* 8036C8B4 7E83A378 */ mr r3, r20
-/* 8036C8B8 7EA5AB78 */ mr r5, r21
-/* 8036C8BC 4BCA1B61 */ bl func_8000e41c
-/* 8036C8C0 7E83A378 */ mr r3, r20
-/* 8036C8C4 7EA4AB78 */ mr r4, r21
-/* 8036C8C8 480010B1 */ bl func_8036d978
-/* 8036C8CC 7C0004AC */ sync 0
-/* 8036C8D0 7E83A378 */ mr r3, r20
-/* 8036C8D4 7EA4AB78 */ mr r4, r21
-/* 8036C8D8 48001101 */ bl func_8036d9d8
-lbl_8036c8dc:
-/* 8036C8DC 3C808037 */ lis r4, func_8036cae8@ha
-/* 8036C8E0 3C608037 */ lis r3, func_8036caec@ha
-/* 8036C8E4 3BE4CAE8 */ addi r31, r4, func_8036cae8@l
-/* 8036C8E8 3803CAEC */ addi r0, r3, func_8036caec@l
-/* 8036C8EC 3B9D00E8 */ addi r28, r29, 0xe8
-/* 8036C8F0 7F7F0050 */ subf r27, r31, r0
-/* 8036C8F4 3B400000 */ li r26, 0x0
-/* 8036C8F8 48000004 */ b lbl_8036c8fc
-lbl_8036c8fc:
-/* 8036C8FC 3C608037 */ lis r3, func_8036cb74@ha
-/* 8036C900 3AA3CB74 */ addi r21, r3, func_8036cb74@l
-/* 8036C904 3EC06000 */ lis r22, 0x6000
-/* 8036C908 48000004 */ b lbl_8036c90c
-lbl_8036c90c:
-/* 8036C90C 48000148 */ b lbl_8036ca54
-lbl_8036c910:
-/* 8036C910 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C914 28030000 */ cmplwi r3, 0
-/* 8036C918 41820034 */ beq- lbl_8036c94c
-/* 8036C91C 80030000 */ lwz r0, 0(r3)
-/* 8036C920 28000002 */ cmplwi r0, 2
-/* 8036C924 41800028 */ blt- lbl_8036c94c
-/* 8036C928 7F43D378 */ mr r3, r26
-/* 8036C92C 4BFFF969 */ bl func_8036c294
-/* 8036C930 2C030000 */ cmpwi r3, 0x0
-/* 8036C934 41820018 */ beq- lbl_8036c94c
-/* 8036C938 387D0140 */ addi r3, r29, 0x140
-/* 8036C93C 4CC63182 */ crclr 6
-/* 8036C940 5744063E */ clrlwi r4, r26, 0x18
-/* 8036C944 4BFFF96D */ bl func_8036c2b0
-/* 8036C948 48000104 */ b lbl_8036ca4c
-lbl_8036c94c:
-/* 8036C94C 5754063E */ clrlwi r20, r26, 0x18
-/* 8036C950 7F20A378 */ or r0, r25, r20
-/* 8036C954 901E0000 */ stw r0, 0(r30)
-/* 8036C958 7F43D378 */ mr r3, r26
-/* 8036C95C 4BFFF939 */ bl func_8036c294
-/* 8036C960 2C030000 */ cmpwi r3, 0x0
-/* 8036C964 41820028 */ beq- lbl_8036c98c
-/* 8036C968 7E84A378 */ mr r4, r20
-/* 8036C96C 4CC63182 */ crclr 6
-/* 8036C970 387D0170 */ addi r3, r29, 0x170
-/* 8036C974 4BFFF93D */ bl func_8036c2b0
-/* 8036C978 7EA3AB78 */ mr r3, r21
-/* 8036C97C 7FE4FB78 */ mr r4, r31
-/* 8036C980 7F65DB78 */ mr r5, r27
-/* 8036C984 4BCA1A99 */ bl func_8000e41c
-/* 8036C988 48000090 */ b lbl_8036ca18
-lbl_8036c98c:
-/* 8036C98C 7EA4AB78 */ mr r4, r21
-/* 8036C990 48000004 */ b lbl_8036c994
-lbl_8036c994:
-/* 8036C994 281B0000 */ cmplwi r27, 0
-/* 8036C998 387B0003 */ addi r3, r27, 0x3
-/* 8036C99C 5463F0BE */ srwi r3, r3, 2
-/* 8036C9A0 40810078 */ ble- lbl_8036ca18
-/* 8036C9A4 5460E8FE */ srwi r0, r3, 3
-/* 8036C9A8 28000000 */ cmplwi r0, 0
-/* 8036C9AC 7C0903A6 */ mtctr r0
-/* 8036C9B0 41820054 */ beq- lbl_8036ca04
-/* 8036C9B4 48000004 */ b lbl_8036c9b8
-lbl_8036c9b8:
-/* 8036C9B8 92C40000 */ stw r22, 0(r4)
-/* 8036C9BC 38840004 */ addi r4, r4, 0x4
-/* 8036C9C0 92C40000 */ stw r22, 0(r4)
-/* 8036C9C4 38840004 */ addi r4, r4, 0x4
-/* 8036C9C8 92C40000 */ stw r22, 0(r4)
-/* 8036C9CC 38840004 */ addi r4, r4, 0x4
-/* 8036C9D0 92C40000 */ stw r22, 0(r4)
-/* 8036C9D4 38840004 */ addi r4, r4, 0x4
-/* 8036C9D8 92C40000 */ stw r22, 0(r4)
-/* 8036C9DC 38840004 */ addi r4, r4, 0x4
-/* 8036C9E0 92C40000 */ stw r22, 0(r4)
-/* 8036C9E4 38840004 */ addi r4, r4, 0x4
-/* 8036C9E8 92C40000 */ stw r22, 0(r4)
-/* 8036C9EC 38840004 */ addi r4, r4, 0x4
-/* 8036C9F0 92C40000 */ stw r22, 0(r4)
-/* 8036C9F4 38840004 */ addi r4, r4, 0x4
-/* 8036C9F8 4200FFC0 */ bdnz lbl_8036c9b8
-/* 8036C9FC 70630007 */ andi. r3, r3, 7
-/* 8036CA00 41820018 */ beq- lbl_8036ca18
-lbl_8036ca04:
-/* 8036CA04 7C6903A6 */ mtctr r3
-/* 8036CA08 48000004 */ b lbl_8036ca0c
-lbl_8036ca0c:
-/* 8036CA0C 92C40000 */ stw r22, 0(r4)
-/* 8036CA10 38840004 */ addi r4, r4, 0x4
-/* 8036CA14 4200FFF8 */ bdnz lbl_8036ca0c
-lbl_8036ca18:
-/* 8036CA18 807C0000 */ lwz r3, 0(r28)
-/* 8036CA1C 7F04C378 */ mr r4, r24
-/* 8036CA20 7EE5BB78 */ mr r5, r23
-/* 8036CA24 3E838000 */ addis r20, r3, 0x8000
-/* 8036CA28 7E83A378 */ mr r3, r20
-/* 8036CA2C 4BCA19F1 */ bl func_8000e41c
-/* 8036CA30 7E83A378 */ mr r3, r20
-/* 8036CA34 7EE4BB78 */ mr r4, r23
-/* 8036CA38 48000F41 */ bl func_8036d978
-/* 8036CA3C 7C0004AC */ sync 0
-/* 8036CA40 7E83A378 */ mr r3, r20
-/* 8036CA44 7EE4BB78 */ mr r4, r23
-/* 8036CA48 48000F91 */ bl func_8036d9d8
-lbl_8036ca4c:
-/* 8036CA4C 3B9C0004 */ addi r28, r28, 0x4
-/* 8036CA50 3B5A0001 */ addi r26, r26, 0x1
-lbl_8036ca54:
-/* 8036CA54 5740063E */ clrlwi r0, r26, 0x18
-/* 8036CA58 2800000F */ cmplwi r0, 0xf
-/* 8036CA5C 4180FEB4 */ blt+ lbl_8036c910
-/* 8036CA60 3C608000 */ lis r3, 0x8000
-/* 8036CA64 38033000 */ addi r0, r3, 0x3000
-/* 8036CA68 900DCA0C */ stw r0, lbl_805c682c@sda21(0)
-/* 8036CA6C 3A800000 */ li r20, 0x0
-/* 8036CA70 48000004 */ b lbl_8036ca74
-lbl_8036ca74:
-/* 8036CA74 3C608037 */ lis r3, func_8036cbb8@ha
-/* 8036CA78 3AE3CBB8 */ addi r23, r3, func_8036cbb8@l
-/* 8036CA7C 48000004 */ b lbl_8036ca80
-lbl_8036ca80:
-/* 8036CA80 48000014 */ b lbl_8036ca94
-lbl_8036ca84:
-/* 8036CA84 7E83A378 */ mr r3, r20
-/* 8036CA88 7EE4BB78 */ mr r4, r23
-/* 8036CA8C 48000061 */ bl func_8036caec
-/* 8036CA90 3A940001 */ addi r20, r20, 0x1
-lbl_8036ca94:
-/* 8036CA94 5680063E */ clrlwi r0, r20, 0x18
-/* 8036CA98 2800000F */ cmplwi r0, 0xf
-/* 8036CA9C 4180FFE8 */ blt+ lbl_8036ca84
-/* 8036CAA0 933E0000 */ stw r25, 0(r30)
-/* 8036CAA4 387D01A0 */ addi r3, r29, 0x1a0
-/* 8036CAA8 4CC63182 */ crclr 6
-/* 8036CAAC 4BFFF805 */ bl func_8036c2b0
-/* 8036CAB0 BA810008 */ lmw r20, 8(r1)
-/* 8036CAB4 8001003C */ lwz r0, 0x3c(r1)
-/* 8036CAB8 38210038 */ addi r1, r1, 0x38
-/* 8036CABC 7C0803A6 */ mtlr r0
-/* 8036CAC0 4E800020 */ blr
-.size func_8036c844, . - func_8036c844
-
-
-.global func_8036cac4
-.type func_8036cac4, @function
-func_8036cac4:
-/* 8036CAC4 38A00040 */ li r5, 0x40
-/* 8036CAC8 7C6802A6 */ mflr r3
-/* 8036CACC 9065000C */ stw r3, 0xc(r5)
-/* 8036CAD0 80650008 */ lwz r3, 8(r5)
-/* 8036CAD4 64638000 */ oris r3, r3, 0x8000
-/* 8036CAD8 7C6803A6 */ mtlr r3
-/* 8036CADC 38600030 */ li r3, 0x30
-/* 8036CAE0 7C600124 */ mtmsr r3
-/* 8036CAE4 4E800020 */ blr
-.size func_8036cac4, . - func_8036cac4
-
-
-.global func_8036cae8
-.type func_8036cae8, @function
-func_8036cae8:
-/* 8036CAE8 48000063 */ bla 0x60
-.size func_8036cae8, . - func_8036cae8
-
-
-.global func_8036caec
-.type func_8036caec, @function
-func_8036caec:
-/* 8036CAEC 5460063E */ clrlwi r0, r3, 0x18
-/* 8036CAF0 806DCA0C */ lwz r3, lbl_805c682c@sda21(0)
-/* 8036CAF4 5400103A */ slwi r0, r0, 2
-/* 8036CAF8 7CA30214 */ add r5, r3, r0
-/* 8036CAFC 80650000 */ lwz r3, 0(r5)
-/* 8036CB00 90850000 */ stw r4, 0(r5)
-/* 8036CB04 4E800020 */ blr
-.size func_8036caec, . - func_8036caec
-
-
-.global func_8036cb08
-.type func_8036cb08, @function
-func_8036cb08:
-/* 8036CB08 5460063E */ clrlwi r0, r3, 0x18
-/* 8036CB0C 806DCA0C */ lwz r3, lbl_805c682c@sda21(0)
-/* 8036CB10 5400103A */ slwi r0, r0, 2
-/* 8036CB14 7C63002E */ lwzx r3, r3, r0
-/* 8036CB18 4E800020 */ blr
-.size func_8036cb08, . - func_8036cb08
-
-
-.global func_8036cb1c
-.type func_8036cb1c, @function
-func_8036cb1c:
-/* 8036CB1C 7C9043A6 */ mtspr 0x110, r4
-/* 8036CB20 808000C0 */ lwz r4, 0xc0(0)
-/* 8036CB24 9064000C */ stw r3, 0xc(r4)
-/* 8036CB28 7C7042A6 */ mfspr r3, 0x110
-/* 8036CB2C 90640010 */ stw r3, 0x10(r4)
-/* 8036CB30 90A40014 */ stw r5, 0x14(r4)
-/* 8036CB34 A06401A2 */ lhz r3, 0x1a2(r4)
-/* 8036CB38 60630002 */ ori r3, r3, 2
-/* 8036CB3C B06401A2 */ sth r3, 0x1a2(r4)
-/* 8036CB40 7C600026 */ mfcr r3
-/* 8036CB44 90640080 */ stw r3, 0x80(r4)
-/* 8036CB48 7C6802A6 */ mflr r3
-/* 8036CB4C 90640084 */ stw r3, 0x84(r4)
-/* 8036CB50 7C6902A6 */ mfctr r3
-/* 8036CB54 90640088 */ stw r3, 0x88(r4)
-/* 8036CB58 7C6102A6 */ mfxer r3
-/* 8036CB5C 9064008C */ stw r3, 0x8c(r4)
-/* 8036CB60 7C7A02A6 */ mfspr r3, 0x1a
-/* 8036CB64 90640198 */ stw r3, 0x198(r4)
-/* 8036CB68 7C7B02A6 */ mfspr r3, 0x1b
-/* 8036CB6C 9064019C */ stw r3, 0x19c(r4)
-/* 8036CB70 7C651B78 */ mr r5, r3
-.size func_8036cb1c, . - func_8036cb1c
-
-
-.global func_8036cb74
-.type func_8036cb74, @function
-func_8036cb74:
-/* 8036CB74 60000000 */ nop
-/* 8036CB78 7C6000A6 */ mfmsr r3
-/* 8036CB7C 60630030 */ ori r3, r3, 0x30
-/* 8036CB80 7C7B03A6 */ mtspr 0x1b, r3
-.size func_8036cb74, . - func_8036cb74
-
-
-.global func_8036cb84
-.type func_8036cb84, @function
-func_8036cb84:
-/* 8036CB84 38600000 */ li r3, 0x0
-/* 8036CB88 808000D4 */ lwz r4, 0xd4(0)
-/* 8036CB8C 54A507BD */ rlwinm. r5, r5, 0, 0x1e, 0x1e
-/* 8036CB90 40820014 */ bne- lbl_8036cba4
-/* 8036CB94 3CA08037 */ lis r5, func_8036cbb8@ha
-/* 8036CB98 38A5CBB8 */ addi r5, r5, func_8036cbb8@l
-/* 8036CB9C 7CBA03A6 */ mtspr 0x1a, r5
-/* 8036CBA0 4C000064 */ rfi
-lbl_8036cba4:
-/* 8036CBA4 546515BA */ rlwinm r5, r3, 2, 0x16, 0x1d
-/* 8036CBA8 80A53000 */ lwz r5, 0x3000(r5)
-/* 8036CBAC 7CBA03A6 */ mtspr 0x1a, r5
-/* 8036CBB0 4C000064 */ rfi
-.size func_8036cb84, . - func_8036cb84
-
-
-.global func_8036cbb4
-.type func_8036cbb4, @function
-func_8036cbb4:
-/* 8036CBB4 60000000 */ nop
-.size func_8036cbb4, . - func_8036cbb4
-
-
-.global func_8036cbb8
-.type func_8036cbb8, @function
-func_8036cbb8:
-/* 8036CBB8 90040000 */ stw r0, 0(r4)
-/* 8036CBBC 90240004 */ stw r1, 4(r4)
-/* 8036CBC0 90440008 */ stw r2, 8(r4)
-/* 8036CBC4 BCC40018 */ stmw r6, 0x18(r4)
-/* 8036CBC8 7C11E2A6 */ mfspr r0, 0x391
-/* 8036CBCC 900401A8 */ stw r0, 0x1a8(r4)
-/* 8036CBD0 7C12E2A6 */ mfspr r0, 0x392
-/* 8036CBD4 900401AC */ stw r0, 0x1ac(r4)
-/* 8036CBD8 7C13E2A6 */ mfspr r0, 0x393
-/* 8036CBDC 900401B0 */ stw r0, 0x1b0(r4)
-/* 8036CBE0 7C14E2A6 */ mfspr r0, 0x394
-/* 8036CBE4 900401B4 */ stw r0, 0x1b4(r4)
-/* 8036CBE8 7C15E2A6 */ mfspr r0, 0x395
-/* 8036CBEC 900401B8 */ stw r0, 0x1b8(r4)
-/* 8036CBF0 7C16E2A6 */ mfspr r0, 0x396
-/* 8036CBF4 900401BC */ stw r0, 0x1bc(r4)
-/* 8036CBF8 7C17E2A6 */ mfspr r0, 0x397
-/* 8036CBFC 900401C0 */ stw r0, 0x1c0(r4)
-/* 8036CC00 7CB202A6 */ mfdsisr r5
-/* 8036CC04 7CD302A6 */ mfdar r6
-/* 8036CC08 9421FFF8 */ stwu r1, -8(r1)
-/* 8036CC0C 48001C70 */ b func_8036e87c
-.size func_8036cbb8, . - func_8036cbb8
-
-
-.global func_8036cc10
-.type func_8036cc10, @function
-func_8036cc10:
-/* 8036CC10 7C0802A6 */ mflr r0
-/* 8036CC14 90010004 */ stw r0, 4(r1)
-/* 8036CC18 9421FFF8 */ stwu r1, -8(r1)
-/* 8036CC1C 4BFFF5B1 */ bl func_8036c1cc
-/* 8036CC20 6463A000 */ oris r3, r3, 0xa000
-/* 8036CC24 4BFFF5B1 */ bl func_8036c1d4
-/* 8036CC28 48000DE9 */ bl func_8036da10
-/* 8036CC2C 7C0004AC */ sync 0
-/* 8036CC30 38600000 */ li r3, 0x0
-/* 8036CC34 7C70E3A6 */ mtspr 0x390, r3
-/* 8036CC38 8001000C */ lwz r0, 0xc(r1)
-/* 8036CC3C 38210008 */ addi r1, r1, 0x8
-/* 8036CC40 7C0803A6 */ mtlr r0
-/* 8036CC44 4E800020 */ blr
-.size func_8036cc10, . - func_8036cc10
-
-
-.global func_8036cc48
-.type func_8036cc48, @function
-func_8036cc48:
-/* 8036CC48 3C60CC00 */ lis r3, 0xcc00
-/* 8036CC4C 38636000 */ addi r3, r3, 0x6000
-/* 8036CC50 80030024 */ lwz r0, 0x24(r3)
-/* 8036CC54 5403063E */ clrlwi r3, r0, 0x18
-/* 8036CC58 4E800020 */ blr
-.size func_8036cc48, . - func_8036cc48
-
diff --git a/asm/Dolphin/os/OSAlarm.s b/asm/Dolphin/os/OSAlarm.s
deleted file mode 100644
index 7d9dcff..0000000
--- a/asm/Dolphin/os/OSAlarm.s
+++ /dev/null
@@ -1,503 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036cc5c
-.type func_8036cc5c, @function
-func_8036cc5c:
-/* 8036CC5C 7C0802A6 */ mflr r0
-/* 8036CC60 38600008 */ li r3, 0x8
-/* 8036CC64 90010004 */ stw r0, 4(r1)
-/* 8036CC68 9421FFF8 */ stwu r1, -8(r1)
-/* 8036CC6C 4BFFFE9D */ bl func_8036cb08
-/* 8036CC70 3C808037 */ lis r4, func_8036d2b8@ha
-/* 8036CC74 3884D2B8 */ addi r4, r4, func_8036d2b8@l
-/* 8036CC78 7C032040 */ cmplw r3, r4
-/* 8036CC7C 4182001C */ beq- lbl_8036cc98
-/* 8036CC80 38000000 */ li r0, 0x0
-/* 8036CC84 386DCA28 */ addi r3, 0, lbl_805c6848@sda21
-/* 8036CC88 90030004 */ stw r0, 4(r3)
-/* 8036CC8C 38600008 */ li r3, 0x8
-/* 8036CC90 900DCA28 */ stw r0, lbl_805c6848@sda21(0)
-/* 8036CC94 4BFFFE59 */ bl func_8036caec
-lbl_8036cc98:
-/* 8036CC98 8001000C */ lwz r0, 0xc(r1)
-/* 8036CC9C 38210008 */ addi r1, r1, 0x8
-/* 8036CCA0 7C0803A6 */ mtlr r0
-/* 8036CCA4 4E800020 */ blr
-.size func_8036cc5c, . - func_8036cc5c
-
-
-.global func_8036cca8
-.type func_8036cca8, @function
-func_8036cca8:
-/* 8036CCA8 38000000 */ li r0, 0x0
-/* 8036CCAC 90030000 */ stw r0, 0(r3)
-/* 8036CCB0 4E800020 */ blr
-.size func_8036cca8, . - func_8036cca8
-
-
-.global func_8036ccb4
-.type func_8036ccb4, @function
-func_8036ccb4:
-/* 8036CCB4 7C0802A6 */ mflr r0
-/* 8036CCB8 90010004 */ stw r0, 4(r1)
-/* 8036CCBC 9421FFC0 */ stwu r1, -0x40(r1)
-/* 8036CCC0 BF210024 */ stmw r25, 0x24(r1)
-/* 8036CCC4 3B800000 */ li r28, 0x0
-/* 8036CCC8 7C7D1B78 */ mr r29, r3
-/* 8036CCCC 6F848000 */ xoris r4, r28, 0x8000
-/* 8036CCD0 3B250000 */ addi r25, r5, 0x0
-/* 8036CCD4 3BC60000 */ addi r30, r6, 0x0
-/* 8036CCD8 3BE70000 */ addi r31, r7, 0x0
-/* 8036CCDC 80030018 */ lwz r0, 0x18(r3)
-/* 8036CCE0 8103001C */ lwz r8, 0x1c(r3)
-/* 8036CCE4 6C038000 */ xoris r3, r0, 0x8000
-/* 8036CCE8 7C08E010 */ subfc r0, r8, r28
-/* 8036CCEC 7C632110 */ subfe r3, r3, r4
-/* 8036CCF0 7C642110 */ subfe r3, r4, r4
-/* 8036CCF4 7C6300D1 */ neg. r3, r3
-/* 8036CCF8 4182007C */ beq- lbl_8036cd74
-/* 8036CCFC 48005AE9 */ bl func_803727e4
-/* 8036CD00 80FD0020 */ lwz r7, 0x20(r29)
-/* 8036CD04 6C658000 */ xoris r5, r3, 0x8000
-/* 8036CD08 811D0024 */ lwz r8, 0x24(r29)
-/* 8036CD0C 6CE68000 */ xoris r6, r7, 0x8000
-/* 8036CD10 7C044010 */ subfc r0, r4, r8
-/* 8036CD14 7CA53110 */ subfe r5, r5, r6
-/* 8036CD18 7CA63110 */ subfe r5, r6, r6
-/* 8036CD1C 7CA500D1 */ neg. r5, r5
-/* 8036CD20 3BC80000 */ addi r30, r8, 0x0
-/* 8036CD24 3B270000 */ addi r25, r7, 0x0
-/* 8036CD28 4182004C */ beq- lbl_8036cd74
-/* 8036CD2C 837D0018 */ lwz r27, 0x18(r29)
-/* 8036CD30 7C882010 */ subfc r4, r8, r4
-/* 8036CD34 835D001C */ lwz r26, 0x1c(r29)
-/* 8036CD38 7C671910 */ subfe r3, r7, r3
-/* 8036CD3C 38BB0000 */ addi r5, r27, 0x0
-/* 8036CD40 38DA0000 */ addi r6, r26, 0x0
-/* 8036CD44 4802686D */ bl func_803935b0
-/* 8036CD48 38000001 */ li r0, 0x1
-/* 8036CD4C 7CA40014 */ addc r5, r4, r0
-/* 8036CD50 7C9B29D6 */ mullw r4, r27, r5
-/* 8036CD54 7C1A2816 */ mulhwu r0, r26, r5
-/* 8036CD58 7C63E114 */ adde r3, r3, r28
-/* 8036CD5C 7C840214 */ add r4, r4, r0
-/* 8036CD60 7C1A19D6 */ mullw r0, r26, r3
-/* 8036CD64 7C7A29D6 */ mullw r3, r26, r5
-/* 8036CD68 7C040214 */ add r0, r4, r0
-/* 8036CD6C 7FDE1814 */ addc r30, r30, r3
-/* 8036CD70 7F390114 */ adde r25, r25, r0
-lbl_8036cd74:
-/* 8036CD74 93FD0000 */ stw r31, 0(r29)
-/* 8036CD78 6F248000 */ xoris r4, r25, 0x8000
-/* 8036CD7C 93DD000C */ stw r30, 0xc(r29)
-/* 8036CD80 933D0008 */ stw r25, 8(r29)
-/* 8036CD84 80CDCA28 */ lwz r6, lbl_805c6848@sda21(0)
-/* 8036CD88 480000C4 */ b lbl_8036ce4c
-lbl_8036cd8c:
-/* 8036CD8C 80060008 */ lwz r0, 8(r6)
-/* 8036CD90 80A6000C */ lwz r5, 0xc(r6)
-/* 8036CD94 6C038000 */ xoris r3, r0, 0x8000
-/* 8036CD98 7C05F010 */ subfc r0, r5, r30
-/* 8036CD9C 7C632110 */ subfe r3, r3, r4
-/* 8036CDA0 7C642110 */ subfe r3, r4, r4
-/* 8036CDA4 7C6300D1 */ neg. r3, r3
-/* 8036CDA8 418200A0 */ beq- lbl_8036ce48
-/* 8036CDAC 80060010 */ lwz r0, 0x10(r6)
-/* 8036CDB0 901D0010 */ stw r0, 0x10(r29)
-/* 8036CDB4 93A60010 */ stw r29, 0x10(r6)
-/* 8036CDB8 90DD0014 */ stw r6, 0x14(r29)
-/* 8036CDBC 807D0010 */ lwz r3, 0x10(r29)
-/* 8036CDC0 28030000 */ cmplwi r3, 0
-/* 8036CDC4 4182000C */ beq- lbl_8036cdd0
-/* 8036CDC8 93A30014 */ stw r29, 0x14(r3)
-/* 8036CDCC 48000124 */ b lbl_8036cef0
-lbl_8036cdd0:
-/* 8036CDD0 93ADCA28 */ stw r29, lbl_805c6848@sda21(0)
-/* 8036CDD4 48005A11 */ bl func_803727e4
-/* 8036CDD8 80DD000C */ lwz r6, 0xc(r29)
-/* 8036CDDC 38E00000 */ li r7, 0x0
-/* 8036CDE0 801D0008 */ lwz r0, 8(r29)
-/* 8036CDE4 6CE58000 */ xoris r5, r7, 0x8000
-/* 8036CDE8 7D043010 */ subfc r8, r4, r6
-/* 8036CDEC 7C030110 */ subfe r0, r3, r0
-/* 8036CDF0 6C068000 */ xoris r6, r0, 0x8000
-/* 8036CDF4 7C074010 */ subfc r0, r7, r8
-/* 8036CDF8 7CA53110 */ subfe r5, r5, r6
-/* 8036CDFC 7CA63110 */ subfe r5, r6, r6
-/* 8036CE00 7CA500D1 */ neg. r5, r5
-/* 8036CE04 41820010 */ beq- lbl_8036ce14
-/* 8036CE08 38600000 */ li r3, 0x0
-/* 8036CE0C 4BFFF39D */ bl func_8036c1a8
-/* 8036CE10 480000E0 */ b lbl_8036cef0
-lbl_8036ce14:
-/* 8036CE14 3C808000 */ lis r4, 0x8000
-/* 8036CE18 6CE38000 */ xoris r3, r7, 0x8000
-/* 8036CE1C 7C044010 */ subfc r0, r4, r8
-/* 8036CE20 7C633110 */ subfe r3, r3, r6
-/* 8036CE24 7C663110 */ subfe r3, r6, r6
-/* 8036CE28 7C6300D1 */ neg. r3, r3
-/* 8036CE2C 41820010 */ beq- lbl_8036ce3c
-/* 8036CE30 7D034378 */ mr r3, r8
-/* 8036CE34 4BFFF375 */ bl func_8036c1a8
-/* 8036CE38 480000B8 */ b lbl_8036cef0
-lbl_8036ce3c:
-/* 8036CE3C 3864FFFF */ addi r3, r4, -0x1
-/* 8036CE40 4BFFF369 */ bl func_8036c1a8
-/* 8036CE44 480000AC */ b lbl_8036cef0
-lbl_8036ce48:
-/* 8036CE48 80C60014 */ lwz r6, 0x14(r6)
-lbl_8036ce4c:
-/* 8036CE4C 28060000 */ cmplwi r6, 0
-/* 8036CE50 4082FF3C */ bne+ lbl_8036cd8c
-/* 8036CE54 3BC00000 */ li r30, 0x0
-/* 8036CE58 93DD0014 */ stw r30, 0x14(r29)
-/* 8036CE5C 386DCA28 */ addi r3, 0, lbl_805c6848@sda21
-/* 8036CE60 80830004 */ lwz r4, 4(r3)
-/* 8036CE64 97A30004 */ stwu r29, 4(r3)
-/* 8036CE68 28040000 */ cmplwi r4, 0
-/* 8036CE6C 909D0010 */ stw r4, 0x10(r29)
-/* 8036CE70 4182000C */ beq- lbl_8036ce7c
-/* 8036CE74 93A40014 */ stw r29, 0x14(r4)
-/* 8036CE78 48000078 */ b lbl_8036cef0
-lbl_8036ce7c:
-/* 8036CE7C 93A30000 */ stw r29, 0(r3)
-/* 8036CE80 93ADCA28 */ stw r29, lbl_805c6848@sda21(0)
-/* 8036CE84 48005961 */ bl func_803727e4
-/* 8036CE88 80DD000C */ lwz r6, 0xc(r29)
-/* 8036CE8C 6FC58000 */ xoris r5, r30, 0x8000
-/* 8036CE90 801D0008 */ lwz r0, 8(r29)
-/* 8036CE94 7CE43010 */ subfc r7, r4, r6
-/* 8036CE98 7C030110 */ subfe r0, r3, r0
-/* 8036CE9C 6C068000 */ xoris r6, r0, 0x8000
-/* 8036CEA0 7C1E3810 */ subfc r0, r30, r7
-/* 8036CEA4 7CA53110 */ subfe r5, r5, r6
-/* 8036CEA8 7CA63110 */ subfe r5, r6, r6
-/* 8036CEAC 7CA500D1 */ neg. r5, r5
-/* 8036CEB0 41820010 */ beq- lbl_8036cec0
-/* 8036CEB4 38600000 */ li r3, 0x0
-/* 8036CEB8 4BFFF2F1 */ bl func_8036c1a8
-/* 8036CEBC 48000034 */ b lbl_8036cef0
-lbl_8036cec0:
-/* 8036CEC0 3C808000 */ lis r4, 0x8000
-/* 8036CEC4 6FC38000 */ xoris r3, r30, 0x8000
-/* 8036CEC8 7C043810 */ subfc r0, r4, r7
-/* 8036CECC 7C633110 */ subfe r3, r3, r6
-/* 8036CED0 7C663110 */ subfe r3, r6, r6
-/* 8036CED4 7C6300D1 */ neg. r3, r3
-/* 8036CED8 41820010 */ beq- lbl_8036cee8
-/* 8036CEDC 7CE33B78 */ mr r3, r7
-/* 8036CEE0 4BFFF2C9 */ bl func_8036c1a8
-/* 8036CEE4 4800000C */ b lbl_8036cef0
-lbl_8036cee8:
-/* 8036CEE8 3864FFFF */ addi r3, r4, -0x1
-/* 8036CEEC 4BFFF2BD */ bl func_8036c1a8
-lbl_8036cef0:
-/* 8036CEF0 BB210024 */ lmw r25, 0x24(r1)
-/* 8036CEF4 80010044 */ lwz r0, 0x44(r1)
-/* 8036CEF8 38210040 */ addi r1, r1, 0x40
-/* 8036CEFC 7C0803A6 */ mtlr r0
-/* 8036CF00 4E800020 */ blr
-.size func_8036ccb4, . - func_8036ccb4
-
-
-.global func_8036cf04
-.type func_8036cf04, @function
-func_8036cf04:
-/* 8036CF04 7C0802A6 */ mflr r0
-/* 8036CF08 90010004 */ stw r0, 4(r1)
-/* 8036CF0C 9421FFC8 */ stwu r1, -0x38(r1)
-/* 8036CF10 BF610024 */ stmw r27, 0x24(r1)
-/* 8036CF14 3B630000 */ addi r27, r3, 0x0
-/* 8036CF18 3BA50000 */ addi r29, r5, 0x0
-/* 8036CF1C 3B860000 */ addi r28, r6, 0x0
-/* 8036CF20 3BC70000 */ addi r30, r7, 0x0
-/* 8036CF24 48001BB1 */ bl func_8036ead4
-/* 8036CF28 38000000 */ li r0, 0x0
-/* 8036CF2C 901B001C */ stw r0, 0x1c(r27)
-/* 8036CF30 7C7F1B78 */ mr r31, r3
-/* 8036CF34 901B0018 */ stw r0, 0x18(r27)
-/* 8036CF38 480058AD */ bl func_803727e4
-/* 8036CF3C 7CDC2014 */ addc r6, r28, r4
-/* 8036CF40 7CBD1914 */ adde r5, r29, r3
-/* 8036CF44 387B0000 */ addi r3, r27, 0x0
-/* 8036CF48 38FE0000 */ addi r7, r30, 0x0
-/* 8036CF4C 4BFFFD69 */ bl func_8036ccb4
-/* 8036CF50 7FE3FB78 */ mr r3, r31
-/* 8036CF54 48001BA9 */ bl func_8036eafc
-/* 8036CF58 BB610024 */ lmw r27, 0x24(r1)
-/* 8036CF5C 8001003C */ lwz r0, 0x3c(r1)
-/* 8036CF60 38210038 */ addi r1, r1, 0x38
-/* 8036CF64 7C0803A6 */ mtlr r0
-/* 8036CF68 4E800020 */ blr
-.size func_8036cf04, . - func_8036cf04
-
-
-.global func_8036cf6c
-.type func_8036cf6c, @function
-func_8036cf6c:
-/* 8036CF6C 7C0802A6 */ mflr r0
-/* 8036CF70 90010004 */ stw r0, 4(r1)
-/* 8036CF74 9421FFE0 */ stwu r1, -0x20(r1)
-/* 8036CF78 93E1001C */ stw r31, 0x1c(r1)
-/* 8036CF7C 93C10018 */ stw r30, 0x18(r1)
-/* 8036CF80 7C7E1B78 */ mr r30, r3
-/* 8036CF84 93A10014 */ stw r29, 0x14(r1)
-/* 8036CF88 48001B4D */ bl func_8036ead4
-/* 8036CF8C 801E0000 */ lwz r0, 0(r30)
-/* 8036CF90 3BE30000 */ addi r31, r3, 0x0
-/* 8036CF94 28000000 */ cmplwi r0, 0
-/* 8036CF98 40820010 */ bne- lbl_8036cfa8
-/* 8036CF9C 7FE3FB78 */ mr r3, r31
-/* 8036CFA0 48001B5D */ bl func_8036eafc
-/* 8036CFA4 480000C8 */ b lbl_8036d06c
-lbl_8036cfa8:
-/* 8036CFA8 83BE0014 */ lwz r29, 0x14(r30)
-/* 8036CFAC 281D0000 */ cmplwi r29, 0
-/* 8036CFB0 40820014 */ bne- lbl_8036cfc4
-/* 8036CFB4 801E0010 */ lwz r0, 0x10(r30)
-/* 8036CFB8 386DCA28 */ addi r3, 0, lbl_805c6848@sda21
-/* 8036CFBC 90030004 */ stw r0, 4(r3)
-/* 8036CFC0 4800000C */ b lbl_8036cfcc
-lbl_8036cfc4:
-/* 8036CFC4 801E0010 */ lwz r0, 0x10(r30)
-/* 8036CFC8 901D0010 */ stw r0, 0x10(r29)
-lbl_8036cfcc:
-/* 8036CFCC 807E0010 */ lwz r3, 0x10(r30)
-/* 8036CFD0 28030000 */ cmplwi r3, 0
-/* 8036CFD4 4182000C */ beq- lbl_8036cfe0
-/* 8036CFD8 93A30014 */ stw r29, 0x14(r3)
-/* 8036CFDC 48000080 */ b lbl_8036d05c
-lbl_8036cfe0:
-/* 8036CFE0 281D0000 */ cmplwi r29, 0
-/* 8036CFE4 93ADCA28 */ stw r29, lbl_805c6848@sda21(0)
-/* 8036CFE8 41820074 */ beq- lbl_8036d05c
-/* 8036CFEC 480057F9 */ bl func_803727e4
-/* 8036CFF0 80DD000C */ lwz r6, 0xc(r29)
-/* 8036CFF4 38E00000 */ li r7, 0x0
-/* 8036CFF8 801D0008 */ lwz r0, 8(r29)
-/* 8036CFFC 6CE58000 */ xoris r5, r7, 0x8000
-/* 8036D000 7D043010 */ subfc r8, r4, r6
-/* 8036D004 7C030110 */ subfe r0, r3, r0
-/* 8036D008 6C068000 */ xoris r6, r0, 0x8000
-/* 8036D00C 7C074010 */ subfc r0, r7, r8
-/* 8036D010 7CA53110 */ subfe r5, r5, r6
-/* 8036D014 7CA63110 */ subfe r5, r6, r6
-/* 8036D018 7CA500D1 */ neg. r5, r5
-/* 8036D01C 41820010 */ beq- lbl_8036d02c
-/* 8036D020 38600000 */ li r3, 0x0
-/* 8036D024 4BFFF185 */ bl func_8036c1a8
-/* 8036D028 48000034 */ b lbl_8036d05c
-lbl_8036d02c:
-/* 8036D02C 3C808000 */ lis r4, 0x8000
-/* 8036D030 6CE38000 */ xoris r3, r7, 0x8000
-/* 8036D034 7C044010 */ subfc r0, r4, r8
-/* 8036D038 7C633110 */ subfe r3, r3, r6
-/* 8036D03C 7C663110 */ subfe r3, r6, r6
-/* 8036D040 7C6300D1 */ neg. r3, r3
-/* 8036D044 41820010 */ beq- lbl_8036d054
-/* 8036D048 7D034378 */ mr r3, r8
-/* 8036D04C 4BFFF15D */ bl func_8036c1a8
-/* 8036D050 4800000C */ b lbl_8036d05c
-lbl_8036d054:
-/* 8036D054 3864FFFF */ addi r3, r4, -0x1
-/* 8036D058 4BFFF151 */ bl func_8036c1a8
-lbl_8036d05c:
-/* 8036D05C 38000000 */ li r0, 0x0
-/* 8036D060 901E0000 */ stw r0, 0(r30)
-/* 8036D064 7FE3FB78 */ mr r3, r31
-/* 8036D068 48001A95 */ bl func_8036eafc
-lbl_8036d06c:
-/* 8036D06C 80010024 */ lwz r0, 0x24(r1)
-/* 8036D070 83E1001C */ lwz r31, 0x1c(r1)
-/* 8036D074 83C10018 */ lwz r30, 0x18(r1)
-/* 8036D078 83A10014 */ lwz r29, 0x14(r1)
-/* 8036D07C 38210020 */ addi r1, r1, 0x20
-/* 8036D080 7C0803A6 */ mtlr r0
-/* 8036D084 4E800020 */ blr
-.size func_8036cf6c, . - func_8036cf6c
-
-
-.global func_8036d088
-.type func_8036d088, @function
-func_8036d088:
-/* 8036D088 7C0802A6 */ mflr r0
-/* 8036D08C 90010004 */ stw r0, 4(r1)
-/* 8036D090 9421FD10 */ stwu r1, -0x2f0(r1)
-/* 8036D094 93E102EC */ stw r31, 0x2ec(r1)
-/* 8036D098 93C102E8 */ stw r30, 0x2e8(r1)
-/* 8036D09C 93A102E4 */ stw r29, 0x2e4(r1)
-/* 8036D0A0 7C9D2378 */ mr r29, r4
-/* 8036D0A4 938102E0 */ stw r28, 0x2e0(r1)
-/* 8036D0A8 4800573D */ bl func_803727e4
-/* 8036D0AC 800DCA28 */ lwz r0, lbl_805c6848@sda21(0)
-/* 8036D0B0 3B840000 */ addi r28, r4, 0x0
-/* 8036D0B4 3BC30000 */ addi r30, r3, 0x0
-/* 8036D0B8 28000000 */ cmplwi r0, 0
-/* 8036D0BC 7C1F0378 */ mr r31, r0
-/* 8036D0C0 4082000C */ bne- lbl_8036d0cc
-/* 8036D0C4 7FA3EB78 */ mr r3, r29
-/* 8036D0C8 480010B9 */ bl func_8036e180
-lbl_8036d0cc:
-/* 8036D0CC 801F0008 */ lwz r0, 8(r31)
-/* 8036D0D0 6FC48000 */ xoris r4, r30, 0x8000
-/* 8036D0D4 80BF000C */ lwz r5, 0xc(r31)
-/* 8036D0D8 6C038000 */ xoris r3, r0, 0x8000
-/* 8036D0DC 7C05E010 */ subfc r0, r5, r28
-/* 8036D0E0 7C632110 */ subfe r3, r3, r4
-/* 8036D0E4 7C642110 */ subfe r3, r4, r4
-/* 8036D0E8 7C6300D1 */ neg. r3, r3
-/* 8036D0EC 4182007C */ beq- lbl_8036d168
-/* 8036D0F0 480056F5 */ bl func_803727e4
-/* 8036D0F4 80DF000C */ lwz r6, 0xc(r31)
-/* 8036D0F8 38E00000 */ li r7, 0x0
-/* 8036D0FC 801F0008 */ lwz r0, 8(r31)
-/* 8036D100 6CE58000 */ xoris r5, r7, 0x8000
-/* 8036D104 7D043010 */ subfc r8, r4, r6
-/* 8036D108 7C030110 */ subfe r0, r3, r0
-/* 8036D10C 6C068000 */ xoris r6, r0, 0x8000
-/* 8036D110 7C074010 */ subfc r0, r7, r8
-/* 8036D114 7CA53110 */ subfe r5, r5, r6
-/* 8036D118 7CA63110 */ subfe r5, r6, r6
-/* 8036D11C 7CA500D1 */ neg. r5, r5
-/* 8036D120 41820010 */ beq- lbl_8036d130
-/* 8036D124 38600000 */ li r3, 0x0
-/* 8036D128 4BFFF081 */ bl func_8036c1a8
-/* 8036D12C 48000034 */ b lbl_8036d160
-lbl_8036d130:
-/* 8036D130 3C808000 */ lis r4, 0x8000
-/* 8036D134 6CE38000 */ xoris r3, r7, 0x8000
-/* 8036D138 7C044010 */ subfc r0, r4, r8
-/* 8036D13C 7C633110 */ subfe r3, r3, r6
-/* 8036D140 7C663110 */ subfe r3, r6, r6
-/* 8036D144 7C6300D1 */ neg. r3, r3
-/* 8036D148 41820010 */ beq- lbl_8036d158
-/* 8036D14C 7D034378 */ mr r3, r8
-/* 8036D150 4BFFF059 */ bl func_8036c1a8
-/* 8036D154 4800000C */ b lbl_8036d160
-lbl_8036d158:
-/* 8036D158 3864FFFF */ addi r3, r4, -0x1
-/* 8036D15C 4BFFF04D */ bl func_8036c1a8
-lbl_8036d160:
-/* 8036D160 7FA3EB78 */ mr r3, r29
-/* 8036D164 4800101D */ bl func_8036e180
-lbl_8036d168:
-/* 8036D168 807F0014 */ lwz r3, 0x14(r31)
-/* 8036D16C 28030000 */ cmplwi r3, 0
-/* 8036D170 906DCA28 */ stw r3, lbl_805c6848@sda21(0)
-/* 8036D174 40820014 */ bne- lbl_8036d188
-/* 8036D178 38000000 */ li r0, 0x0
-/* 8036D17C 386DCA28 */ addi r3, 0, lbl_805c6848@sda21
-/* 8036D180 90030004 */ stw r0, 4(r3)
-/* 8036D184 4800000C */ b lbl_8036d190
-lbl_8036d188:
-/* 8036D188 38000000 */ li r0, 0x0
-/* 8036D18C 90030010 */ stw r0, 0x10(r3)
-lbl_8036d190:
-/* 8036D190 83DF0000 */ lwz r30, 0(r31)
-/* 8036D194 38C00000 */ li r6, 0x0
-/* 8036D198 6CC48000 */ xoris r4, r6, 0x8000
-/* 8036D19C 90DF0000 */ stw r6, 0(r31)
-/* 8036D1A0 801F0018 */ lwz r0, 0x18(r31)
-/* 8036D1A4 80BF001C */ lwz r5, 0x1c(r31)
-/* 8036D1A8 6C038000 */ xoris r3, r0, 0x8000
-/* 8036D1AC 7C053010 */ subfc r0, r5, r6
-/* 8036D1B0 7C632110 */ subfe r3, r3, r4
-/* 8036D1B4 7C642110 */ subfe r3, r4, r4
-/* 8036D1B8 7C6300D1 */ neg. r3, r3
-/* 8036D1BC 41820018 */ beq- lbl_8036d1d4
-/* 8036D1C0 387F0000 */ addi r3, r31, 0x0
-/* 8036D1C4 38FE0000 */ addi r7, r30, 0x0
-/* 8036D1C8 38C00000 */ li r6, 0x0
-/* 8036D1CC 38A00000 */ li r5, 0x0
-/* 8036D1D0 4BFFFAE5 */ bl func_8036ccb4
-lbl_8036d1d4:
-/* 8036D1D4 838DCA28 */ lwz r28, lbl_805c6848@sda21(0)
-/* 8036D1D8 281C0000 */ cmplwi r28, 0
-/* 8036D1DC 41820074 */ beq- lbl_8036d250
-/* 8036D1E0 48005605 */ bl func_803727e4
-/* 8036D1E4 80DC000C */ lwz r6, 0xc(r28)
-/* 8036D1E8 38E00000 */ li r7, 0x0
-/* 8036D1EC 801C0008 */ lwz r0, 8(r28)
-/* 8036D1F0 6CE58000 */ xoris r5, r7, 0x8000
-/* 8036D1F4 7D043010 */ subfc r8, r4, r6
-/* 8036D1F8 7C030110 */ subfe r0, r3, r0
-/* 8036D1FC 6C068000 */ xoris r6, r0, 0x8000
-/* 8036D200 7C074010 */ subfc r0, r7, r8
-/* 8036D204 7CA53110 */ subfe r5, r5, r6
-/* 8036D208 7CA63110 */ subfe r5, r6, r6
-/* 8036D20C 7CA500D1 */ neg. r5, r5
-/* 8036D210 41820010 */ beq- lbl_8036d220
-/* 8036D214 38600000 */ li r3, 0x0
-/* 8036D218 4BFFEF91 */ bl func_8036c1a8
-/* 8036D21C 48000034 */ b lbl_8036d250
-lbl_8036d220:
-/* 8036D220 3C808000 */ lis r4, 0x8000
-/* 8036D224 6CE38000 */ xoris r3, r7, 0x8000
-/* 8036D228 7C044010 */ subfc r0, r4, r8
-/* 8036D22C 7C633110 */ subfe r3, r3, r6
-/* 8036D230 7C663110 */ subfe r3, r6, r6
-/* 8036D234 7C6300D1 */ neg. r3, r3
-/* 8036D238 41820010 */ beq- lbl_8036d248
-/* 8036D23C 7D034378 */ mr r3, r8
-/* 8036D240 4BFFEF69 */ bl func_8036c1a8
-/* 8036D244 4800000C */ b lbl_8036d250
-lbl_8036d248:
-/* 8036D248 3864FFFF */ addi r3, r4, -0x1
-/* 8036D24C 4BFFEF5D */ bl func_8036c1a8
-lbl_8036d250:
-/* 8036D250 48004565 */ bl func_803717b4
-/* 8036D254 38610018 */ addi r3, r1, 0x18
-/* 8036D258 48001009 */ bl func_8036e260
-/* 8036D25C 38610018 */ addi r3, r1, 0x18
-/* 8036D260 48000E39 */ bl func_8036e098
-/* 8036D264 399E0000 */ addi r12, r30, 0x0
-/* 8036D268 7D8803A6 */ mtlr r12
-/* 8036D26C 387F0000 */ addi r3, r31, 0x0
-/* 8036D270 389D0000 */ addi r4, r29, 0x0
-/* 8036D274 4E800021 */ blrl
-/* 8036D278 38610018 */ addi r3, r1, 0x18
-/* 8036D27C 48000FE5 */ bl func_8036e260
-/* 8036D280 7FA3EB78 */ mr r3, r29
-/* 8036D284 48000E15 */ bl func_8036e098
-/* 8036D288 4800456D */ bl func_803717f4
-/* 8036D28C 48004A5D */ bl func_80371ce8
-/* 8036D290 7FA3EB78 */ mr r3, r29
-/* 8036D294 48000EED */ bl func_8036e180
-/* 8036D298 800102F4 */ lwz r0, 0x2f4(r1)
-/* 8036D29C 83E102EC */ lwz r31, 0x2ec(r1)
-/* 8036D2A0 83C102E8 */ lwz r30, 0x2e8(r1)
-/* 8036D2A4 83A102E4 */ lwz r29, 0x2e4(r1)
-/* 8036D2A8 838102E0 */ lwz r28, 0x2e0(r1)
-/* 8036D2AC 382102F0 */ addi r1, r1, 0x2f0
-/* 8036D2B0 7C0803A6 */ mtlr r0
-/* 8036D2B4 4E800020 */ blr
-.size func_8036d088, . - func_8036d088
-
-
-.global func_8036d2b8
-.type func_8036d2b8, @function
-func_8036d2b8:
-/* 8036D2B8 90040000 */ stw r0, 0(r4)
-/* 8036D2BC 90240004 */ stw r1, 4(r4)
-/* 8036D2C0 90440008 */ stw r2, 8(r4)
-/* 8036D2C4 BCC40018 */ stmw r6, 0x18(r4)
-/* 8036D2C8 7C11E2A6 */ mfspr r0, 0x391
-/* 8036D2CC 900401A8 */ stw r0, 0x1a8(r4)
-/* 8036D2D0 7C12E2A6 */ mfspr r0, 0x392
-/* 8036D2D4 900401AC */ stw r0, 0x1ac(r4)
-/* 8036D2D8 7C13E2A6 */ mfspr r0, 0x393
-/* 8036D2DC 900401B0 */ stw r0, 0x1b0(r4)
-/* 8036D2E0 7C14E2A6 */ mfspr r0, 0x394
-/* 8036D2E4 900401B4 */ stw r0, 0x1b4(r4)
-/* 8036D2E8 7C15E2A6 */ mfspr r0, 0x395
-/* 8036D2EC 900401B8 */ stw r0, 0x1b8(r4)
-/* 8036D2F0 7C16E2A6 */ mfspr r0, 0x396
-/* 8036D2F4 900401BC */ stw r0, 0x1bc(r4)
-/* 8036D2F8 7C17E2A6 */ mfspr r0, 0x397
-/* 8036D2FC 900401C0 */ stw r0, 0x1c0(r4)
-/* 8036D300 9421FFF8 */ stwu r1, -8(r1)
-/* 8036D304 4BFFFD84 */ b func_8036d088
-.size func_8036d2b8, . - func_8036d2b8
-
diff --git a/asm/Dolphin/os/OSAlloc.s b/asm/Dolphin/os/OSAlloc.s
deleted file mode 100644
index 4c5d756..0000000
--- a/asm/Dolphin/os/OSAlloc.s
+++ /dev/null
@@ -1,260 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036d308
-.type func_8036d308, @function
-func_8036d308:
-/* 8036D308 38E30000 */ addi r7, r3, 0x0
-/* 8036D30C 38C00000 */ li r6, 0x0
-/* 8036D310 48000014 */ b lbl_8036d324
-lbl_8036d314:
-/* 8036D314 7C043840 */ cmplw r4, r7
-/* 8036D318 40810014 */ ble- lbl_8036d32c
-/* 8036D31C 7CE63B78 */ mr r6, r7
-/* 8036D320 80E70004 */ lwz r7, 4(r7)
-lbl_8036d324:
-/* 8036D324 28070000 */ cmplwi r7, 0
-/* 8036D328 4082FFEC */ bne+ lbl_8036d314
-lbl_8036d32c:
-/* 8036D32C 90E40004 */ stw r7, 4(r4)
-/* 8036D330 28070000 */ cmplwi r7, 0
-/* 8036D334 90C40000 */ stw r6, 0(r4)
-/* 8036D338 41820038 */ beq- lbl_8036d370
-/* 8036D33C 90870000 */ stw r4, 0(r7)
-/* 8036D340 80A40008 */ lwz r5, 8(r4)
-/* 8036D344 7C042A14 */ add r0, r4, r5
-/* 8036D348 7C003840 */ cmplw r0, r7
-/* 8036D34C 40820024 */ bne- lbl_8036d370
-/* 8036D350 80070008 */ lwz r0, 8(r7)
-/* 8036D354 7C050214 */ add r0, r5, r0
-/* 8036D358 90040008 */ stw r0, 8(r4)
-/* 8036D35C 80E70004 */ lwz r7, 4(r7)
-/* 8036D360 28070000 */ cmplwi r7, 0
-/* 8036D364 90E40004 */ stw r7, 4(r4)
-/* 8036D368 41820008 */ beq- lbl_8036d370
-/* 8036D36C 90870000 */ stw r4, 0(r7)
-lbl_8036d370:
-/* 8036D370 28060000 */ cmplwi r6, 0
-/* 8036D374 41820038 */ beq- lbl_8036d3ac
-/* 8036D378 90860004 */ stw r4, 4(r6)
-/* 8036D37C 80A60008 */ lwz r5, 8(r6)
-/* 8036D380 7C062A14 */ add r0, r6, r5
-/* 8036D384 7C002040 */ cmplw r0, r4
-/* 8036D388 4C820020 */ bnelr-
-/* 8036D38C 80040008 */ lwz r0, 8(r4)
-/* 8036D390 28070000 */ cmplwi r7, 0
-/* 8036D394 7C050214 */ add r0, r5, r0
-/* 8036D398 90060008 */ stw r0, 8(r6)
-/* 8036D39C 90E60004 */ stw r7, 4(r6)
-/* 8036D3A0 4D820020 */ beqlr-
-/* 8036D3A4 90C70000 */ stw r6, 0(r7)
-/* 8036D3A8 4E800020 */ blr
-lbl_8036d3ac:
-/* 8036D3AC 7C832378 */ mr r3, r4
-/* 8036D3B0 4E800020 */ blr
-.size func_8036d308, . - func_8036d308
-
-
-.global func_8036d3b4
-.type func_8036d3b4, @function
-func_8036d3b4:
-/* 8036D3B4 1C03000C */ mulli r0, r3, 0xc
-/* 8036D3B8 806DCA30 */ lwz r3, lbl_805c6850@sda21(0)
-/* 8036D3BC 7CA30214 */ add r5, r3, r0
-/* 8036D3C0 3804003F */ addi r0, r4, 0x3f
-/* 8036D3C4 80C50004 */ lwz r6, 4(r5)
-/* 8036D3C8 54030034 */ rlwinm r3, r0, 0, 0, 0x1a
-/* 8036D3CC 48000014 */ b lbl_8036d3e0
-lbl_8036d3d0:
-/* 8036D3D0 80060008 */ lwz r0, 8(r6)
-/* 8036D3D4 7C030000 */ cmpw r3, r0
-/* 8036D3D8 40810010 */ ble- lbl_8036d3e8
-/* 8036D3DC 80C60004 */ lwz r6, 4(r6)
-lbl_8036d3e0:
-/* 8036D3E0 28060000 */ cmplwi r6, 0
-/* 8036D3E4 4082FFEC */ bne+ lbl_8036d3d0
-lbl_8036d3e8:
-/* 8036D3E8 28060000 */ cmplwi r6, 0
-/* 8036D3EC 4082000C */ bne- lbl_8036d3f8
-/* 8036D3F0 38600000 */ li r3, 0x0
-/* 8036D3F4 4E800020 */ blr
-lbl_8036d3f8:
-/* 8036D3F8 80060008 */ lwz r0, 8(r6)
-/* 8036D3FC 7C030050 */ subf r0, r3, r0
-/* 8036D400 28000040 */ cmplwi r0, 0x40
-/* 8036D404 40800040 */ bge- lbl_8036d444
-/* 8036D408 80860004 */ lwz r4, 4(r6)
-/* 8036D40C 80650004 */ lwz r3, 4(r5)
-/* 8036D410 28040000 */ cmplwi r4, 0
-/* 8036D414 4182000C */ beq- lbl_8036d420
-/* 8036D418 80060000 */ lwz r0, 0(r6)
-/* 8036D41C 90040000 */ stw r0, 0(r4)
-lbl_8036d420:
-/* 8036D420 80860000 */ lwz r4, 0(r6)
-/* 8036D424 28040000 */ cmplwi r4, 0
-/* 8036D428 4082000C */ bne- lbl_8036d434
-/* 8036D42C 80660004 */ lwz r3, 4(r6)
-/* 8036D430 4800000C */ b lbl_8036d43c
-lbl_8036d434:
-/* 8036D434 80060004 */ lwz r0, 4(r6)
-/* 8036D438 90040004 */ stw r0, 4(r4)
-lbl_8036d43c:
-/* 8036D43C 90650004 */ stw r3, 4(r5)
-/* 8036D440 48000048 */ b lbl_8036d488
-lbl_8036d444:
-/* 8036D444 90660008 */ stw r3, 8(r6)
-/* 8036D448 7C861A14 */ add r4, r6, r3
-/* 8036D44C 90040008 */ stw r0, 8(r4)
-/* 8036D450 80060000 */ lwz r0, 0(r6)
-/* 8036D454 90040000 */ stw r0, 0(r4)
-/* 8036D458 80060004 */ lwz r0, 4(r6)
-/* 8036D45C 90040004 */ stw r0, 4(r4)
-/* 8036D460 80640004 */ lwz r3, 4(r4)
-/* 8036D464 28030000 */ cmplwi r3, 0
-/* 8036D468 41820008 */ beq- lbl_8036d470
-/* 8036D46C 90830000 */ stw r4, 0(r3)
-lbl_8036d470:
-/* 8036D470 80640000 */ lwz r3, 0(r4)
-/* 8036D474 28030000 */ cmplwi r3, 0
-/* 8036D478 4182000C */ beq- lbl_8036d484
-/* 8036D47C 90830004 */ stw r4, 4(r3)
-/* 8036D480 48000008 */ b lbl_8036d488
-lbl_8036d484:
-/* 8036D484 90850004 */ stw r4, 4(r5)
-lbl_8036d488:
-/* 8036D488 80650008 */ lwz r3, 8(r5)
-/* 8036D48C 38000000 */ li r0, 0x0
-/* 8036D490 90660004 */ stw r3, 4(r6)
-/* 8036D494 28030000 */ cmplwi r3, 0
-/* 8036D498 90060000 */ stw r0, 0(r6)
-/* 8036D49C 41820008 */ beq- lbl_8036d4a4
-/* 8036D4A0 90C30000 */ stw r6, 0(r3)
-lbl_8036d4a4:
-/* 8036D4A4 90C50008 */ stw r6, 8(r5)
-/* 8036D4A8 38660020 */ addi r3, r6, 0x20
-/* 8036D4AC 4E800020 */ blr
-.size func_8036d3b4, . - func_8036d3b4
-
-
-.global func_8036d4b0
-.type func_8036d4b0, @function
-func_8036d4b0:
-/* 8036D4B0 7C0802A6 */ mflr r0
-/* 8036D4B4 38C4FFE0 */ addi r6, r4, -0x20
-/* 8036D4B8 90010004 */ stw r0, 4(r1)
-/* 8036D4BC 1C03000C */ mulli r0, r3, 0xc
-/* 8036D4C0 9421FFE8 */ stwu r1, -0x18(r1)
-/* 8036D4C4 93E10014 */ stw r31, 0x14(r1)
-/* 8036D4C8 808DCA30 */ lwz r4, lbl_805c6850@sda21(0)
-/* 8036D4CC 80660004 */ lwz r3, 4(r6)
-/* 8036D4D0 7FE40214 */ add r31, r4, r0
-/* 8036D4D4 28030000 */ cmplwi r3, 0
-/* 8036D4D8 80BF0008 */ lwz r5, 8(r31)
-/* 8036D4DC 7CC43378 */ mr r4, r6
-/* 8036D4E0 4182000C */ beq- lbl_8036d4ec
-/* 8036D4E4 80040000 */ lwz r0, 0(r4)
-/* 8036D4E8 90030000 */ stw r0, 0(r3)
-lbl_8036d4ec:
-/* 8036D4EC 80640000 */ lwz r3, 0(r4)
-/* 8036D4F0 28030000 */ cmplwi r3, 0
-/* 8036D4F4 4082000C */ bne- lbl_8036d500
-/* 8036D4F8 80A40004 */ lwz r5, 4(r4)
-/* 8036D4FC 4800000C */ b lbl_8036d508
-lbl_8036d500:
-/* 8036D500 80040004 */ lwz r0, 4(r4)
-/* 8036D504 90030004 */ stw r0, 4(r3)
-lbl_8036d508:
-/* 8036D508 90BF0008 */ stw r5, 8(r31)
-/* 8036D50C 807F0004 */ lwz r3, 4(r31)
-/* 8036D510 4BFFFDF9 */ bl func_8036d308
-/* 8036D514 907F0004 */ stw r3, 4(r31)
-/* 8036D518 8001001C */ lwz r0, 0x1c(r1)
-/* 8036D51C 83E10014 */ lwz r31, 0x14(r1)
-/* 8036D520 38210018 */ addi r1, r1, 0x18
-/* 8036D524 7C0803A6 */ mtlr r0
-/* 8036D528 4E800020 */ blr
-.size func_8036d4b0, . - func_8036d4b0
-
-
-.global func_8036d52c
-.type func_8036d52c, @function
-func_8036d52c:
-/* 8036D52C 800D9EF8 */ lwz r0, lbl_805c3d18@sda21(0)
-/* 8036D530 906D9EF8 */ stw r3, lbl_805c3d18@sda21(0)
-/* 8036D534 7C030378 */ mr r3, r0
-/* 8036D538 4E800020 */ blr
-.size func_8036d52c, . - func_8036d52c
-
-
-.global func_8036d53c
-.type func_8036d53c, @function
-func_8036d53c:
-/* 8036D53C 1CE5000C */ mulli r7, r5, 0xc
-/* 8036D540 906DCA30 */ stw r3, lbl_805c6850@sda21(0)
-/* 8036D544 90ADCA34 */ stw r5, lbl_805c6854@sda21(0)
-/* 8036D548 38C00000 */ li r6, 0x0
-/* 8036D54C 38660000 */ addi r3, r6, 0x0
-/* 8036D550 39000000 */ li r8, 0x0
-/* 8036D554 38A0FFFF */ li r5, -0x1
-/* 8036D558 48000020 */ b lbl_8036d578
-lbl_8036d55c:
-/* 8036D55C 800DCA30 */ lwz r0, lbl_805c6850@sda21(0)
-/* 8036D560 39080001 */ addi r8, r8, 0x1
-/* 8036D564 7D203214 */ add r9, r0, r6
-/* 8036D568 90A90000 */ stw r5, 0(r9)
-/* 8036D56C 38C6000C */ addi r6, r6, 0xc
-/* 8036D570 90690008 */ stw r3, 8(r9)
-/* 8036D574 90690004 */ stw r3, 4(r9)
-lbl_8036d578:
-/* 8036D578 800DCA34 */ lwz r0, lbl_805c6854@sda21(0)
-/* 8036D57C 7C080000 */ cmpw r8, r0
-/* 8036D580 4180FFDC */ blt+ lbl_8036d55c
-/* 8036D584 806DCA30 */ lwz r3, lbl_805c6850@sda21(0)
-/* 8036D588 54800034 */ rlwinm r0, r4, 0, 0, 0x1a
-/* 8036D58C 3880FFFF */ li r4, -0x1
-/* 8036D590 900DCA3C */ stw r0, lbl_805c685c@sda21(0)
-/* 8036D594 7C633A14 */ add r3, r3, r7
-/* 8036D598 3803001F */ addi r0, r3, 0x1f
-/* 8036D59C 908D9EF8 */ stw r4, lbl_805c3d18@sda21(0)
-/* 8036D5A0 54030034 */ rlwinm r3, r0, 0, 0, 0x1a
-/* 8036D5A4 906DCA38 */ stw r3, lbl_805c6858@sda21(0)
-/* 8036D5A8 4E800020 */ blr
-.size func_8036d53c, . - func_8036d53c
-
-
-.global func_8036d5ac
-.type func_8036d5ac, @function
-func_8036d5ac:
-/* 8036D5AC 80CDCA34 */ lwz r6, lbl_805c6854@sda21(0)
-/* 8036D5B0 3803001F */ addi r0, r3, 0x1f
-/* 8036D5B4 80ADCA30 */ lwz r5, lbl_805c6850@sda21(0)
-/* 8036D5B8 54070034 */ rlwinm r7, r0, 0, 0, 0x1a
-/* 8036D5BC 2C060000 */ cmpwi r6, 0x0
-/* 8036D5C0 7CC903A6 */ mtctr r6
-/* 8036D5C4 54840034 */ rlwinm r4, r4, 0, 0, 0x1a
-/* 8036D5C8 38600000 */ li r3, 0x0
-/* 8036D5CC 40810044 */ ble- lbl_8036d610
-lbl_8036d5d0:
-/* 8036D5D0 80050000 */ lwz r0, 0(r5)
-/* 8036D5D4 2C000000 */ cmpwi r0, 0x0
-/* 8036D5D8 4080002C */ bge- lbl_8036d604
-/* 8036D5DC 7C072050 */ subf r0, r7, r4
-/* 8036D5E0 90050000 */ stw r0, 0(r5)
-/* 8036D5E4 38800000 */ li r4, 0x0
-/* 8036D5E8 90870000 */ stw r4, 0(r7)
-/* 8036D5EC 90870004 */ stw r4, 4(r7)
-/* 8036D5F0 80050000 */ lwz r0, 0(r5)
-/* 8036D5F4 90070008 */ stw r0, 8(r7)
-/* 8036D5F8 90E50004 */ stw r7, 4(r5)
-/* 8036D5FC 90850008 */ stw r4, 8(r5)
-/* 8036D600 4E800020 */ blr
-lbl_8036d604:
-/* 8036D604 38A5000C */ addi r5, r5, 0xc
-/* 8036D608 38630001 */ addi r3, r3, 0x1
-/* 8036D60C 4200FFC4 */ bdnz lbl_8036d5d0
-lbl_8036d610:
-/* 8036D610 3860FFFF */ li r3, -0x1
-/* 8036D614 4E800020 */ blr
-.size func_8036d5ac, . - func_8036d5ac
-
diff --git a/asm/Dolphin/os/OSAudioSystem-data.s b/asm/Dolphin/os/OSAudioSystem-data.s
deleted file mode 100644
index bd5e002..0000000
--- a/asm/Dolphin/os/OSAudioSystem-data.s
+++ /dev/null
@@ -1,43 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804eed70
-.type lbl_804eed70, @object
-lbl_804eed70:
-/* 804EED70 029F0010 */ .4byte 0x029f0010
-/* 804EED74 029F0033 */ .4byte 0x029f0033
-/* 804EED78 029F0034 */ .4byte 0x029f0034
-/* 804EED7C 029F0035 */ .4byte 0x029f0035
-/* 804EED80 029F0036 */ .4byte 0x029f0036
-/* 804EED84 029F0037 */ .4byte 0x029f0037
-/* 804EED88 029F0038 */ .4byte 0x029f0038
-/* 804EED8C 029F0039 */ .4byte 0x029f0039
-/* 804EED90 12061203 */ .4byte 0x12061203
-/* 804EED94 12041205 */ .4byte 0x12041205
-/* 804EED98 00808000 */ .4byte 0x00808000
-/* 804EED9C 0088FFFF */ .4byte 0x0088ffff
-/* 804EEDA0 00841000 */ .4byte 0x00841000
-/* 804EEDA4 0064001D */ .4byte 0x0064001d
-/* 804EEDA8 02180000 */ .4byte 0x02180000
-/* 804EEDAC 81001C1E */ .4byte 0x81001c1e
-/* 804EEDB0 00441B1E */ .4byte 0x00441b1e
-/* 804EEDB4 00840800 */ .4byte 0x00840800
-/* 804EEDB8 00640027 */ .4byte 0x00640027
-/* 804EEDBC 191E0000 */ .4byte 0x191e0000
-/* 804EEDC0 00DEFFFC */ .4byte 0x00defffc
-/* 804EEDC4 02A08000 */ .4byte 0x02a08000
-/* 804EEDC8 029C0028 */ .4byte 0x029c0028
-/* 804EEDCC 16FC0054 */ .4byte 0x16fc0054
-/* 804EEDD0 16FD4348 */ .4byte 0x16fd4348
-/* 804EEDD4 002102FF */ .4byte 0x002102ff
-/* 804EEDD8 02FF02FF */ .4byte 0x02ff02ff
-/* 804EEDDC 02FF02FF */ .4byte 0x02ff02ff
-/* 804EEDE0 02FF02FF */ .4byte 0x02ff02ff
-/* 804EEDE4 00000000 */ .4byte 0x00000000
-/* 804EEDE8 00000000 */ .4byte 0x00000000
-/* 804EEDEC 00000000 */ .4byte 0x00000000
-.size lbl_804eed70, . - lbl_804eed70
-
diff --git a/asm/Dolphin/os/OSAudioSystem.s b/asm/Dolphin/os/OSAudioSystem.s
deleted file mode 100644
index c3aafe4..0000000
--- a/asm/Dolphin/os/OSAudioSystem.s
+++ /dev/null
@@ -1,199 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036d638
-.type func_8036d638, @function
-func_8036d638:
-/* 8036D638 7C0802A6 */ mflr r0
-/* 8036D63C 90010004 */ stw r0, 4(r1)
-/* 8036D640 9421FFD0 */ stwu r1, -0x30(r1)
-/* 8036D644 BF210014 */ stmw r25, 0x14(r1)
-/* 8036D648 4BFFFFD1 */ bl func_8036d618
-/* 8036D64C 3C808100 */ lis r4, 0x8100
-/* 8036D650 38A00080 */ li r5, 0x80
-/* 8036D654 3863FF80 */ addi r3, r3, -0x80
-/* 8036D658 4BCA0DC5 */ bl func_8000e41c
-/* 8036D65C 3C60804F */ lis r3, lbl_804eed70@ha
-/* 8036D660 3883ED70 */ addi r4, r3, lbl_804eed70@l
-/* 8036D664 3C608100 */ lis r3, 0x8100
-/* 8036D668 38A00080 */ li r5, 0x80
-/* 8036D66C 4BCA0DB1 */ bl func_8000e41c
-/* 8036D670 3C608100 */ lis r3, 0x8100
-/* 8036D674 38800080 */ li r4, 0x80
-/* 8036D678 48000299 */ bl func_8036d910
-/* 8036D67C 3C60CC00 */ lis r3, 0xcc00
-/* 8036D680 38635000 */ addi r3, r3, 0x5000
-/* 8036D684 38000043 */ li r0, 0x43
-/* 8036D688 B0030012 */ sth r0, 0x12(r3)
-/* 8036D68C 3BE3000A */ addi r31, r3, 0xa
-/* 8036D690 380008AC */ li r0, 0x8ac
-/* 8036D694 B003000A */ sth r0, 0xa(r3)
-/* 8036D698 A003000A */ lhz r0, 0xa(r3)
-/* 8036D69C 60000001 */ ori r0, r0, 1
-/* 8036D6A0 B003000A */ sth r0, 0xa(r3)
-lbl_8036d6a4:
-/* 8036D6A4 A01F0000 */ lhz r0, 0(r31)
-/* 8036D6A8 540007FF */ clrlwi. r0, r0, 0x1f
-/* 8036D6AC 4082FFF8 */ bne+ lbl_8036d6a4
-/* 8036D6B0 38000000 */ li r0, 0x0
-/* 8036D6B4 3C80CC00 */ lis r4, 0xcc00
-/* 8036D6B8 B0045000 */ sth r0, 0x5000(r4)
-lbl_8036d6bc:
-/* 8036D6BC 3BC45000 */ addi r30, r4, 0x5000
-/* 8036D6C0 A47E0004 */ lhzu r3, 4(r30)
-/* 8036D6C4 3BA45000 */ addi r29, r4, 0x5000
-/* 8036D6C8 A41D0006 */ lhzu r0, 6(r29)
-/* 8036D6CC 5060801E */ rlwimi r0, r3, 0x10, 0, 0xf
-/* 8036D6D0 54000001 */ rlwinm. r0, r0, 0, 0, 0
-/* 8036D6D4 4082FFE8 */ bne+ lbl_8036d6bc
-/* 8036D6D8 3C60CC00 */ lis r3, 0xcc00
-/* 8036D6DC 3C000100 */ lis r0, 0x100
-/* 8036D6E0 3B635000 */ addi r27, r3, 0x5000
-/* 8036D6E4 941B0020 */ stwu r0, 0x20(r27)
-/* 8036D6E8 38000000 */ li r0, 0x0
-/* 8036D6EC 3B435000 */ addi r26, r3, 0x5000
-/* 8036D6F0 941A0024 */ stwu r0, 0x24(r26)
-/* 8036D6F4 38000020 */ li r0, 0x20
-/* 8036D6F8 3B235000 */ addi r25, r3, 0x5000
-/* 8036D6FC 94190028 */ stwu r0, 0x28(r25)
-/* 8036D700 A07F0000 */ lhz r3, 0(r31)
-/* 8036D704 48000008 */ b lbl_8036d70c
-lbl_8036d708:
-/* 8036D708 A07F0000 */ lhz r3, 0(r31)
-lbl_8036d70c:
-/* 8036D70C 546006B5 */ rlwinm. r0, r3, 0, 0x1a, 0x1a
-/* 8036D710 4182FFF8 */ beq+ lbl_8036d708
-/* 8036D714 B07F0000 */ sth r3, 0(r31)
-/* 8036D718 480050C5 */ bl func_803727dc
-/* 8036D71C 7C7C1B78 */ mr r28, r3
-lbl_8036d720:
-/* 8036D720 480050BD */ bl func_803727dc
-/* 8036D724 7C1C1850 */ subf r0, r28, r3
-/* 8036D728 2C000892 */ cmpwi r0, 0x892
-/* 8036D72C 4180FFF4 */ blt+ lbl_8036d720
-/* 8036D730 3C000100 */ lis r0, 0x100
-/* 8036D734 901B0000 */ stw r0, 0(r27)
-/* 8036D738 38600000 */ li r3, 0x0
-/* 8036D73C 38000020 */ li r0, 0x20
-/* 8036D740 907A0000 */ stw r3, 0(r26)
-/* 8036D744 90190000 */ stw r0, 0(r25)
-/* 8036D748 A07F0000 */ lhz r3, 0(r31)
-/* 8036D74C 48000008 */ b lbl_8036d754
-lbl_8036d750:
-/* 8036D750 A07F0000 */ lhz r3, 0(r31)
-lbl_8036d754:
-/* 8036D754 546006B5 */ rlwinm. r0, r3, 0, 0x1a, 0x1a
-/* 8036D758 4182FFF8 */ beq+ lbl_8036d750
-/* 8036D75C B07F0000 */ sth r3, 0(r31)
-/* 8036D760 A01F0000 */ lhz r0, 0(r31)
-/* 8036D764 54000566 */ rlwinm r0, r0, 0, 0x15, 0x13
-/* 8036D768 B01F0000 */ sth r0, 0(r31)
-lbl_8036d76c:
-/* 8036D76C A01F0000 */ lhz r0, 0(r31)
-/* 8036D770 5400056B */ rlwinm. r0, r0, 0, 0x15, 0x15
-/* 8036D774 4082FFF8 */ bne+ lbl_8036d76c
-/* 8036D778 A01F0000 */ lhz r0, 0(r31)
-/* 8036D77C 540007B8 */ rlwinm r0, r0, 0, 0x1e, 0x1c
-/* 8036D780 B01F0000 */ sth r0, 0(r31)
-/* 8036D784 A01E0000 */ lhz r0, 0(r30)
-/* 8036D788 48000008 */ b lbl_8036d790
-lbl_8036d78c:
-/* 8036D78C A01E0000 */ lhz r0, 0(r30)
-lbl_8036d790:
-/* 8036D790 5405043E */ clrlwi r5, r0, 0x10
-/* 8036D794 54000421 */ rlwinm. r0, r0, 0, 0x10, 0x10
-/* 8036D798 4182FFF4 */ beq+ lbl_8036d78c
-/* 8036D79C A01F0000 */ lhz r0, 0(r31)
-/* 8036D7A0 A09D0000 */ lhz r4, 0(r29)
-/* 8036D7A4 60000004 */ ori r0, r0, 4
-/* 8036D7A8 B01F0000 */ sth r0, 0(r31)
-/* 8036D7AC 380008AC */ li r0, 0x8ac
-/* 8036D7B0 B01F0000 */ sth r0, 0(r31)
-/* 8036D7B4 A01F0000 */ lhz r0, 0(r31)
-/* 8036D7B8 60000001 */ ori r0, r0, 1
-/* 8036D7BC B01F0000 */ sth r0, 0(r31)
-lbl_8036d7c0:
-/* 8036D7C0 A01F0000 */ lhz r0, 0(r31)
-/* 8036D7C4 540007FF */ clrlwi. r0, r0, 0x1f
-/* 8036D7C8 4082FFF8 */ bne+ lbl_8036d7c0
-/* 8036D7CC 4BFFFE4D */ bl func_8036d618
-/* 8036D7D0 3883FF80 */ addi r4, r3, -0x80
-/* 8036D7D4 3C608100 */ lis r3, 0x8100
-/* 8036D7D8 38A00080 */ li r5, 0x80
-/* 8036D7DC 4BCA0C41 */ bl func_8000e41c
-/* 8036D7E0 BB210014 */ lmw r25, 0x14(r1)
-/* 8036D7E4 80010034 */ lwz r0, 0x34(r1)
-/* 8036D7E8 38210030 */ addi r1, r1, 0x30
-/* 8036D7EC 7C0803A6 */ mtlr r0
-/* 8036D7F0 4E800020 */ blr
-.size func_8036d638, . - func_8036d638
-
-
-.global func_8036d7f4
-.type func_8036d7f4, @function
-func_8036d7f4:
-/* 8036D7F4 7C0802A6 */ mflr r0
-/* 8036D7F8 3C60CC00 */ lis r3, 0xcc00
-/* 8036D7FC 90010004 */ stw r0, 4(r1)
-/* 8036D800 38000804 */ li r0, 0x804
-/* 8036D804 9421FFF0 */ stwu r1, -0x10(r1)
-/* 8036D808 93E1000C */ stw r31, 0xc(r1)
-/* 8036D80C 3BE35000 */ addi r31, r3, 0x5000
-/* 8036D810 38635000 */ addi r3, r3, 0x5000
-/* 8036D814 93C10008 */ stw r30, 8(r1)
-/* 8036D818 B01F000A */ sth r0, 0xa(r31)
-/* 8036D81C A0030036 */ lhz r0, 0x36(r3)
-/* 8036D820 5400045E */ rlwinm r0, r0, 0, 0x11, 0xf
-/* 8036D824 B0030036 */ sth r0, 0x36(r3)
-/* 8036D828 A41F000A */ lhzu r0, 0xa(r31)
-/* 8036D82C 48000008 */ b lbl_8036d834
-lbl_8036d830:
-/* 8036D830 A01F0000 */ lhz r0, 0(r31)
-lbl_8036d834:
-/* 8036D834 5400056B */ rlwinm. r0, r0, 0, 0x15, 0x15
-/* 8036D838 4082FFF8 */ bne+ lbl_8036d830
-/* 8036D83C A01F0000 */ lhz r0, 0(r31)
-/* 8036D840 48000008 */ b lbl_8036d848
-lbl_8036d844:
-/* 8036D844 A01F0000 */ lhz r0, 0(r31)
-lbl_8036d848:
-/* 8036D848 540005AD */ rlwinm. r0, r0, 0, 0x16, 0x16
-/* 8036D84C 4082FFF8 */ bne+ lbl_8036d844
-/* 8036D850 380008AC */ li r0, 0x8ac
-/* 8036D854 3C60CC00 */ lis r3, 0xcc00
-/* 8036D858 B01F0000 */ sth r0, 0(r31)
-/* 8036D85C 38000000 */ li r0, 0x0
-/* 8036D860 B0035000 */ sth r0, 0x5000(r3)
-/* 8036D864 38835000 */ addi r4, r3, 0x5000
-lbl_8036d868:
-/* 8036D868 A0640004 */ lhz r3, 4(r4)
-/* 8036D86C A0040006 */ lhz r0, 6(r4)
-/* 8036D870 5060801E */ rlwimi r0, r3, 0x10, 0, 0xf
-/* 8036D874 54000001 */ rlwinm. r0, r0, 0, 0, 0
-/* 8036D878 4082FFF0 */ bne+ lbl_8036d868
-/* 8036D87C 48004F61 */ bl func_803727dc
-/* 8036D880 7C7E1B78 */ mr r30, r3
-lbl_8036d884:
-/* 8036D884 48004F59 */ bl func_803727dc
-/* 8036D888 7C1E1850 */ subf r0, r30, r3
-/* 8036D88C 2C00002C */ cmpwi r0, 0x2c
-/* 8036D890 4180FFF4 */ blt+ lbl_8036d884
-/* 8036D894 A01F0000 */ lhz r0, 0(r31)
-/* 8036D898 60000001 */ ori r0, r0, 1
-/* 8036D89C B01F0000 */ sth r0, 0(r31)
-/* 8036D8A0 A01F0000 */ lhz r0, 0(r31)
-/* 8036D8A4 48000008 */ b lbl_8036d8ac
-lbl_8036d8a8:
-/* 8036D8A8 A01F0000 */ lhz r0, 0(r31)
-lbl_8036d8ac:
-/* 8036D8AC 540007FF */ clrlwi. r0, r0, 0x1f
-/* 8036D8B0 4082FFF8 */ bne+ lbl_8036d8a8
-/* 8036D8B4 80010014 */ lwz r0, 0x14(r1)
-/* 8036D8B8 83E1000C */ lwz r31, 0xc(r1)
-/* 8036D8BC 83C10008 */ lwz r30, 8(r1)
-/* 8036D8C0 38210010 */ addi r1, r1, 0x10
-/* 8036D8C4 7C0803A6 */ mtlr r0
-/* 8036D8C8 4E800020 */ blr
-.size func_8036d7f4, . - func_8036d7f4
-
diff --git a/asm/Dolphin/os/OSCache-data.s b/asm/Dolphin/os/OSCache-data.s
deleted file mode 100644
index a04cf5d..0000000
--- a/asm/Dolphin/os/OSCache-data.s
+++ /dev/null
@@ -1,151 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804eedf0
-.type lbl_804eedf0, @object
-lbl_804eedf0:
-/* 804EEDF0 3E3E3E20 */ .4byte 0x3e3e3e20
-/* 804EEDF4 4C322049 */ .4byte 0x4c322049
-/* 804EEDF8 4E56414C */ .4byte 0x4e56414c
-/* 804EEDFC 49444154 */ .4byte 0x49444154
-/* 804EEE00 45203A20 */ .4byte 0x45203a20
-/* 804EEE04 53484F55 */ .4byte 0x53484f55
-/* 804EEE08 4C44204E */ .4byte 0x4c44204e
-/* 804EEE0C 45564552 */ .4byte 0x45564552
-/* 804EEE10 20484150 */ .4byte 0x20484150
-/* 804EEE14 50454E0A */ .4byte 0x50454e0a
-/* 804EEE18 00000000 */ .4byte 0x00000000
-/* 804EEE1C 4D616368 */ .4byte 0x4d616368
-/* 804EEE20 696E6520 */ .4byte 0x696e6520
-/* 804EEE24 63686563 */ .4byte 0x63686563
-/* 804EEE28 6B207265 */ .4byte 0x6b207265
-/* 804EEE2C 63656976 */ .4byte 0x63656976
-/* 804EEE30 65640A00 */ .4byte 0x65640a00
-/* 804EEE34 48494432 */ .4byte 0x48494432
-/* 804EEE38 203D2030 */ .4byte 0x203d2030
-/* 804EEE3C 78257820 */ .4byte 0x78257820
-/* 804EEE40 20205352 */ .4byte 0x20205352
-/* 804EEE44 5231203D */ .4byte 0x5231203d
-/* 804EEE48 20307825 */ .4byte 0x20307825
-/* 804EEE4C 780A0000 */ .4byte 0x780a0000
-/* 804EEE50 4D616368 */ .4byte 0x4d616368
-/* 804EEE54 696E6520 */ .4byte 0x696e6520
-/* 804EEE58 63686563 */ .4byte 0x63686563
-/* 804EEE5C 6B207761 */ .4byte 0x6b207761
-/* 804EEE60 73206E6F */ .4byte 0x73206e6f
-/* 804EEE64 7420444D */ .4byte 0x7420444d
-/* 804EEE68 412F6C6F */ .4byte 0x412f6c6f
-/* 804EEE6C 636B6564 */ .4byte 0x636b6564
-/* 804EEE70 20636163 */ .4byte 0x20636163
-/* 804EEE74 68652072 */ .4byte 0x68652072
-/* 804EEE78 656C6174 */ .4byte 0x656c6174
-/* 804EEE7C 65640A00 */ .4byte 0x65640a00
-/* 804EEE80 444D4145 */ .4byte 0x444d4145
-/* 804EEE84 72726F72 */ .4byte 0x72726f72
-/* 804EEE88 48616E64 */ .4byte 0x48616e64
-/* 804EEE8C 6C657228 */ .4byte 0x6c657228
-/* 804EEE90 293A2041 */ .4byte 0x293a2041
-/* 804EEE94 6E206572 */ .4byte 0x6e206572
-/* 804EEE98 726F7220 */ .4byte 0x726f7220
-/* 804EEE9C 6F636375 */ .4byte 0x6f636375
-/* 804EEEA0 72726564 */ .4byte 0x72726564
-/* 804EEEA4 20776869 */ .4byte 0x20776869
-/* 804EEEA8 6C652070 */ .4byte 0x6c652070
-/* 804EEEAC 726F6365 */ .4byte 0x726f6365
-/* 804EEEB0 7373696E */ .4byte 0x7373696e
-/* 804EEEB4 6720444D */ .4byte 0x6720444d
-/* 804EEEB8 412E0A00 */ .4byte 0x412e0a00
-/* 804EEEBC 54686520 */ .4byte 0x54686520
-/* 804EEEC0 666F6C6C */ .4byte 0x666f6c6c
-/* 804EEEC4 6F77696E */ .4byte 0x6f77696e
-/* 804EEEC8 67206572 */ .4byte 0x67206572
-/* 804EEECC 726F7273 */ .4byte 0x726f7273
-/* 804EEED0 20686176 */ .4byte 0x20686176
-/* 804EEED4 65206265 */ .4byte 0x65206265
-/* 804EEED8 656E2064 */ .4byte 0x656e2064
-/* 804EEEDC 65746563 */ .4byte 0x65746563
-/* 804EEEE0 74656420 */ .4byte 0x74656420
-/* 804EEEE4 616E6420 */ .4byte 0x616e6420
-/* 804EEEE8 636C6561 */ .4byte 0x636c6561
-/* 804EEEEC 72656420 */ .4byte 0x72656420
-/* 804EEEF0 3A0A0000 */ .4byte 0x3a0a0000
-/* 804EEEF4 092D2052 */ .4byte 0x092d2052
-/* 804EEEF8 65717565 */ .4byte 0x65717565
-/* 804EEEFC 73746564 */ .4byte 0x73746564
-/* 804EEF00 2061206C */ .4byte 0x2061206c
-/* 804EEF04 6F636B65 */ .4byte 0x6f636b65
-/* 804EEF08 64206361 */ .4byte 0x64206361
-/* 804EEF0C 63686520 */ .4byte 0x63686520
-/* 804EEF10 74616720 */ .4byte 0x74616720
-/* 804EEF14 74686174 */ .4byte 0x74686174
-/* 804EEF18 20776173 */ .4byte 0x20776173
-/* 804EEF1C 20616C72 */ .4byte 0x20616c72
-/* 804EEF20 65616479 */ .4byte 0x65616479
-/* 804EEF24 20696E20 */ .4byte 0x20696e20
-/* 804EEF28 74686520 */ .4byte 0x74686520
-/* 804EEF2C 63616368 */ .4byte 0x63616368
-/* 804EEF30 650A0000 */ .4byte 0x650a0000
-/* 804EEF34 092D2044 */ .4byte 0x092d2044
-/* 804EEF38 4D412061 */ .4byte 0x4d412061
-/* 804EEF3C 7474656D */ .4byte 0x7474656d
-/* 804EEF40 70746564 */ .4byte 0x70746564
-/* 804EEF44 20746F20 */ .4byte 0x20746f20
-/* 804EEF48 61636365 */ .4byte 0x61636365
-/* 804EEF4C 7373206E */ .4byte 0x7373206e
-/* 804EEF50 6F726D61 */ .4byte 0x6f726d61
-/* 804EEF54 6C206361 */ .4byte 0x6c206361
-/* 804EEF58 6368650A */ .4byte 0x6368650a
-/* 804EEF5C 00000000 */ .4byte 0x00000000
-/* 804EEF60 092D2044 */ .4byte 0x092d2044
-/* 804EEF64 4D41206D */ .4byte 0x4d41206d
-/* 804EEF68 69737365 */ .4byte 0x69737365
-/* 804EEF6C 6420696E */ .4byte 0x6420696e
-/* 804EEF70 20646174 */ .4byte 0x20646174
-/* 804EEF74 61206361 */ .4byte 0x61206361
-/* 804EEF78 6368650A */ .4byte 0x6368650a
-/* 804EEF7C 00000000 */ .4byte 0x00000000
-/* 804EEF80 092D2044 */ .4byte 0x092d2044
-/* 804EEF84 4D412071 */ .4byte 0x4d412071
-/* 804EEF88 75657565 */ .4byte 0x75657565
-/* 804EEF8C 206F7665 */ .4byte 0x206f7665
-/* 804EEF90 72666C6F */ .4byte 0x72666c6f
-/* 804EEF94 7765640A */ .4byte 0x7765640a
-/* 804EEF98 00000000 */ .4byte 0x00000000
-/* 804EEF9C 4C312069 */ .4byte 0x4c312069
-/* 804EEFA0 2D636163 */ .4byte 0x2d636163
-/* 804EEFA4 68657320 */ .4byte 0x68657320
-/* 804EEFA8 696E6974 */ .4byte 0x696e6974
-/* 804EEFAC 69616C69 */ .4byte 0x69616c69
-/* 804EEFB0 7A65640A */ .4byte 0x7a65640a
-/* 804EEFB4 00000000 */ .4byte 0x00000000
-/* 804EEFB8 4C312064 */ .4byte 0x4c312064
-/* 804EEFBC 2D636163 */ .4byte 0x2d636163
-/* 804EEFC0 68657320 */ .4byte 0x68657320
-/* 804EEFC4 696E6974 */ .4byte 0x696e6974
-/* 804EEFC8 69616C69 */ .4byte 0x69616c69
-/* 804EEFCC 7A65640A */ .4byte 0x7a65640a
-/* 804EEFD0 00000000 */ .4byte 0x00000000
-/* 804EEFD4 4C322063 */ .4byte 0x4c322063
-/* 804EEFD8 61636865 */ .4byte 0x61636865
-/* 804EEFDC 20696E69 */ .4byte 0x20696e69
-/* 804EEFE0 7469616C */ .4byte 0x7469616c
-/* 804EEFE4 697A6564 */ .4byte 0x697a6564
-/* 804EEFE8 0A000000 */ .4byte 0x0a000000
-/* 804EEFEC 4C6F636B */ .4byte 0x4c6f636b
-/* 804EEFF0 65642063 */ .4byte 0x65642063
-/* 804EEFF4 61636865 */ .4byte 0x61636865
-/* 804EEFF8 206D6163 */ .4byte 0x206d6163
-/* 804EEFFC 68696E65 */ .4byte 0x68696e65
-/* 804EF000 20636865 */ .4byte 0x20636865
-/* 804EF004 636B2068 */ .4byte 0x636b2068
-/* 804EF008 616E646C */ .4byte 0x616e646c
-/* 804EF00C 65722069 */ .4byte 0x65722069
-/* 804EF010 6E737461 */ .4byte 0x6e737461
-/* 804EF014 6C6C6564 */ .4byte 0x6c6c6564
-/* 804EF018 0A000000 */ .4byte 0x0a000000
-/* 804EF01C 00000000 */ .4byte 0x00000000
-.size lbl_804eedf0, . - lbl_804eedf0
-
diff --git a/asm/Dolphin/os/OSCache.s b/asm/Dolphin/os/OSCache.s
deleted file mode 100644
index dc8cd69..0000000
--- a/asm/Dolphin/os/OSCache.s
+++ /dev/null
@@ -1,476 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036d8cc
-.type func_8036d8cc, @function
-func_8036d8cc:
-/* 8036D8CC 7C0004AC */ sync 0
-/* 8036D8D0 7C70FAA6 */ mfspr r3, 0x3f0
-/* 8036D8D4 60634000 */ ori r3, r3, 0x4000
-/* 8036D8D8 7C70FBA6 */ mtspr 0x3f0, r3
-/* 8036D8DC 4E800020 */ blr
-.size func_8036d8cc, . - func_8036d8cc
-
-
-.global func_8036d8e0
-.type func_8036d8e0, @function
-func_8036d8e0:
-/* 8036D8E0 28040000 */ cmplwi r4, 0
-/* 8036D8E4 4C810020 */ blelr-
-/* 8036D8E8 546506FF */ clrlwi. r5, r3, 0x1b
-/* 8036D8EC 41820008 */ beq- lbl_8036d8f4
-/* 8036D8F0 38840020 */ addi r4, r4, 0x20
-lbl_8036d8f4:
-/* 8036D8F4 3884001F */ addi r4, r4, 0x1f
-/* 8036D8F8 5484D97E */ srwi r4, r4, 5
-/* 8036D8FC 7C8903A6 */ mtctr r4
-lbl_8036d900:
-/* 8036D900 7C001BAC */ dcbi 0, r3
-/* 8036D904 38630020 */ addi r3, r3, 0x20
-/* 8036D908 4200FFF8 */ bdnz lbl_8036d900
-/* 8036D90C 4E800020 */ blr
-.size func_8036d8e0, . - func_8036d8e0
-
-
-.global func_8036d910
-.type func_8036d910, @function
-func_8036d910:
-/* 8036D910 28040000 */ cmplwi r4, 0
-/* 8036D914 4C810020 */ blelr-
-/* 8036D918 546506FF */ clrlwi. r5, r3, 0x1b
-/* 8036D91C 41820008 */ beq- lbl_8036d924
-/* 8036D920 38840020 */ addi r4, r4, 0x20
-lbl_8036d924:
-/* 8036D924 3884001F */ addi r4, r4, 0x1f
-/* 8036D928 5484D97E */ srwi r4, r4, 5
-/* 8036D92C 7C8903A6 */ mtctr r4
-lbl_8036d930:
-/* 8036D930 7C0018AC */ dcbf 0, r3
-/* 8036D934 38630020 */ addi r3, r3, 0x20
-/* 8036D938 4200FFF8 */ bdnz lbl_8036d930
-/* 8036D93C 44000002 */ sc
-/* 8036D940 4E800020 */ blr
-.size func_8036d910, . - func_8036d910
-
-
-.global func_8036d944
-.type func_8036d944, @function
-func_8036d944:
-/* 8036D944 28040000 */ cmplwi r4, 0
-/* 8036D948 4C810020 */ blelr-
-/* 8036D94C 546506FF */ clrlwi. r5, r3, 0x1b
-/* 8036D950 41820008 */ beq- lbl_8036d958
-/* 8036D954 38840020 */ addi r4, r4, 0x20
-lbl_8036d958:
-/* 8036D958 3884001F */ addi r4, r4, 0x1f
-/* 8036D95C 5484D97E */ srwi r4, r4, 5
-/* 8036D960 7C8903A6 */ mtctr r4
-lbl_8036d964:
-/* 8036D964 7C00186C */ dcbst 0, r3
-/* 8036D968 38630020 */ addi r3, r3, 0x20
-/* 8036D96C 4200FFF8 */ bdnz lbl_8036d964
-/* 8036D970 44000002 */ sc
-/* 8036D974 4E800020 */ blr
-.size func_8036d944, . - func_8036d944
-
-
-.global func_8036d978
-.type func_8036d978, @function
-func_8036d978:
-/* 8036D978 28040000 */ cmplwi r4, 0
-/* 8036D97C 4C810020 */ blelr-
-/* 8036D980 546506FF */ clrlwi. r5, r3, 0x1b
-/* 8036D984 41820008 */ beq- lbl_8036d98c
-/* 8036D988 38840020 */ addi r4, r4, 0x20
-lbl_8036d98c:
-/* 8036D98C 3884001F */ addi r4, r4, 0x1f
-/* 8036D990 5484D97E */ srwi r4, r4, 5
-/* 8036D994 7C8903A6 */ mtctr r4
-lbl_8036d998:
-/* 8036D998 7C0018AC */ dcbf 0, r3
-/* 8036D99C 38630020 */ addi r3, r3, 0x20
-/* 8036D9A0 4200FFF8 */ bdnz lbl_8036d998
-/* 8036D9A4 4E800020 */ blr
-.size func_8036d978, . - func_8036d978
-
-
-.global func_8036d9a8
-.type func_8036d9a8, @function
-func_8036d9a8:
-/* 8036D9A8 28040000 */ cmplwi r4, 0
-/* 8036D9AC 4C810020 */ blelr-
-/* 8036D9B0 546506FF */ clrlwi. r5, r3, 0x1b
-/* 8036D9B4 41820008 */ beq- lbl_8036d9bc
-/* 8036D9B8 38840020 */ addi r4, r4, 0x20
-lbl_8036d9bc:
-/* 8036D9BC 3884001F */ addi r4, r4, 0x1f
-/* 8036D9C0 5484D97E */ srwi r4, r4, 5
-/* 8036D9C4 7C8903A6 */ mtctr r4
-lbl_8036d9c8:
-/* 8036D9C8 7C00186C */ dcbst 0, r3
-/* 8036D9CC 38630020 */ addi r3, r3, 0x20
-/* 8036D9D0 4200FFF8 */ bdnz lbl_8036d9c8
-/* 8036D9D4 4E800020 */ blr
-.size func_8036d9a8, . - func_8036d9a8
-
-
-.global func_8036d9d8
-.type func_8036d9d8, @function
-func_8036d9d8:
-/* 8036D9D8 28040000 */ cmplwi r4, 0
-/* 8036D9DC 4C810020 */ blelr-
-/* 8036D9E0 546506FF */ clrlwi. r5, r3, 0x1b
-/* 8036D9E4 41820008 */ beq- lbl_8036d9ec
-/* 8036D9E8 38840020 */ addi r4, r4, 0x20
-lbl_8036d9ec:
-/* 8036D9EC 3884001F */ addi r4, r4, 0x1f
-/* 8036D9F0 5484D97E */ srwi r4, r4, 5
-/* 8036D9F4 7C8903A6 */ mtctr r4
-lbl_8036d9f8:
-/* 8036D9F8 7C001FAC */ icbi 0, r3
-/* 8036D9FC 38630020 */ addi r3, r3, 0x20
-/* 8036DA00 4200FFF8 */ bdnz lbl_8036d9f8
-/* 8036DA04 7C0004AC */ sync 0
-/* 8036DA08 4C00012C */ isync
-/* 8036DA0C 4E800020 */ blr
-.size func_8036d9d8, . - func_8036d9d8
-
-
-.global func_8036da10
-.type func_8036da10, @function
-func_8036da10:
-/* 8036DA10 7C70FAA6 */ mfspr r3, 0x3f0
-/* 8036DA14 60630800 */ ori r3, r3, 0x800
-/* 8036DA18 7C70FBA6 */ mtspr 0x3f0, r3
-/* 8036DA1C 4E800020 */ blr
-.size func_8036da10, . - func_8036da10
-
-
-.global func_8036da20
-.type func_8036da20, @function
-func_8036da20:
-/* 8036DA20 4C00012C */ isync
-/* 8036DA24 7C70FAA6 */ mfspr r3, 0x3f0
-/* 8036DA28 60638000 */ ori r3, r3, 0x8000
-/* 8036DA2C 7C70FBA6 */ mtspr 0x3f0, r3
-/* 8036DA30 4E800020 */ blr
-.size func_8036da20, . - func_8036da20
-
-
-.global func_8036da34
-.type func_8036da34, @function
-func_8036da34:
-/* 8036DA34 7CA000A6 */ mfmsr r5
-/* 8036DA38 60A51000 */ ori r5, r5, 0x1000
-/* 8036DA3C 7CA00124 */ mtmsr r5
-/* 8036DA40 3C608000 */ lis r3, 0x8000
-/* 8036DA44 38800400 */ li r4, 0x400
-/* 8036DA48 7C8903A6 */ mtctr r4
-lbl_8036da4c:
-/* 8036DA4C 7C001A2C */ dcbt 0, r3
-/* 8036DA50 7C00186C */ dcbst 0, r3
-/* 8036DA54 38630020 */ addi r3, r3, 0x20
-/* 8036DA58 4200FFF4 */ bdnz lbl_8036da4c
-/* 8036DA5C 7C98E2A6 */ mfspr r4, 0x398
-/* 8036DA60 6484100F */ oris r4, r4, 0x100f
-/* 8036DA64 7C98E3A6 */ mtspr 0x398, r4
-/* 8036DA68 60000000 */ nop
-/* 8036DA6C 60000000 */ nop
-/* 8036DA70 60000000 */ nop
-/* 8036DA74 60000000 */ nop
-/* 8036DA78 60000000 */ nop
-/* 8036DA7C 60000000 */ nop
-/* 8036DA80 60000000 */ nop
-/* 8036DA84 60000000 */ nop
-/* 8036DA88 60000000 */ nop
-/* 8036DA8C 60000000 */ nop
-/* 8036DA90 60000000 */ nop
-/* 8036DA94 60000000 */ nop
-/* 8036DA98 3C60E000 */ lis r3, 0xe000
-/* 8036DA9C 60630002 */ ori r3, r3, 2
-/* 8036DAA0 7C7F83A6 */ mtdbatl 3, r3
-/* 8036DAA4 606301FE */ ori r3, r3, 0x1fe
-/* 8036DAA8 7C7E83A6 */ mtdbatu 3, r3
-/* 8036DAAC 4C00012C */ isync
-/* 8036DAB0 3C60E000 */ lis r3, 0xe000
-/* 8036DAB4 38C00200 */ li r6, 0x200
-/* 8036DAB8 7CC903A6 */ mtctr r6
-/* 8036DABC 38C00000 */ li r6, 0x0
-lbl_8036dac0:
-/* 8036DAC0 10061FEC */ .4byte 0x10061fec
-/* 8036DAC4 38630020 */ addi r3, r3, 0x20
-/* 8036DAC8 4200FFF8 */ bdnz lbl_8036dac0
-/* 8036DACC 60000000 */ nop
-/* 8036DAD0 60000000 */ nop
-/* 8036DAD4 60000000 */ nop
-/* 8036DAD8 60000000 */ nop
-/* 8036DADC 60000000 */ nop
-/* 8036DAE0 60000000 */ nop
-/* 8036DAE4 60000000 */ nop
-/* 8036DAE8 60000000 */ nop
-/* 8036DAEC 60000000 */ nop
-/* 8036DAF0 60000000 */ nop
-/* 8036DAF4 60000000 */ nop
-/* 8036DAF8 60000000 */ nop
-/* 8036DAFC 4E800020 */ blr
-.size func_8036da34, . - func_8036da34
-
-
-.global func_8036db00
-.type func_8036db00, @function
-func_8036db00:
-/* 8036DB00 7C0802A6 */ mflr r0
-/* 8036DB04 90010004 */ stw r0, 4(r1)
-/* 8036DB08 9421FFF0 */ stwu r1, -0x10(r1)
-/* 8036DB0C 93E1000C */ stw r31, 0xc(r1)
-/* 8036DB10 48000FC5 */ bl func_8036ead4
-/* 8036DB14 7C7F1B78 */ mr r31, r3
-/* 8036DB18 4BFFFF1D */ bl func_8036da34
-/* 8036DB1C 7FE3FB78 */ mr r3, r31
-/* 8036DB20 48000FDD */ bl func_8036eafc
-/* 8036DB24 80010014 */ lwz r0, 0x14(r1)
-/* 8036DB28 83E1000C */ lwz r31, 0xc(r1)
-/* 8036DB2C 38210010 */ addi r1, r1, 0x10
-/* 8036DB30 7C0803A6 */ mtlr r0
-/* 8036DB34 4E800020 */ blr
-.size func_8036db00, . - func_8036db00
-
-
-.global func_8036db38
-.type func_8036db38, @function
-func_8036db38:
-/* 8036DB38 3C60E000 */ lis r3, 0xe000
-/* 8036DB3C 38800200 */ li r4, 0x200
-/* 8036DB40 7C8903A6 */ mtctr r4
-lbl_8036db44:
-/* 8036DB44 7C001BAC */ dcbi 0, r3
-/* 8036DB48 38630020 */ addi r3, r3, 0x20
-/* 8036DB4C 4200FFF8 */ bdnz lbl_8036db44
-/* 8036DB50 7C98E2A6 */ mfspr r4, 0x398
-/* 8036DB54 54840104 */ rlwinm r4, r4, 0, 4, 2
-/* 8036DB58 7C98E3A6 */ mtspr 0x398, r4
-/* 8036DB5C 4E800020 */ blr
-.size func_8036db38, . - func_8036db38
-
-
-.global func_8036db60
-.type func_8036db60, @function
-func_8036db60:
-/* 8036DB60 7C0802A6 */ mflr r0
-/* 8036DB64 90010004 */ stw r0, 4(r1)
-/* 8036DB68 9421FFF0 */ stwu r1, -0x10(r1)
-/* 8036DB6C 93E1000C */ stw r31, 0xc(r1)
-/* 8036DB70 7C0004AC */ sync 0
-/* 8036DB74 4BFFE625 */ bl func_8036c198
-/* 8036DB78 5463007E */ clrlwi r3, r3, 1
-/* 8036DB7C 4BFFE625 */ bl func_8036c1a0
-/* 8036DB80 7C0004AC */ sync 0
-/* 8036DB84 4BFFE615 */ bl func_8036c198
-/* 8036DB88 64630020 */ oris r3, r3, 0x20
-/* 8036DB8C 4BFFE615 */ bl func_8036c1a0
-/* 8036DB90 48000004 */ b lbl_8036db94
-lbl_8036db94:
-/* 8036DB94 48000004 */ b lbl_8036db98
-lbl_8036db98:
-/* 8036DB98 4BFFE601 */ bl func_8036c198
-/* 8036DB9C 546007FE */ clrlwi r0, r3, 0x1f
-/* 8036DBA0 28000000 */ cmplwi r0, 0
-/* 8036DBA4 4082FFF4 */ bne+ lbl_8036db98
-/* 8036DBA8 4BFFE5F1 */ bl func_8036c198
-/* 8036DBAC 546302D2 */ rlwinm r3, r3, 0, 0xb, 9
-/* 8036DBB0 4BFFE5F1 */ bl func_8036c1a0
-/* 8036DBB4 48000004 */ b lbl_8036dbb8
-lbl_8036dbb8:
-/* 8036DBB8 3C60804F */ lis r3, lbl_804eedf0@ha
-/* 8036DBBC 3BE3EDF0 */ addi r31, r3, lbl_804eedf0@l
-/* 8036DBC0 48000004 */ b lbl_8036dbc4
-lbl_8036dbc4:
-/* 8036DBC4 48000010 */ b lbl_8036dbd4
-lbl_8036dbc8:
-/* 8036DBC8 7FE3FB78 */ mr r3, r31
-/* 8036DBCC 4CC63182 */ crclr 6
-/* 8036DBD0 4BFFE6E1 */ bl func_8036c2b0
-lbl_8036dbd4:
-/* 8036DBD4 4BFFE5C5 */ bl func_8036c198
-/* 8036DBD8 546007FE */ clrlwi r0, r3, 0x1f
-/* 8036DBDC 28000000 */ cmplwi r0, 0
-/* 8036DBE0 4082FFE8 */ bne+ lbl_8036dbc8
-/* 8036DBE4 80010014 */ lwz r0, 0x14(r1)
-/* 8036DBE8 83E1000C */ lwz r31, 0xc(r1)
-/* 8036DBEC 38210010 */ addi r1, r1, 0x10
-/* 8036DBF0 7C0803A6 */ mtlr r0
-/* 8036DBF4 4E800020 */ blr
-.size func_8036db60, . - func_8036db60
-
-
-.global func_8036dbf8
-.type func_8036dbf8, @function
-func_8036dbf8:
-/* 8036DBF8 7C0802A6 */ mflr r0
-/* 8036DBFC 90010004 */ stw r0, 4(r1)
-/* 8036DC00 9421FF80 */ stwu r1, -0x80(r1)
-/* 8036DC04 93E1007C */ stw r31, 0x7c(r1)
-/* 8036DC08 93C10078 */ stw r30, 0x78(r1)
-/* 8036DC0C 93A10074 */ stw r29, 0x74(r1)
-/* 8036DC10 40860024 */ bne- cr1, lbl_8036dc34
-/* 8036DC14 D8210028 */ stfd f1, 0x28(r1)
-/* 8036DC18 D8410030 */ stfd f2, 0x30(r1)
-/* 8036DC1C D8610038 */ stfd f3, 0x38(r1)
-/* 8036DC20 D8810040 */ stfd f4, 0x40(r1)
-/* 8036DC24 D8A10048 */ stfd f5, 0x48(r1)
-/* 8036DC28 D8C10050 */ stfd f6, 0x50(r1)
-/* 8036DC2C D8E10058 */ stfd f7, 0x58(r1)
-/* 8036DC30 D9010060 */ stfd f8, 0x60(r1)
-lbl_8036dc34:
-/* 8036DC34 90610008 */ stw r3, 8(r1)
-/* 8036DC38 9081000C */ stw r4, 0xc(r1)
-/* 8036DC3C 90A10010 */ stw r5, 0x10(r1)
-/* 8036DC40 90C10014 */ stw r6, 0x14(r1)
-/* 8036DC44 90E10018 */ stw r7, 0x18(r1)
-/* 8036DC48 9101001C */ stw r8, 0x1c(r1)
-/* 8036DC4C 91210020 */ stw r9, 0x20(r1)
-/* 8036DC50 91410024 */ stw r10, 0x24(r1)
-/* 8036DC54 7C9D2378 */ mr r29, r4
-/* 8036DC58 3C60804F */ lis r3, lbl_804eedf0@ha
-/* 8036DC5C 3BE3EDF0 */ addi r31, r3, lbl_804eedf0@l
-/* 8036DC60 4BFFE56D */ bl func_8036c1cc
-/* 8036DC64 7C7E1B78 */ mr r30, r3
-/* 8036DC68 4CC63182 */ crclr 6
-/* 8036DC6C 387F002C */ addi r3, r31, 0x2c
-/* 8036DC70 48000A45 */ bl func_8036e6b4
-/* 8036DC74 80BD019C */ lwz r5, 0x19c(r29)
-/* 8036DC78 7FC4F378 */ mr r4, r30
-/* 8036DC7C 387F0044 */ addi r3, r31, 0x44
-/* 8036DC80 4CC63182 */ crclr 6
-/* 8036DC84 48000A31 */ bl func_8036e6b4
-/* 8036DC88 57C00216 */ rlwinm r0, r30, 0, 8, 0xb
-/* 8036DC8C 28000000 */ cmplwi r0, 0
-/* 8036DC90 41820014 */ beq- lbl_8036dca4
-/* 8036DC94 801D019C */ lwz r0, 0x19c(r29)
-/* 8036DC98 54000294 */ rlwinm r0, r0, 0, 0xa, 0xa
-/* 8036DC9C 28000000 */ cmplwi r0, 0
-/* 8036DCA0 4082001C */ bne- lbl_8036dcbc
-lbl_8036dca4:
-/* 8036DCA4 387F0060 */ addi r3, r31, 0x60
-/* 8036DCA8 4CC63182 */ crclr 6
-/* 8036DCAC 48000A09 */ bl func_8036e6b4
-/* 8036DCB0 7FA3EB78 */ mr r3, r29
-/* 8036DCB4 4800068D */ bl func_8036e340
-/* 8036DCB8 4BFFE501 */ bl func_8036c1b8
-lbl_8036dcbc:
-/* 8036DCBC 387F0090 */ addi r3, r31, 0x90
-/* 8036DCC0 4CC63182 */ crclr 6
-/* 8036DCC4 480009F1 */ bl func_8036e6b4
-/* 8036DCC8 387F00CC */ addi r3, r31, 0xcc
-/* 8036DCCC 4CC63182 */ crclr 6
-/* 8036DCD0 480009E5 */ bl func_8036e6b4
-/* 8036DCD4 57C00210 */ rlwinm r0, r30, 0, 8, 8
-/* 8036DCD8 28000000 */ cmplwi r0, 0
-/* 8036DCDC 41820010 */ beq- lbl_8036dcec
-/* 8036DCE0 387F0104 */ addi r3, r31, 0x104
-/* 8036DCE4 4CC63182 */ crclr 6
-/* 8036DCE8 480009CD */ bl func_8036e6b4
-lbl_8036dcec:
-/* 8036DCEC 57C00252 */ rlwinm r0, r30, 0, 9, 9
-/* 8036DCF0 28000000 */ cmplwi r0, 0
-/* 8036DCF4 41820010 */ beq- lbl_8036dd04
-/* 8036DCF8 387F0144 */ addi r3, r31, 0x144
-/* 8036DCFC 4CC63182 */ crclr 6
-/* 8036DD00 480009B5 */ bl func_8036e6b4
-lbl_8036dd04:
-/* 8036DD04 57C00294 */ rlwinm r0, r30, 0, 0xa, 0xa
-/* 8036DD08 28000000 */ cmplwi r0, 0
-/* 8036DD0C 41820010 */ beq- lbl_8036dd1c
-/* 8036DD10 387F0170 */ addi r3, r31, 0x170
-/* 8036DD14 4CC63182 */ crclr 6
-/* 8036DD18 4800099D */ bl func_8036e6b4
-lbl_8036dd1c:
-/* 8036DD1C 57C002D6 */ rlwinm r0, r30, 0, 0xb, 0xb
-/* 8036DD20 28000000 */ cmplwi r0, 0
-/* 8036DD24 41820010 */ beq- lbl_8036dd34
-/* 8036DD28 387F0190 */ addi r3, r31, 0x190
-/* 8036DD2C 4CC63182 */ crclr 6
-/* 8036DD30 48000985 */ bl func_8036e6b4
-lbl_8036dd34:
-/* 8036DD34 7FC3F378 */ mr r3, r30
-/* 8036DD38 4BFFE49D */ bl func_8036c1d4
-/* 8036DD3C 80010084 */ lwz r0, 0x84(r1)
-/* 8036DD40 83E1007C */ lwz r31, 0x7c(r1)
-/* 8036DD44 83C10078 */ lwz r30, 0x78(r1)
-/* 8036DD48 83A10074 */ lwz r29, 0x74(r1)
-/* 8036DD4C 38210080 */ addi r1, r1, 0x80
-/* 8036DD50 7C0803A6 */ mtlr r0
-/* 8036DD54 4E800020 */ blr
-.size func_8036dbf8, . - func_8036dbf8
-
-
-.global func_8036dd58
-.type func_8036dd58, @function
-func_8036dd58:
-/* 8036DD58 7C0802A6 */ mflr r0
-/* 8036DD5C 90010004 */ stw r0, 4(r1)
-/* 8036DD60 9421FFF0 */ stwu r1, -0x10(r1)
-/* 8036DD64 93E1000C */ stw r31, 0xc(r1)
-/* 8036DD68 93C10008 */ stw r30, 8(r1)
-/* 8036DD6C 3C60804F */ lis r3, lbl_804eedf0@ha
-/* 8036DD70 3BE3EDF0 */ addi r31, r3, lbl_804eedf0@l
-/* 8036DD74 4BFFE415 */ bl func_8036c188
-/* 8036DD78 54600420 */ rlwinm r0, r3, 0, 0x10, 0x10
-/* 8036DD7C 28000000 */ cmplwi r0, 0
-/* 8036DD80 40820014 */ bne- lbl_8036dd94
-/* 8036DD84 4BFFFC9D */ bl func_8036da20
-/* 8036DD88 387F01AC */ addi r3, r31, 0x1ac
-/* 8036DD8C 4CC63182 */ crclr 6
-/* 8036DD90 4BFFE521 */ bl func_8036c2b0
-lbl_8036dd94:
-/* 8036DD94 4BFFE3F5 */ bl func_8036c188
-/* 8036DD98 54600462 */ rlwinm r0, r3, 0, 0x11, 0x11
-/* 8036DD9C 28000000 */ cmplwi r0, 0
-/* 8036DDA0 40820014 */ bne- lbl_8036ddb4
-/* 8036DDA4 4BFFFB29 */ bl func_8036d8cc
-/* 8036DDA8 387F01C8 */ addi r3, r31, 0x1c8
-/* 8036DDAC 4CC63182 */ crclr 6
-/* 8036DDB0 4BFFE501 */ bl func_8036c2b0
-lbl_8036ddb4:
-/* 8036DDB4 4BFFE3E5 */ bl func_8036c198
-/* 8036DDB8 54600000 */ rlwinm r0, r3, 0, 0, 0
-/* 8036DDBC 28000000 */ cmplwi r0, 0
-/* 8036DDC0 40820058 */ bne- lbl_8036de18
-/* 8036DDC4 4BFFE3B5 */ bl func_8036c178
-/* 8036DDC8 7C7E1B78 */ mr r30, r3
-/* 8036DDCC 7C0004AC */ sync 0
-/* 8036DDD0 38600030 */ li r3, 0x30
-/* 8036DDD4 4BFFE3AD */ bl func_8036c180
-/* 8036DDD8 7C0004AC */ sync 0
-/* 8036DDDC 7C0004AC */ sync 0
-/* 8036DDE0 4BFFE3B9 */ bl func_8036c198
-/* 8036DDE4 5463007E */ clrlwi r3, r3, 1
-/* 8036DDE8 4BFFE3B9 */ bl func_8036c1a0
-/* 8036DDEC 7C0004AC */ sync 0
-/* 8036DDF0 4BFFFD71 */ bl func_8036db60
-/* 8036DDF4 7FC3F378 */ mr r3, r30
-/* 8036DDF8 4BFFE389 */ bl func_8036c180
-/* 8036DDFC 4BFFE39D */ bl func_8036c198
-/* 8036DE00 64608000 */ oris r0, r3, 0x8000
-/* 8036DE04 540302D2 */ rlwinm r3, r0, 0, 0xb, 9
-/* 8036DE08 4BFFE399 */ bl func_8036c1a0
-/* 8036DE0C 387F01E4 */ addi r3, r31, 0x1e4
-/* 8036DE10 4CC63182 */ crclr 6
-/* 8036DE14 4BFFE49D */ bl func_8036c2b0
-lbl_8036de18:
-/* 8036DE18 3C608037 */ lis r3, func_8036dbf8@ha
-/* 8036DE1C 3883DBF8 */ addi r4, r3, func_8036dbf8@l
-/* 8036DE20 38600001 */ li r3, 0x1
-/* 8036DE24 48000A3D */ bl func_8036e860
-/* 8036DE28 387F01FC */ addi r3, r31, 0x1fc
-/* 8036DE2C 4CC63182 */ crclr 6
-/* 8036DE30 4BFFE481 */ bl func_8036c2b0
-/* 8036DE34 80010014 */ lwz r0, 0x14(r1)
-/* 8036DE38 83E1000C */ lwz r31, 0xc(r1)
-/* 8036DE3C 83C10008 */ lwz r30, 8(r1)
-/* 8036DE40 38210010 */ addi r1, r1, 0x10
-/* 8036DE44 7C0803A6 */ mtlr r0
-/* 8036DE48 4E800020 */ blr
-.size func_8036dd58, . - func_8036dd58
-
diff --git a/asm/Dolphin/os/OSContext-data.s b/asm/Dolphin/os/OSContext-data.s
deleted file mode 100644
index 087b4a0..0000000
--- a/asm/Dolphin/os/OSContext-data.s
+++ /dev/null
@@ -1,135 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804ef020
-.type lbl_804ef020, @object
-lbl_804ef020:
-/* 804EF020 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF024 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF028 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF02C 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF030 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF034 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF038 2D20436F */ .4byte 0x2d20436f
-/* 804EF03C 6E746578 */ .4byte 0x6e746578
-/* 804EF040 74203078 */ .4byte 0x74203078
-/* 804EF044 25303878 */ .4byte 0x25303878
-/* 804EF048 202D2D2D */ .4byte 0x202d2d2d
-/* 804EF04C 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF050 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF054 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF058 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF05C 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF060 2D2D0A00 */ .4byte 0x2d2d0a00
-/* 804EF064 72252D32 */ .4byte 0x72252d32
-/* 804EF068 6420203D */ .4byte 0x6420203d
-/* 804EF06C 20307825 */ .4byte 0x20307825
-/* 804EF070 30387820 */ .4byte 0x30387820
-/* 804EF074 28253134 */ .4byte 0x28253134
-/* 804EF078 64292020 */ .4byte 0x64292020
-/* 804EF07C 72252D32 */ .4byte 0x72252d32
-/* 804EF080 6420203D */ .4byte 0x6420203d
-/* 804EF084 20307825 */ .4byte 0x20307825
-/* 804EF088 30387820 */ .4byte 0x30387820
-/* 804EF08C 28253134 */ .4byte 0x28253134
-/* 804EF090 64290A00 */ .4byte 0x64290a00
-/* 804EF094 4C522020 */ .4byte 0x4c522020
-/* 804EF098 203D2030 */ .4byte 0x203d2030
-/* 804EF09C 78253038 */ .4byte 0x78253038
-/* 804EF0A0 78202020 */ .4byte 0x78202020
-/* 804EF0A4 20202020 */ .4byte 0x20202020
-/* 804EF0A8 20202020 */ .4byte 0x20202020
-/* 804EF0AC 20202020 */ .4byte 0x20202020
-/* 804EF0B0 20202020 */ .4byte 0x20202020
-/* 804EF0B4 43522020 */ .4byte 0x43522020
-/* 804EF0B8 203D2030 */ .4byte 0x203d2030
-/* 804EF0BC 78253038 */ .4byte 0x78253038
-/* 804EF0C0 780A0000 */ .4byte 0x780a0000
-/* 804EF0C4 53525230 */ .4byte 0x53525230
-/* 804EF0C8 203D2030 */ .4byte 0x203d2030
-/* 804EF0CC 78253038 */ .4byte 0x78253038
-/* 804EF0D0 78202020 */ .4byte 0x78202020
-/* 804EF0D4 20202020 */ .4byte 0x20202020
-/* 804EF0D8 20202020 */ .4byte 0x20202020
-/* 804EF0DC 20202020 */ .4byte 0x20202020
-/* 804EF0E0 20202020 */ .4byte 0x20202020
-/* 804EF0E4 53525231 */ .4byte 0x53525231
-/* 804EF0E8 203D2030 */ .4byte 0x203d2030
-/* 804EF0EC 78253038 */ .4byte 0x78253038
-/* 804EF0F0 780A0000 */ .4byte 0x780a0000
-/* 804EF0F4 0A475152 */ .4byte 0x0a475152
-/* 804EF0F8 732D2D2D */ .4byte 0x732d2d2d
-/* 804EF0FC 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF100 2D2D2D0A */ .4byte 0x2d2d2d0a
-/* 804EF104 00000000 */ .4byte 0x00000000
-/* 804EF108 67717225 */ .4byte 0x67717225
-/* 804EF10C 64203D20 */ .4byte 0x64203d20
-/* 804EF110 30782530 */ .4byte 0x30782530
-/* 804EF114 38782009 */ .4byte 0x38782009
-/* 804EF118 20677172 */ .4byte 0x20677172
-/* 804EF11C 2564203D */ .4byte 0x2564203d
-/* 804EF120 20307825 */ .4byte 0x20307825
-/* 804EF124 3038780A */ .4byte 0x3038780a
-/* 804EF128 00000000 */ .4byte 0x00000000
-/* 804EF12C 0A0A4650 */ .4byte 0x0a0a4650
-/* 804EF130 52732D2D */ .4byte 0x52732d2d
-/* 804EF134 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF138 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF13C 0A000000 */ .4byte 0x0a000000
-/* 804EF140 66722564 */ .4byte 0x66722564
-/* 804EF144 20093D20 */ .4byte 0x20093d20
-/* 804EF148 25642009 */ .4byte 0x25642009
-/* 804EF14C 20667225 */ .4byte 0x20667225
-/* 804EF150 6420093D */ .4byte 0x6420093d
-/* 804EF154 2025640A */ .4byte 0x2025640a
-/* 804EF158 00000000 */ .4byte 0x00000000
-/* 804EF15C 0A0A5053 */ .4byte 0x0a0a5053
-/* 804EF160 46732D2D */ .4byte 0x46732d2d
-/* 804EF164 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF168 2D2D2D2D */ .4byte 0x2d2d2d2d
-/* 804EF16C 0A000000 */ .4byte 0x0a000000
-/* 804EF170 70732564 */ .4byte 0x70732564
-/* 804EF174 20093D20 */ .4byte 0x20093d20
-/* 804EF178 30782578 */ .4byte 0x30782578
-/* 804EF17C 20092070 */ .4byte 0x20092070
-/* 804EF180 73256420 */ .4byte 0x73256420
-/* 804EF184 093D2030 */ .4byte 0x093d2030
-/* 804EF188 7825780A */ .4byte 0x7825780a
-/* 804EF18C 00000000 */ .4byte 0x00000000
-/* 804EF190 0A416464 */ .4byte 0x0a416464
-/* 804EF194 72657373 */ .4byte 0x72657373
-/* 804EF198 3A202020 */ .4byte 0x3a202020
-/* 804EF19C 20202042 */ .4byte 0x20202042
-/* 804EF1A0 61636B20 */ .4byte 0x61636b20
-/* 804EF1A4 43686169 */ .4byte 0x43686169
-/* 804EF1A8 6E202020 */ .4byte 0x6e202020
-/* 804EF1AC 204C5220 */ .4byte 0x204c5220
-/* 804EF1B0 53617665 */ .4byte 0x53617665
-/* 804EF1B4 0A000000 */ .4byte 0x0a000000
-/* 804EF1B8 30782530 */ .4byte 0x30782530
-/* 804EF1BC 38783A20 */ .4byte 0x38783a20
-/* 804EF1C0 20203078 */ .4byte 0x20203078
-/* 804EF1C4 25303878 */ .4byte 0x25303878
-/* 804EF1C8 20202020 */ .4byte 0x20202020
-/* 804EF1CC 30782530 */ .4byte 0x30782530
-/* 804EF1D0 38780A00 */ .4byte 0x38780a00
-.size lbl_804ef020, . - lbl_804ef020
-
-
-.global lbl_804ef1d4
-.type lbl_804ef1d4, @object
-lbl_804ef1d4:
-/* 804EF1D4 4650552D */ .4byte 0x4650552d
-/* 804EF1D8 756E6176 */ .4byte 0x756e6176
-/* 804EF1DC 61696C61 */ .4byte 0x61696c61
-/* 804EF1E0 626C6520 */ .4byte 0x626c6520
-/* 804EF1E4 68616E64 */ .4byte 0x68616e64
-/* 804EF1E8 6C657220 */ .4byte 0x6c657220
-/* 804EF1EC 696E7374 */ .4byte 0x696e7374
-/* 804EF1F0 616C6C65 */ .4byte 0x616c6c65
-/* 804EF1F4 640A0000 */ .4byte 0x640a0000
-.size lbl_804ef1d4, . - lbl_804ef1d4
-
diff --git a/asm/Dolphin/os/OSContext.s b/asm/Dolphin/os/OSContext.s
deleted file mode 100644
index 23fa01a..0000000
--- a/asm/Dolphin/os/OSContext.s
+++ /dev/null
@@ -1,643 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036de4c
-.type func_8036de4c, @function
-func_8036de4c:
-/* 8036DE4C A0A401A2 */ lhz r5, 0x1a2(r4)
-/* 8036DE50 54A507FF */ clrlwi. r5, r5, 0x1f
-/* 8036DE54 41820118 */ beq- lbl_8036df6c
-/* 8036DE58 C8040190 */ lfd f0, 0x190(r4)
-/* 8036DE5C FDFE058E */ mtfsf 0xff, f0
-/* 8036DE60 7CB8E2A6 */ mfspr r5, 0x398
-/* 8036DE64 54A51FFF */ rlwinm. r5, r5, 3, 0x1f, 0x1f
-/* 8036DE68 41820084 */ beq- lbl_8036deec
-/* 8036DE6C E00401C8 */ .4byte 0xe00401c8
-/* 8036DE70 E02401D0 */ .4byte 0xe02401d0
-/* 8036DE74 E04401D8 */ .4byte 0xe04401d8
-/* 8036DE78 E06401E0 */ .4byte 0xe06401e0
-/* 8036DE7C E08401E8 */ .4byte 0xe08401e8
-/* 8036DE80 E0A401F0 */ .4byte 0xe0a401f0
-/* 8036DE84 E0C401F8 */ .4byte 0xe0c401f8
-/* 8036DE88 E0E40200 */ .4byte 0xe0e40200
-/* 8036DE8C E1040208 */ .4byte 0xe1040208
-/* 8036DE90 E1240210 */ .4byte 0xe1240210
-/* 8036DE94 E1440218 */ .4byte 0xe1440218
-/* 8036DE98 E1640220 */ .4byte 0xe1640220
-/* 8036DE9C E1840228 */ .4byte 0xe1840228
-/* 8036DEA0 E1A40230 */ .4byte 0xe1a40230
-/* 8036DEA4 E1C40238 */ .4byte 0xe1c40238
-/* 8036DEA8 E1E40240 */ .4byte 0xe1e40240
-/* 8036DEAC E2040248 */ .4byte 0xe2040248
-/* 8036DEB0 E2240250 */ .4byte 0xe2240250
-/* 8036DEB4 E2440258 */ .4byte 0xe2440258
-/* 8036DEB8 E2640260 */ .4byte 0xe2640260
-/* 8036DEBC E2840268 */ .4byte 0xe2840268
-/* 8036DEC0 E2A40270 */ .4byte 0xe2a40270
-/* 8036DEC4 E2C40278 */ .4byte 0xe2c40278
-/* 8036DEC8 E2E40280 */ .4byte 0xe2e40280
-/* 8036DECC E3040288 */ .4byte 0xe3040288
-/* 8036DED0 E3240290 */ .4byte 0xe3240290
-/* 8036DED4 E3440298 */ .4byte 0xe3440298
-/* 8036DED8 E36402A0 */ .4byte 0xe36402a0
-/* 8036DEDC E38402A8 */ .4byte 0xe38402a8
-/* 8036DEE0 E3A402B0 */ .4byte 0xe3a402b0
-/* 8036DEE4 E3C402B8 */ .4byte 0xe3c402b8
-/* 8036DEE8 E3E402C0 */ .4byte 0xe3e402c0
-lbl_8036deec:
-/* 8036DEEC C8040090 */ lfd f0, 0x90(r4)
-/* 8036DEF0 C8240098 */ lfd f1, 0x98(r4)
-/* 8036DEF4 C84400A0 */ lfd f2, 0xa0(r4)
-/* 8036DEF8 C86400A8 */ lfd f3, 0xa8(r4)
-/* 8036DEFC C88400B0 */ lfd f4, 0xb0(r4)
-/* 8036DF00 C8A400B8 */ lfd f5, 0xb8(r4)
-/* 8036DF04 C8C400C0 */ lfd f6, 0xc0(r4)
-/* 8036DF08 C8E400C8 */ lfd f7, 0xc8(r4)
-/* 8036DF0C C90400D0 */ lfd f8, 0xd0(r4)
-/* 8036DF10 C92400D8 */ lfd f9, 0xd8(r4)
-/* 8036DF14 C94400E0 */ lfd f10, 0xe0(r4)
-/* 8036DF18 C96400E8 */ lfd f11, 0xe8(r4)
-/* 8036DF1C C98400F0 */ lfd f12, 0xf0(r4)
-/* 8036DF20 C9A400F8 */ lfd f13, 0xf8(r4)
-/* 8036DF24 C9C40100 */ lfd f14, 0x100(r4)
-/* 8036DF28 C9E40108 */ lfd f15, 0x108(r4)
-/* 8036DF2C CA040110 */ lfd f16, 0x110(r4)
-/* 8036DF30 CA240118 */ lfd f17, 0x118(r4)
-/* 8036DF34 CA440120 */ lfd f18, 0x120(r4)
-/* 8036DF38 CA640128 */ lfd f19, 0x128(r4)
-/* 8036DF3C CA840130 */ lfd f20, 0x130(r4)
-/* 8036DF40 CAA40138 */ lfd f21, 0x138(r4)
-/* 8036DF44 CAC40140 */ lfd f22, 0x140(r4)
-/* 8036DF48 CAE40148 */ lfd f23, 0x148(r4)
-/* 8036DF4C CB040150 */ lfd f24, 0x150(r4)
-/* 8036DF50 CB240158 */ lfd f25, 0x158(r4)
-/* 8036DF54 CB440160 */ lfd f26, 0x160(r4)
-/* 8036DF58 CB640168 */ lfd f27, 0x168(r4)
-/* 8036DF5C CB840170 */ lfd f28, 0x170(r4)
-/* 8036DF60 CBA40178 */ lfd f29, 0x178(r4)
-/* 8036DF64 CBC40180 */ lfd f30, 0x180(r4)
-/* 8036DF68 CBE40188 */ lfd f31, 0x188(r4)
-lbl_8036df6c:
-/* 8036DF6C 4E800020 */ blr
-.size func_8036de4c, . - func_8036de4c
-
-
-.global func_8036df70
-.type func_8036df70, @function
-func_8036df70:
-/* 8036DF70 A06501A2 */ lhz r3, 0x1a2(r5)
-/* 8036DF74 60630001 */ ori r3, r3, 1
-/* 8036DF78 B06501A2 */ sth r3, 0x1a2(r5)
-/* 8036DF7C D8050090 */ stfd f0, 0x90(r5)
-/* 8036DF80 D8250098 */ stfd f1, 0x98(r5)
-/* 8036DF84 D84500A0 */ stfd f2, 0xa0(r5)
-/* 8036DF88 D86500A8 */ stfd f3, 0xa8(r5)
-/* 8036DF8C D88500B0 */ stfd f4, 0xb0(r5)
-/* 8036DF90 D8A500B8 */ stfd f5, 0xb8(r5)
-/* 8036DF94 D8C500C0 */ stfd f6, 0xc0(r5)
-/* 8036DF98 D8E500C8 */ stfd f7, 0xc8(r5)
-/* 8036DF9C D90500D0 */ stfd f8, 0xd0(r5)
-/* 8036DFA0 D92500D8 */ stfd f9, 0xd8(r5)
-/* 8036DFA4 D94500E0 */ stfd f10, 0xe0(r5)
-/* 8036DFA8 D96500E8 */ stfd f11, 0xe8(r5)
-/* 8036DFAC D98500F0 */ stfd f12, 0xf0(r5)
-/* 8036DFB0 D9A500F8 */ stfd f13, 0xf8(r5)
-/* 8036DFB4 D9C50100 */ stfd f14, 0x100(r5)
-/* 8036DFB8 D9E50108 */ stfd f15, 0x108(r5)
-/* 8036DFBC DA050110 */ stfd f16, 0x110(r5)
-/* 8036DFC0 DA250118 */ stfd f17, 0x118(r5)
-/* 8036DFC4 DA450120 */ stfd f18, 0x120(r5)
-/* 8036DFC8 DA650128 */ stfd f19, 0x128(r5)
-/* 8036DFCC DA850130 */ stfd f20, 0x130(r5)
-/* 8036DFD0 DAA50138 */ stfd f21, 0x138(r5)
-/* 8036DFD4 DAC50140 */ stfd f22, 0x140(r5)
-/* 8036DFD8 DAE50148 */ stfd f23, 0x148(r5)
-/* 8036DFDC DB050150 */ stfd f24, 0x150(r5)
-/* 8036DFE0 DB250158 */ stfd f25, 0x158(r5)
-/* 8036DFE4 DB450160 */ stfd f26, 0x160(r5)
-/* 8036DFE8 DB650168 */ stfd f27, 0x168(r5)
-/* 8036DFEC DB850170 */ stfd f28, 0x170(r5)
-/* 8036DFF0 DBA50178 */ stfd f29, 0x178(r5)
-/* 8036DFF4 DBC50180 */ stfd f30, 0x180(r5)
-/* 8036DFF8 DBE50188 */ stfd f31, 0x188(r5)
-/* 8036DFFC FC00048E */ mffs f0
-/* 8036E000 D8050190 */ stfd f0, 0x190(r5)
-/* 8036E004 C8050090 */ lfd f0, 0x90(r5)
-/* 8036E008 7C78E2A6 */ mfspr r3, 0x398
-/* 8036E00C 54631FFF */ rlwinm. r3, r3, 3, 0x1f, 0x1f
-/* 8036E010 41820084 */ beq- lbl_8036e094
-/* 8036E014 F00501C8 */ .4byte 0xf00501c8
-/* 8036E018 F02501D0 */ .4byte 0xf02501d0
-/* 8036E01C F04501D8 */ .4byte 0xf04501d8
-/* 8036E020 F06501E0 */ .4byte 0xf06501e0
-/* 8036E024 F08501E8 */ .4byte 0xf08501e8
-/* 8036E028 F0A501F0 */ .4byte 0xf0a501f0
-/* 8036E02C F0C501F8 */ .4byte 0xf0c501f8
-/* 8036E030 F0E50200 */ .4byte 0xf0e50200
-/* 8036E034 F1050208 */ .4byte 0xf1050208
-/* 8036E038 F1250210 */ .4byte 0xf1250210
-/* 8036E03C F1450218 */ .4byte 0xf1450218
-/* 8036E040 F1650220 */ .4byte 0xf1650220
-/* 8036E044 F1850228 */ .4byte 0xf1850228
-/* 8036E048 F1A50230 */ .4byte 0xf1a50230
-/* 8036E04C F1C50238 */ .4byte 0xf1c50238
-/* 8036E050 F1E50240 */ .4byte 0xf1e50240
-/* 8036E054 F2050248 */ .4byte 0xf2050248
-/* 8036E058 F2250250 */ .4byte 0xf2250250
-/* 8036E05C F2450258 */ .4byte 0xf2450258
-/* 8036E060 F2650260 */ .4byte 0xf2650260
-/* 8036E064 F2850268 */ .4byte 0xf2850268
-/* 8036E068 F2A50270 */ .4byte 0xf2a50270
-/* 8036E06C F2C50278 */ .4byte 0xf2c50278
-/* 8036E070 F2E50280 */ .4byte 0xf2e50280
-/* 8036E074 F3050288 */ .4byte 0xf3050288
-/* 8036E078 F3250290 */ .4byte 0xf3250290
-/* 8036E07C F3450298 */ .4byte 0xf3450298
-/* 8036E080 F36502A0 */ .4byte 0xf36502a0
-/* 8036E084 F38502A8 */ .4byte 0xf38502a8
-/* 8036E088 F3A502B0 */ .4byte 0xf3a502b0
-/* 8036E08C F3C502B8 */ .4byte 0xf3c502b8
-/* 8036E090 F3E502C0 */ .4byte 0xf3e502c0
-lbl_8036e094:
-/* 8036E094 4E800020 */ blr
-.size func_8036df70, . - func_8036df70
-
-
-.global func_8036e098
-.type func_8036e098, @function
-func_8036e098:
-/* 8036E098 3C808000 */ lis r4, 0x8000
-/* 8036E09C 906400D4 */ stw r3, 0xd4(r4)
-/* 8036E0A0 546500BE */ clrlwi r5, r3, 2
-/* 8036E0A4 90A400C0 */ stw r5, 0xc0(r4)
-/* 8036E0A8 80A400D8 */ lwz r5, 0xd8(r4)
-/* 8036E0AC 7C051800 */ cmpw r5, r3
-/* 8036E0B0 40820020 */ bne- lbl_8036e0d0
-/* 8036E0B4 80C3019C */ lwz r6, 0x19c(r3)
-/* 8036E0B8 60C62000 */ ori r6, r6, 0x2000
-/* 8036E0BC 90C3019C */ stw r6, 0x19c(r3)
-/* 8036E0C0 7CC000A6 */ mfmsr r6
-/* 8036E0C4 60C60002 */ ori r6, r6, 2
-/* 8036E0C8 7CC00124 */ mtmsr r6
-/* 8036E0CC 4E800020 */ blr
-lbl_8036e0d0:
-/* 8036E0D0 80C3019C */ lwz r6, 0x19c(r3)
-/* 8036E0D4 54C604E2 */ rlwinm r6, r6, 0, 0x13, 0x11
-/* 8036E0D8 90C3019C */ stw r6, 0x19c(r3)
-/* 8036E0DC 7CC000A6 */ mfmsr r6
-/* 8036E0E0 54C604E2 */ rlwinm r6, r6, 0, 0x13, 0x11
-/* 8036E0E4 60C60002 */ ori r6, r6, 2
-/* 8036E0E8 7CC00124 */ mtmsr r6
-/* 8036E0EC 4C00012C */ isync
-/* 8036E0F0 4E800020 */ blr
-.size func_8036e098, . - func_8036e098
-
-
-.global func_8036e0f4
-.type func_8036e0f4, @function
-func_8036e0f4:
-/* 8036E0F4 3C608000 */ lis r3, 0x8000
-/* 8036E0F8 806300D4 */ lwz r3, 0xd4(r3)
-/* 8036E0FC 4E800020 */ blr
-.size func_8036e0f4, . - func_8036e0f4
-
-
-.global func_8036e100
-.type func_8036e100, @function
-func_8036e100:
-/* 8036E100 BDA30034 */ stmw r13, 0x34(r3)
-/* 8036E104 7C11E2A6 */ mfspr r0, 0x391
-/* 8036E108 900301A8 */ stw r0, 0x1a8(r3)
-/* 8036E10C 7C12E2A6 */ mfspr r0, 0x392
-/* 8036E110 900301AC */ stw r0, 0x1ac(r3)
-/* 8036E114 7C13E2A6 */ mfspr r0, 0x393
-/* 8036E118 900301B0 */ stw r0, 0x1b0(r3)
-/* 8036E11C 7C14E2A6 */ mfspr r0, 0x394
-/* 8036E120 900301B4 */ stw r0, 0x1b4(r3)
-/* 8036E124 7C15E2A6 */ mfspr r0, 0x395
-/* 8036E128 900301B8 */ stw r0, 0x1b8(r3)
-/* 8036E12C 7C16E2A6 */ mfspr r0, 0x396
-/* 8036E130 900301BC */ stw r0, 0x1bc(r3)
-/* 8036E134 7C17E2A6 */ mfspr r0, 0x397
-/* 8036E138 900301C0 */ stw r0, 0x1c0(r3)
-/* 8036E13C 7C000026 */ mfcr r0
-/* 8036E140 90030080 */ stw r0, 0x80(r3)
-/* 8036E144 7C0802A6 */ mflr r0
-/* 8036E148 90030084 */ stw r0, 0x84(r3)
-/* 8036E14C 90030198 */ stw r0, 0x198(r3)
-/* 8036E150 7C0000A6 */ mfmsr r0
-/* 8036E154 9003019C */ stw r0, 0x19c(r3)
-/* 8036E158 7C0902A6 */ mfctr r0
-/* 8036E15C 90030088 */ stw r0, 0x88(r3)
-/* 8036E160 7C0102A6 */ mfxer r0
-/* 8036E164 9003008C */ stw r0, 0x8c(r3)
-/* 8036E168 90230004 */ stw r1, 4(r3)
-/* 8036E16C 90430008 */ stw r2, 8(r3)
-/* 8036E170 38000001 */ li r0, 0x1
-/* 8036E174 9003000C */ stw r0, 0xc(r3)
-/* 8036E178 38600000 */ li r3, 0x0
-/* 8036E17C 4E800020 */ blr
-.size func_8036e100, . - func_8036e100
-
-
-.global func_8036e180
-.type func_8036e180, @function
-func_8036e180:
-/* 8036E180 3C808037 */ lis r4, func_8036ead4@ha
-/* 8036E184 80C30198 */ lwz r6, 0x198(r3)
-/* 8036E188 38A4EAD4 */ addi r5, r4, func_8036ead4@l
-/* 8036E18C 7C062840 */ cmplw r6, r5
-/* 8036E190 41800018 */ blt- lbl_8036e1a8
-/* 8036E194 3C808037 */ lis r4, func_8036eae4@ha
-/* 8036E198 3804EAE4 */ addi r0, r4, func_8036eae4@l
-/* 8036E19C 7C060040 */ cmplw r6, r0
-/* 8036E1A0 41810008 */ bgt- lbl_8036e1a8
-/* 8036E1A4 90A30198 */ stw r5, 0x198(r3)
-lbl_8036e1a8:
-/* 8036E1A8 80030000 */ lwz r0, 0(r3)
-/* 8036E1AC 80230004 */ lwz r1, 4(r3)
-/* 8036E1B0 80430008 */ lwz r2, 8(r3)
-/* 8036E1B4 A08301A2 */ lhz r4, 0x1a2(r3)
-/* 8036E1B8 548507BD */ rlwinm. r5, r4, 0, 0x1e, 0x1e
-/* 8036E1BC 41820014 */ beq- lbl_8036e1d0
-/* 8036E1C0 548407FA */ rlwinm r4, r4, 0, 0x1f, 0x1d
-/* 8036E1C4 B08301A2 */ sth r4, 0x1a2(r3)
-/* 8036E1C8 B8A30014 */ lmw r5, 0x14(r3)
-/* 8036E1CC 48000008 */ b lbl_8036e1d4
-lbl_8036e1d0:
-/* 8036E1D0 B9A30034 */ lmw r13, 0x34(r3)
-lbl_8036e1d4:
-/* 8036E1D4 808301A8 */ lwz r4, 0x1a8(r3)
-/* 8036E1D8 7C91E3A6 */ mtspr 0x391, r4
-/* 8036E1DC 808301AC */ lwz r4, 0x1ac(r3)
-/* 8036E1E0 7C92E3A6 */ mtspr 0x392, r4
-/* 8036E1E4 808301B0 */ lwz r4, 0x1b0(r3)
-/* 8036E1E8 7C93E3A6 */ mtspr 0x393, r4
-/* 8036E1EC 808301B4 */ lwz r4, 0x1b4(r3)
-/* 8036E1F0 7C94E3A6 */ mtspr 0x394, r4
-/* 8036E1F4 808301B8 */ lwz r4, 0x1b8(r3)
-/* 8036E1F8 7C95E3A6 */ mtspr 0x395, r4
-/* 8036E1FC 808301BC */ lwz r4, 0x1bc(r3)
-/* 8036E200 7C96E3A6 */ mtspr 0x396, r4
-/* 8036E204 808301C0 */ lwz r4, 0x1c0(r3)
-/* 8036E208 7C97E3A6 */ mtspr 0x397, r4
-/* 8036E20C 80830080 */ lwz r4, 0x80(r3)
-/* 8036E210 7C8FF120 */ mtcrf 0xff, r4
-/* 8036E214 80830084 */ lwz r4, 0x84(r3)
-/* 8036E218 7C8803A6 */ mtlr r4
-/* 8036E21C 80830088 */ lwz r4, 0x88(r3)
-/* 8036E220 7C8903A6 */ mtctr r4
-/* 8036E224 8083008C */ lwz r4, 0x8c(r3)
-/* 8036E228 7C8103A6 */ mtxer r4
-/* 8036E22C 7C8000A6 */ mfmsr r4
-/* 8036E230 5484045E */ rlwinm r4, r4, 0, 0x11, 0xf
-/* 8036E234 548407FA */ rlwinm r4, r4, 0, 0x1f, 0x1d
-/* 8036E238 7C800124 */ mtmsr r4
-/* 8036E23C 80830198 */ lwz r4, 0x198(r3)
-/* 8036E240 7C9A03A6 */ mtspr 0x1a, r4
-/* 8036E244 8083019C */ lwz r4, 0x19c(r3)
-/* 8036E248 7C9B03A6 */ mtspr 0x1b, r4
-/* 8036E24C 80830010 */ lwz r4, 0x10(r3)
-/* 8036E250 8063000C */ lwz r3, 0xc(r3)
-/* 8036E254 4C000064 */ rfi
-.size func_8036e180, . - func_8036e180
-
-
-.global func_8036e258
-.type func_8036e258, @function
-func_8036e258:
-/* 8036E258 7C230B78 */ mr r3, r1
-/* 8036E25C 4E800020 */ blr
-.size func_8036e258, . - func_8036e258
-
-
-.global func_8036e260
-.type func_8036e260, @function
-func_8036e260:
-/* 8036E260 38A00000 */ li r5, 0x0
-/* 8036E264 B0A301A0 */ sth r5, 0x1a0(r3)
-/* 8036E268 3C808000 */ lis r4, 0x8000
-/* 8036E26C B0A301A2 */ sth r5, 0x1a2(r3)
-/* 8036E270 800400D8 */ lwz r0, 0xd8(r4)
-/* 8036E274 7C030040 */ cmplw r3, r0
-/* 8036E278 40820008 */ bne- lbl_8036e280
-/* 8036E27C 90A400D8 */ stw r5, 0xd8(r4)
-lbl_8036e280:
-/* 8036E280 4E800020 */ blr
-.size func_8036e260, . - func_8036e260
-
-
-.global func_8036e284
-.type func_8036e284, @function
-func_8036e284:
-/* 8036E284 90830198 */ stw r4, 0x198(r3)
-/* 8036E288 90A30004 */ stw r5, 4(r3)
-/* 8036E28C 39600000 */ li r11, 0x0
-/* 8036E290 616B9032 */ ori r11, r11, 0x9032
-/* 8036E294 9163019C */ stw r11, 0x19c(r3)
-/* 8036E298 38000000 */ li r0, 0x0
-/* 8036E29C 90030080 */ stw r0, 0x80(r3)
-/* 8036E2A0 9003008C */ stw r0, 0x8c(r3)
-/* 8036E2A4 90430008 */ stw r2, 8(r3)
-/* 8036E2A8 91A30034 */ stw r13, 0x34(r3)
-/* 8036E2AC 9003000C */ stw r0, 0xc(r3)
-/* 8036E2B0 90030010 */ stw r0, 0x10(r3)
-/* 8036E2B4 90030014 */ stw r0, 0x14(r3)
-/* 8036E2B8 90030018 */ stw r0, 0x18(r3)
-/* 8036E2BC 9003001C */ stw r0, 0x1c(r3)
-/* 8036E2C0 90030020 */ stw r0, 0x20(r3)
-/* 8036E2C4 90030024 */ stw r0, 0x24(r3)
-/* 8036E2C8 90030028 */ stw r0, 0x28(r3)
-/* 8036E2CC 9003002C */ stw r0, 0x2c(r3)
-/* 8036E2D0 90030030 */ stw r0, 0x30(r3)
-/* 8036E2D4 90030038 */ stw r0, 0x38(r3)
-/* 8036E2D8 9003003C */ stw r0, 0x3c(r3)
-/* 8036E2DC 90030040 */ stw r0, 0x40(r3)
-/* 8036E2E0 90030044 */ stw r0, 0x44(r3)
-/* 8036E2E4 90030048 */ stw r0, 0x48(r3)
-/* 8036E2E8 9003004C */ stw r0, 0x4c(r3)
-/* 8036E2EC 90030050 */ stw r0, 0x50(r3)
-/* 8036E2F0 90030054 */ stw r0, 0x54(r3)
-/* 8036E2F4 90030058 */ stw r0, 0x58(r3)
-/* 8036E2F8 9003005C */ stw r0, 0x5c(r3)
-/* 8036E2FC 90030060 */ stw r0, 0x60(r3)
-/* 8036E300 90030064 */ stw r0, 0x64(r3)
-/* 8036E304 90030068 */ stw r0, 0x68(r3)
-/* 8036E308 9003006C */ stw r0, 0x6c(r3)
-/* 8036E30C 90030070 */ stw r0, 0x70(r3)
-/* 8036E310 90030074 */ stw r0, 0x74(r3)
-/* 8036E314 90030078 */ stw r0, 0x78(r3)
-/* 8036E318 9003007C */ stw r0, 0x7c(r3)
-/* 8036E31C 900301A4 */ stw r0, 0x1a4(r3)
-/* 8036E320 900301A8 */ stw r0, 0x1a8(r3)
-/* 8036E324 900301AC */ stw r0, 0x1ac(r3)
-/* 8036E328 900301B0 */ stw r0, 0x1b0(r3)
-/* 8036E32C 900301B4 */ stw r0, 0x1b4(r3)
-/* 8036E330 900301B8 */ stw r0, 0x1b8(r3)
-/* 8036E334 900301BC */ stw r0, 0x1bc(r3)
-/* 8036E338 900301C0 */ stw r0, 0x1c0(r3)
-/* 8036E33C 4BFFFF24 */ b func_8036e260
-.size func_8036e284, . - func_8036e284
-
-
-.global func_8036e340
-.type func_8036e340, @function
-func_8036e340:
-/* 8036E340 7C0802A6 */ mflr r0
-/* 8036E344 90010004 */ stw r0, 4(r1)
-/* 8036E348 9421FD08 */ stwu r1, -0x2f8(r1)
-/* 8036E34C BF2102DC */ stmw r25, 0x2dc(r1)
-/* 8036E350 7C7C1B78 */ mr r28, r3
-/* 8036E354 3C60804F */ lis r3, lbl_804ef020@ha
-/* 8036E358 4CC63182 */ crclr 6
-/* 8036E35C 3BE3F020 */ addi r31, r3, lbl_804ef020@l
-/* 8036E360 7FE3FB78 */ mr r3, r31
-/* 8036E364 7F84E378 */ mr r4, r28
-/* 8036E368 4800034D */ bl func_8036e6b4
-/* 8036E36C 3B200000 */ li r25, 0x0
-/* 8036E370 5720103A */ slwi r0, r25, 2
-/* 8036E374 7F7C0214 */ add r27, r28, r0
-/* 8036E378 48000004 */ b lbl_8036e37c
-lbl_8036e37c:
-/* 8036E37C 48000004 */ b lbl_8036e380
-lbl_8036e380:
-/* 8036E380 48000004 */ b lbl_8036e384
-lbl_8036e384:
-/* 8036E384 811B0040 */ lwz r8, 0x40(r27)
-/* 8036E388 7F24CB78 */ mr r4, r25
-/* 8036E38C 80BB0000 */ lwz r5, 0(r27)
-/* 8036E390 387F0044 */ addi r3, r31, 0x44
-/* 8036E394 4CC63182 */ crclr 6
-/* 8036E398 7CA62B78 */ mr r6, r5
-/* 8036E39C 7D094378 */ mr r9, r8
-/* 8036E3A0 38F90010 */ addi r7, r25, 0x10
-/* 8036E3A4 48000311 */ bl func_8036e6b4
-/* 8036E3A8 3B7B0004 */ addi r27, r27, 0x4
-/* 8036E3AC 3B390001 */ addi r25, r25, 0x1
-/* 8036E3B0 28190010 */ cmplwi r25, 0x10
-/* 8036E3B4 4180FFD0 */ blt+ lbl_8036e384
-/* 8036E3B8 809C0084 */ lwz r4, 0x84(r28)
-/* 8036E3BC 387F0074 */ addi r3, r31, 0x74
-/* 8036E3C0 80BC0080 */ lwz r5, 0x80(r28)
-/* 8036E3C4 4CC63182 */ crclr 6
-/* 8036E3C8 480002ED */ bl func_8036e6b4
-/* 8036E3CC 809C0198 */ lwz r4, 0x198(r28)
-/* 8036E3D0 387F00A4 */ addi r3, r31, 0xa4
-/* 8036E3D4 80BC019C */ lwz r5, 0x19c(r28)
-/* 8036E3D8 4CC63182 */ crclr 6
-/* 8036E3DC 480002D9 */ bl func_8036e6b4
-/* 8036E3E0 387F00D4 */ addi r3, r31, 0xd4
-/* 8036E3E4 4CC63182 */ crclr 6
-/* 8036E3E8 480002CD */ bl func_8036e6b4
-/* 8036E3EC 3B200000 */ li r25, 0x0
-/* 8036E3F0 5720103A */ slwi r0, r25, 2
-/* 8036E3F4 7F7C0214 */ add r27, r28, r0
-/* 8036E3F8 48000004 */ b lbl_8036e3fc
-lbl_8036e3fc:
-/* 8036E3FC 48000004 */ b lbl_8036e400
-lbl_8036e400:
-/* 8036E400 48000004 */ b lbl_8036e404
-lbl_8036e404:
-/* 8036E404 80BB01A4 */ lwz r5, 0x1a4(r27)
-/* 8036E408 7F24CB78 */ mr r4, r25
-/* 8036E40C 80FB01B4 */ lwz r7, 0x1b4(r27)
-/* 8036E410 387F00E8 */ addi r3, r31, 0xe8
-/* 8036E414 38D90004 */ addi r6, r25, 0x4
-/* 8036E418 4CC63182 */ crclr 6
-/* 8036E41C 48000299 */ bl func_8036e6b4
-/* 8036E420 3B7B0004 */ addi r27, r27, 0x4
-/* 8036E424 3B390001 */ addi r25, r25, 0x1
-/* 8036E428 28190004 */ cmplwi r25, 4
-/* 8036E42C 4180FFD8 */ blt+ lbl_8036e404
-/* 8036E430 A01C01A2 */ lhz r0, 0x1a2(r28)
-/* 8036E434 540007FE */ clrlwi r0, r0, 0x1f
-/* 8036E438 28000000 */ cmplwi r0, 0
-/* 8036E43C 4182013C */ beq- lbl_8036e578
-/* 8036E440 48000695 */ bl func_8036ead4
-/* 8036E444 3CC08000 */ lis r6, 0x8000
-/* 8036E448 800600D4 */ lwz r0, 0xd4(r6)
-/* 8036E44C 38A00000 */ li r5, 0x0
-/* 8036E450 38810010 */ addi r4, r1, 0x10
-/* 8036E454 B0A101B0 */ sth r5, 0x1b0(r1)
-/* 8036E458 7C1E0378 */ mr r30, r0
-/* 8036E45C 7C7D1B78 */ mr r29, r3
-/* 8036E460 B0A101B2 */ sth r5, 0x1b2(r1)
-/* 8036E464 800600D8 */ lwz r0, 0xd8(r6)
-/* 8036E468 7C040040 */ cmplw r4, r0
-/* 8036E46C 40820008 */ bne- lbl_8036e474
-/* 8036E470 90A600D8 */ stw r5, 0xd8(r6)
-lbl_8036e474:
-/* 8036E474 38610010 */ addi r3, r1, 0x10
-/* 8036E478 4BFFFC21 */ bl func_8036e098
-/* 8036E47C 387F010C */ addi r3, r31, 0x10c
-/* 8036E480 4CC63182 */ crclr 6
-/* 8036E484 48000231 */ bl func_8036e6b4
-/* 8036E488 3B200000 */ li r25, 0x0
-/* 8036E48C 57201838 */ slwi r0, r25, 3
-/* 8036E490 7F5C0214 */ add r26, r28, r0
-/* 8036E494 48000004 */ b lbl_8036e498
-lbl_8036e498:
-/* 8036E498 48000004 */ b lbl_8036e49c
-lbl_8036e49c:
-/* 8036E49C 48000004 */ b lbl_8036e4a0
-lbl_8036e4a0:
-/* 8036E4A0 C83A0098 */ lfd f1, 0x98(r26)
-/* 8036E4A4 48024E95 */ bl func_80393338
-/* 8036E4A8 7C7B1B78 */ mr r27, r3
-/* 8036E4AC C83A0090 */ lfd f1, 0x90(r26)
-/* 8036E4B0 48024E89 */ bl func_80393338
-/* 8036E4B4 7C651B78 */ mr r5, r3
-/* 8036E4B8 4CC63182 */ crclr 6
-/* 8036E4BC 7F24CB78 */ mr r4, r25
-/* 8036E4C0 7F67DB78 */ mr r7, r27
-/* 8036E4C4 387F0120 */ addi r3, r31, 0x120
-/* 8036E4C8 38D90001 */ addi r6, r25, 0x1
-/* 8036E4CC 480001E9 */ bl func_8036e6b4
-/* 8036E4D0 3B5A0010 */ addi r26, r26, 0x10
-/* 8036E4D4 3B390002 */ addi r25, r25, 0x2
-/* 8036E4D8 28190020 */ cmplwi r25, 0x20
-/* 8036E4DC 4180FFC4 */ blt+ lbl_8036e4a0
-/* 8036E4E0 387F013C */ addi r3, r31, 0x13c
-/* 8036E4E4 4CC63182 */ crclr 6
-/* 8036E4E8 480001CD */ bl func_8036e6b4
-/* 8036E4EC 3B200000 */ li r25, 0x0
-/* 8036E4F0 57201838 */ slwi r0, r25, 3
-/* 8036E4F4 7F5C0214 */ add r26, r28, r0
-/* 8036E4F8 48000004 */ b lbl_8036e4fc
-lbl_8036e4fc:
-/* 8036E4FC 48000004 */ b lbl_8036e500
-lbl_8036e500:
-/* 8036E500 48000004 */ b lbl_8036e504
-lbl_8036e504:
-/* 8036E504 C83A01D0 */ lfd f1, 0x1d0(r26)
-/* 8036E508 48024E31 */ bl func_80393338
-/* 8036E50C 7C7B1B78 */ mr r27, r3
-/* 8036E510 C83A01C8 */ lfd f1, 0x1c8(r26)
-/* 8036E514 48024E25 */ bl func_80393338
-/* 8036E518 7C651B78 */ mr r5, r3
-/* 8036E51C 4CC63182 */ crclr 6
-/* 8036E520 7F24CB78 */ mr r4, r25
-/* 8036E524 7F67DB78 */ mr r7, r27
-/* 8036E528 387F0150 */ addi r3, r31, 0x150
-/* 8036E52C 38D90001 */ addi r6, r25, 0x1
-/* 8036E530 48000185 */ bl func_8036e6b4
-/* 8036E534 3B5A0010 */ addi r26, r26, 0x10
-/* 8036E538 3B390002 */ addi r25, r25, 0x2
-/* 8036E53C 28190020 */ cmplwi r25, 0x20
-/* 8036E540 4180FFC4 */ blt+ lbl_8036e504
-/* 8036E544 38A00000 */ li r5, 0x0
-/* 8036E548 B0A101B0 */ sth r5, 0x1b0(r1)
-/* 8036E54C 3C608000 */ lis r3, 0x8000
-/* 8036E550 38810010 */ addi r4, r1, 0x10
-/* 8036E554 B0A101B2 */ sth r5, 0x1b2(r1)
-/* 8036E558 800300D8 */ lwz r0, 0xd8(r3)
-/* 8036E55C 7C040040 */ cmplw r4, r0
-/* 8036E560 40820008 */ bne- lbl_8036e568
-/* 8036E564 90A300D8 */ stw r5, 0xd8(r3)
-lbl_8036e568:
-/* 8036E568 7FC3F378 */ mr r3, r30
-/* 8036E56C 4BFFFB2D */ bl func_8036e098
-/* 8036E570 7FA3EB78 */ mr r3, r29
-/* 8036E574 48000589 */ bl func_8036eafc
-lbl_8036e578:
-/* 8036E578 387F0170 */ addi r3, r31, 0x170
-/* 8036E57C 4CC63182 */ crclr 6
-/* 8036E580 48000135 */ bl func_8036e6b4
-/* 8036E584 833C0004 */ lwz r25, 4(r28)
-/* 8036E588 3B400000 */ li r26, 0x0
-/* 8036E58C 48000004 */ b lbl_8036e590
-lbl_8036e590:
-/* 8036E590 48000004 */ b lbl_8036e594
-lbl_8036e594:
-/* 8036E594 48000020 */ b lbl_8036e5b4
-lbl_8036e598:
-/* 8036E598 80B90000 */ lwz r5, 0(r25)
-/* 8036E59C 7F24CB78 */ mr r4, r25
-/* 8036E5A0 80D90004 */ lwz r6, 4(r25)
-/* 8036E5A4 387F0198 */ addi r3, r31, 0x198
-/* 8036E5A8 4CC63182 */ crclr 6
-/* 8036E5AC 48000109 */ bl func_8036e6b4
-/* 8036E5B0 83390000 */ lwz r25, 0(r25)
-lbl_8036e5b4:
-/* 8036E5B4 28190000 */ cmplwi r25, 0
-/* 8036E5B8 4182001C */ beq- lbl_8036e5d4
-/* 8036E5BC 3C190001 */ addis r0, r25, 1
-/* 8036E5C0 2800FFFF */ cmplwi r0, 0xffff
-/* 8036E5C4 41820010 */ beq- lbl_8036e5d4
-/* 8036E5C8 281A0010 */ cmplwi r26, 0x10
-/* 8036E5CC 3B5A0001 */ addi r26, r26, 0x1
-/* 8036E5D0 4180FFC8 */ blt+ lbl_8036e598
-lbl_8036e5d4:
-/* 8036E5D4 BB2102DC */ lmw r25, 0x2dc(r1)
-/* 8036E5D8 800102FC */ lwz r0, 0x2fc(r1)
-/* 8036E5DC 382102F8 */ addi r1, r1, 0x2f8
-/* 8036E5E0 7C0803A6 */ mtlr r0
-/* 8036E5E4 4E800020 */ blr
-.size func_8036e340, . - func_8036e340
-
-
-.global func_8036e5e8
-.type func_8036e5e8, @function
-func_8036e5e8:
-/* 8036E5E8 7CA000A6 */ mfmsr r5
-/* 8036E5EC 60A52000 */ ori r5, r5, 0x2000
-/* 8036E5F0 7CA00124 */ mtmsr r5
-/* 8036E5F4 4C00012C */ isync
-/* 8036E5F8 80A4019C */ lwz r5, 0x19c(r4)
-/* 8036E5FC 60A52000 */ ori r5, r5, 0x2000
-/* 8036E600 7CBB03A6 */ mtspr 0x1b, r5
-/* 8036E604 3C608000 */ lis r3, 0x8000
-/* 8036E608 80A300D8 */ lwz r5, 0xd8(r3)
-/* 8036E60C 908300D8 */ stw r4, 0xd8(r3)
-/* 8036E610 7C052000 */ cmpw r5, r4
-/* 8036E614 41820014 */ beq- lbl_8036e628
-/* 8036E618 2C050000 */ cmpwi r5, 0x0
-/* 8036E61C 41820008 */ beq- lbl_8036e624
-/* 8036E620 4BFFF951 */ bl func_8036df70
-lbl_8036e624:
-/* 8036E624 4BFFF829 */ bl func_8036de4c
-lbl_8036e628:
-/* 8036E628 80640080 */ lwz r3, 0x80(r4)
-/* 8036E62C 7C6FF120 */ mtcrf 0xff, r3
-/* 8036E630 80640084 */ lwz r3, 0x84(r4)
-/* 8036E634 7C6803A6 */ mtlr r3
-/* 8036E638 80640198 */ lwz r3, 0x198(r4)
-/* 8036E63C 7C7A03A6 */ mtspr 0x1a, r3
-/* 8036E640 80640088 */ lwz r3, 0x88(r4)
-/* 8036E644 7C6903A6 */ mtctr r3
-/* 8036E648 8064008C */ lwz r3, 0x8c(r4)
-/* 8036E64C 7C6103A6 */ mtxer r3
-/* 8036E650 A06401A2 */ lhz r3, 0x1a2(r4)
-/* 8036E654 546307FA */ rlwinm r3, r3, 0, 0x1f, 0x1d
-/* 8036E658 B06401A2 */ sth r3, 0x1a2(r4)
-/* 8036E65C 80A40014 */ lwz r5, 0x14(r4)
-/* 8036E660 8064000C */ lwz r3, 0xc(r4)
-/* 8036E664 80840010 */ lwz r4, 0x10(r4)
-/* 8036E668 4C000064 */ rfi
-.size func_8036e5e8, . - func_8036e5e8
-
-
-.global func_8036e66c
-.type func_8036e66c, @function
-func_8036e66c:
-/* 8036E66C 7C0802A6 */ mflr r0
-/* 8036E670 90010004 */ stw r0, 4(r1)
-/* 8036E674 9421FFF8 */ stwu r1, -8(r1)
-/* 8036E678 3C608037 */ lis r3, func_8036e5e8@ha
-/* 8036E67C 3883E5E8 */ addi r4, r3, func_8036e5e8@l
-/* 8036E680 38600007 */ li r3, 0x7
-/* 8036E684 4BFFE469 */ bl func_8036caec
-/* 8036E688 38000000 */ li r0, 0x0
-/* 8036E68C 4CC63182 */ crclr 6
-/* 8036E690 3C808000 */ lis r4, 0x8000
-/* 8036E694 3C60804F */ lis r3, lbl_804ef1d4@ha
-/* 8036E698 900400D8 */ stw r0, 0xd8(r4)
-/* 8036E69C 3863F1D4 */ addi r3, r3, lbl_804ef1d4@l
-/* 8036E6A0 4BFFDC11 */ bl func_8036c2b0
-/* 8036E6A4 8001000C */ lwz r0, 0xc(r1)
-/* 8036E6A8 38210008 */ addi r1, r1, 0x8
-/* 8036E6AC 7C0803A6 */ mtlr r0
-/* 8036E6B0 4E800020 */ blr
-.size func_8036e66c, . - func_8036e66c
-
diff --git a/asm/Dolphin/os/OSError-data.s b/asm/Dolphin/os/OSError-data.s
deleted file mode 100644
index 385cc46..0000000
--- a/asm/Dolphin/os/OSError-data.s
+++ /dev/null
@@ -1,217 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804ef1f8
-.type lbl_804ef1f8, @object
-lbl_804ef1f8:
-/* 804EF1F8 20696E20 */ .4byte 0x20696e20
-/* 804EF1FC 22257322 */ .4byte 0x22257322
-/* 804EF200 206F6E20 */ .4byte 0x206f6e20
-/* 804EF204 6C696E65 */ .4byte 0x6c696e65
-/* 804EF208 2025642E */ .4byte 0x2025642e
-/* 804EF20C 0A000000 */ .4byte 0x0a000000
-/* 804EF210 0A416464 */ .4byte 0x0a416464
-/* 804EF214 72657373 */ .4byte 0x72657373
-/* 804EF218 3A202020 */ .4byte 0x3a202020
-/* 804EF21C 20202042 */ .4byte 0x20202042
-/* 804EF220 61636B20 */ .4byte 0x61636b20
-/* 804EF224 43686169 */ .4byte 0x43686169
-/* 804EF228 6E202020 */ .4byte 0x6e202020
-/* 804EF22C 204C5220 */ .4byte 0x204c5220
-/* 804EF230 53617665 */ .4byte 0x53617665
-/* 804EF234 0A000000 */ .4byte 0x0a000000
-/* 804EF238 30782530 */ .4byte 0x30782530
-/* 804EF23C 38783A20 */ .4byte 0x38783a20
-/* 804EF240 20203078 */ .4byte 0x20203078
-/* 804EF244 25303878 */ .4byte 0x25303878
-/* 804EF248 20202020 */ .4byte 0x20202020
-/* 804EF24C 30782530 */ .4byte 0x30782530
-/* 804EF250 38780A00 */ .4byte 0x38780a00
-/* 804EF254 4E6F6E2D */ .4byte 0x4e6f6e2d
-/* 804EF258 7265636F */ .4byte 0x7265636f
-/* 804EF25C 76657261 */ .4byte 0x76657261
-/* 804EF260 626C6520 */ .4byte 0x626c6520
-/* 804EF264 45786365 */ .4byte 0x45786365
-/* 804EF268 7074696F */ .4byte 0x7074696f
-/* 804EF26C 6E202564 */ .4byte 0x6e202564
-/* 804EF270 00000000 */ .4byte 0x00000000
-/* 804EF274 556E6861 */ .4byte 0x556e6861
-/* 804EF278 6E646C65 */ .4byte 0x6e646c65
-/* 804EF27C 64204578 */ .4byte 0x64204578
-/* 804EF280 63657074 */ .4byte 0x63657074
-/* 804EF284 696F6E20 */ .4byte 0x696f6e20
-/* 804EF288 25640000 */ .4byte 0x25640000
-/* 804EF28C 0A445349 */ .4byte 0x0a445349
-/* 804EF290 5352203D */ .4byte 0x5352203d
-/* 804EF294 20307825 */ .4byte 0x20307825
-/* 804EF298 30387820 */ .4byte 0x30387820
-/* 804EF29C 20202020 */ .4byte 0x20202020
-/* 804EF2A0 20202020 */ .4byte 0x20202020
-/* 804EF2A4 20202020 */ .4byte 0x20202020
-/* 804EF2A8 20202020 */ .4byte 0x20202020
-/* 804EF2AC 20204441 */ .4byte 0x20204441
-/* 804EF2B0 5220203D */ .4byte 0x5220203d
-/* 804EF2B4 20307825 */ .4byte 0x20307825
-/* 804EF2B8 3038780A */ .4byte 0x3038780a
-/* 804EF2BC 00000000 */ .4byte 0x00000000
-/* 804EF2C0 5442203D */ .4byte 0x5442203d
-/* 804EF2C4 20307825 */ .4byte 0x20307825
-/* 804EF2C8 3031366C */ .4byte 0x3031366c
-/* 804EF2CC 6C780A00 */ .4byte 0x6c780a00
-/* 804EF2D0 0A496E73 */ .4byte 0x0a496e73
-/* 804EF2D4 74727563 */ .4byte 0x74727563
-/* 804EF2D8 74696F6E */ .4byte 0x74696f6e
-/* 804EF2DC 20617420 */ .4byte 0x20617420
-/* 804EF2E0 30782578 */ .4byte 0x30782578
-/* 804EF2E4 20287265 */ .4byte 0x20287265
-/* 804EF2E8 61642066 */ .4byte 0x61642066
-/* 804EF2EC 726F6D20 */ .4byte 0x726f6d20
-/* 804EF2F0 53525230 */ .4byte 0x53525230
-/* 804EF2F4 29206174 */ .4byte 0x29206174
-/* 804EF2F8 74656D70 */ .4byte 0x74656d70
-/* 804EF2FC 74656420 */ .4byte 0x74656420
-/* 804EF300 746F2061 */ .4byte 0x746f2061
-/* 804EF304 63636573 */ .4byte 0x63636573
-/* 804EF308 7320696E */ .4byte 0x7320696e
-/* 804EF30C 76616C69 */ .4byte 0x76616c69
-/* 804EF310 64206164 */ .4byte 0x64206164
-/* 804EF314 64726573 */ .4byte 0x64726573
-/* 804EF318 73203078 */ .4byte 0x73203078
-/* 804EF31C 25782028 */ .4byte 0x25782028
-/* 804EF320 72656164 */ .4byte 0x72656164
-/* 804EF324 2066726F */ .4byte 0x2066726f
-/* 804EF328 6D204441 */ .4byte 0x6d204441
-/* 804EF32C 52290A00 */ .4byte 0x52290a00
-/* 804EF330 0A417474 */ .4byte 0x0a417474
-/* 804EF334 656D7074 */ .4byte 0x656d7074
-/* 804EF338 65642074 */ .4byte 0x65642074
-/* 804EF33C 6F206665 */ .4byte 0x6f206665
-/* 804EF340 74636820 */ .4byte 0x74636820
-/* 804EF344 696E7374 */ .4byte 0x696e7374
-/* 804EF348 72756374 */ .4byte 0x72756374
-/* 804EF34C 696F6E20 */ .4byte 0x696f6e20
-/* 804EF350 66726F6D */ .4byte 0x66726f6d
-/* 804EF354 20696E76 */ .4byte 0x20696e76
-/* 804EF358 616C6964 */ .4byte 0x616c6964
-/* 804EF35C 20616464 */ .4byte 0x20616464
-/* 804EF360 72657373 */ .4byte 0x72657373
-/* 804EF364 20307825 */ .4byte 0x20307825
-/* 804EF368 78202872 */ .4byte 0x78202872
-/* 804EF36C 65616420 */ .4byte 0x65616420
-/* 804EF370 66726F6D */ .4byte 0x66726f6d
-/* 804EF374 20535252 */ .4byte 0x20535252
-/* 804EF378 30290A00 */ .4byte 0x30290a00
-/* 804EF37C 0A496E73 */ .4byte 0x0a496e73
-/* 804EF380 74727563 */ .4byte 0x74727563
-/* 804EF384 74696F6E */ .4byte 0x74696f6e
-/* 804EF388 20617420 */ .4byte 0x20617420
-/* 804EF38C 30782578 */ .4byte 0x30782578
-/* 804EF390 20287265 */ .4byte 0x20287265
-/* 804EF394 61642066 */ .4byte 0x61642066
-/* 804EF398 726F6D20 */ .4byte 0x726f6d20
-/* 804EF39C 53525230 */ .4byte 0x53525230
-/* 804EF3A0 29206174 */ .4byte 0x29206174
-/* 804EF3A4 74656D70 */ .4byte 0x74656d70
-/* 804EF3A8 74656420 */ .4byte 0x74656420
-/* 804EF3AC 746F2061 */ .4byte 0x746f2061
-/* 804EF3B0 63636573 */ .4byte 0x63636573
-/* 804EF3B4 7320756E */ .4byte 0x7320756e
-/* 804EF3B8 616C6967 */ .4byte 0x616c6967
-/* 804EF3BC 6E656420 */ .4byte 0x6e656420
-/* 804EF3C0 61646472 */ .4byte 0x61646472
-/* 804EF3C4 65737320 */ .4byte 0x65737320
-/* 804EF3C8 30782578 */ .4byte 0x30782578
-/* 804EF3CC 20287265 */ .4byte 0x20287265
-/* 804EF3D0 61642066 */ .4byte 0x61642066
-/* 804EF3D4 726F6D20 */ .4byte 0x726f6d20
-/* 804EF3D8 44415229 */ .4byte 0x44415229
-/* 804EF3DC 0A000000 */ .4byte 0x0a000000
-/* 804EF3E0 0A50726F */ .4byte 0x0a50726f
-/* 804EF3E4 6772616D */ .4byte 0x6772616d
-/* 804EF3E8 20657863 */ .4byte 0x20657863
-/* 804EF3EC 65707469 */ .4byte 0x65707469
-/* 804EF3F0 6F6E203A */ .4byte 0x6f6e203a
-/* 804EF3F4 20506F73 */ .4byte 0x20506f73
-/* 804EF3F8 7369626C */ .4byte 0x7369626c
-/* 804EF3FC 6520696C */ .4byte 0x6520696c
-/* 804EF400 6C656761 */ .4byte 0x6c656761
-/* 804EF404 6C20696E */ .4byte 0x6c20696e
-/* 804EF408 73747275 */ .4byte 0x73747275
-/* 804EF40C 6374696F */ .4byte 0x6374696f
-/* 804EF410 6E2F6F70 */ .4byte 0x6e2f6f70
-/* 804EF414 65726174 */ .4byte 0x65726174
-/* 804EF418 696F6E20 */ .4byte 0x696f6e20
-/* 804EF41C 6174206F */ .4byte 0x6174206f
-/* 804EF420 72206172 */ .4byte 0x72206172
-/* 804EF424 6F756E64 */ .4byte 0x6f756e64
-/* 804EF428 20307825 */ .4byte 0x20307825
-/* 804EF42C 78202872 */ .4byte 0x78202872
-/* 804EF430 65616420 */ .4byte 0x65616420
-/* 804EF434 66726F6D */ .4byte 0x66726f6d
-/* 804EF438 20535252 */ .4byte 0x20535252
-/* 804EF43C 30290A00 */ .4byte 0x30290a00
-/* 804EF440 41492044 */ .4byte 0x41492044
-/* 804EF444 4D412041 */ .4byte 0x4d412041
-/* 804EF448 64647265 */ .4byte 0x64647265
-/* 804EF44C 7373203D */ .4byte 0x7373203d
-/* 804EF450 20202030 */ .4byte 0x20202030
-/* 804EF454 78253034 */ .4byte 0x78253034
-/* 804EF458 78253034 */ .4byte 0x78253034
-/* 804EF45C 780A0000 */ .4byte 0x780a0000
-/* 804EF460 4152414D */ .4byte 0x4152414d
-/* 804EF464 20444D41 */ .4byte 0x20444d41
-/* 804EF468 20416464 */ .4byte 0x20416464
-/* 804EF46C 72657373 */ .4byte 0x72657373
-/* 804EF470 203D2030 */ .4byte 0x203d2030
-/* 804EF474 78253034 */ .4byte 0x78253034
-/* 804EF478 78253034 */ .4byte 0x78253034
-/* 804EF47C 780A0000 */ .4byte 0x780a0000
-/* 804EF480 44492044 */ .4byte 0x44492044
-/* 804EF484 4D412041 */ .4byte 0x4d412041
-/* 804EF488 64647265 */ .4byte 0x64647265
-/* 804EF48C 7373203D */ .4byte 0x7373203d
-/* 804EF490 20202030 */ .4byte 0x20202030
-/* 804EF494 78253038 */ .4byte 0x78253038
-/* 804EF498 780A0000 */ .4byte 0x780a0000
-/* 804EF49C 0A4C6173 */ .4byte 0x0a4c6173
-/* 804EF4A0 7420696E */ .4byte 0x7420696e
-/* 804EF4A4 74657272 */ .4byte 0x74657272
-/* 804EF4A8 75707420 */ .4byte 0x75707420
-/* 804EF4AC 28256429 */ .4byte 0x28256429
-/* 804EF4B0 3A205352 */ .4byte 0x3a205352
-/* 804EF4B4 5230203D */ .4byte 0x5230203d
-/* 804EF4B8 20307825 */ .4byte 0x20307825
-/* 804EF4BC 30387820 */ .4byte 0x30387820
-/* 804EF4C0 20544220 */ .4byte 0x20544220
-/* 804EF4C4 3D203078 */ .4byte 0x3d203078
-/* 804EF4C8 25303136 */ .4byte 0x25303136
-/* 804EF4CC 6C6C780A */ .4byte 0x6c6c780a
-/* 804EF4D0 00000000 */ .4byte 0x00000000
-.size lbl_804ef1f8, . - lbl_804ef1f8
-
-
-.global jtbl_804ef4d4
-.type jtbl_804ef4d4, @object
-jtbl_804ef4d4:
-/* 804EF4D4 8036EA48 */ .4byte jump_8036ea48
-/* 804EF4D8 8036EA48 */ .4byte jump_8036ea48
-/* 804EF4DC 8036E9A0 */ .4byte jump_8036e9a0
-/* 804EF4E0 8036E9B8 */ .4byte jump_8036e9b8
-/* 804EF4E4 8036EA48 */ .4byte jump_8036ea48
-/* 804EF4E8 8036E9CC */ .4byte jump_8036e9cc
-/* 804EF4EC 8036E9E4 */ .4byte jump_8036e9e4
-/* 804EF4F0 8036EA48 */ .4byte jump_8036ea48
-/* 804EF4F4 8036EA48 */ .4byte jump_8036ea48
-/* 804EF4F8 8036EA48 */ .4byte jump_8036ea48
-/* 804EF4FC 8036EA48 */ .4byte jump_8036ea48
-/* 804EF500 8036EA48 */ .4byte jump_8036ea48
-/* 804EF504 8036EA48 */ .4byte jump_8036ea48
-/* 804EF508 8036EA48 */ .4byte jump_8036ea48
-/* 804EF50C 8036EA48 */ .4byte jump_8036ea48
-/* 804EF510 8036E9FC */ .4byte jump_8036e9fc
-/* 804EF514 00000000 */ .4byte 0x00000000
-.size jtbl_804ef4d4, . - jtbl_804ef4d4
-
diff --git a/asm/Dolphin/os/OSError.s b/asm/Dolphin/os/OSError.s
deleted file mode 100644
index 49c659e..0000000
--- a/asm/Dolphin/os/OSError.s
+++ /dev/null
@@ -1,329 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036e6b4
-.type func_8036e6b4, @function
-func_8036e6b4:
-/* 8036E6B4 7C0802A6 */ mflr r0
-/* 8036E6B8 90010004 */ stw r0, 4(r1)
-/* 8036E6BC 9421FF88 */ stwu r1, -0x78(r1)
-/* 8036E6C0 40860024 */ bne- cr1, lbl_8036e6e4
-/* 8036E6C4 D8210028 */ stfd f1, 0x28(r1)
-/* 8036E6C8 D8410030 */ stfd f2, 0x30(r1)
-/* 8036E6CC D8610038 */ stfd f3, 0x38(r1)
-/* 8036E6D0 D8810040 */ stfd f4, 0x40(r1)
-/* 8036E6D4 D8A10048 */ stfd f5, 0x48(r1)
-/* 8036E6D8 D8C10050 */ stfd f6, 0x50(r1)
-/* 8036E6DC D8E10058 */ stfd f7, 0x58(r1)
-/* 8036E6E0 D9010060 */ stfd f8, 0x60(r1)
-lbl_8036e6e4:
-/* 8036E6E4 90610008 */ stw r3, 8(r1)
-/* 8036E6E8 3C000100 */ lis r0, 0x100
-/* 8036E6EC 9081000C */ stw r4, 0xc(r1)
-/* 8036E6F0 3881006C */ addi r4, r1, 0x6c
-/* 8036E6F4 90A10010 */ stw r5, 0x10(r1)
-/* 8036E6F8 90C10014 */ stw r6, 0x14(r1)
-/* 8036E6FC 90E10018 */ stw r7, 0x18(r1)
-/* 8036E700 9101001C */ stw r8, 0x1c(r1)
-/* 8036E704 91210020 */ stw r9, 0x20(r1)
-/* 8036E708 91410024 */ stw r10, 0x24(r1)
-/* 8036E70C 9001006C */ stw r0, 0x6c(r1)
-/* 8036E710 38010080 */ addi r0, r1, 0x80
-/* 8036E714 90010070 */ stw r0, 0x70(r1)
-/* 8036E718 38010008 */ addi r0, r1, 0x8
-/* 8036E71C 90010074 */ stw r0, 0x74(r1)
-/* 8036E720 48028C05 */ bl func_80397324
-/* 8036E724 8001007C */ lwz r0, 0x7c(r1)
-/* 8036E728 38210078 */ addi r1, r1, 0x78
-/* 8036E72C 7C0803A6 */ mtlr r0
-/* 8036E730 4E800020 */ blr
-.size func_8036e6b4, . - func_8036e6b4
-
-
-.global func_8036e734
-.type func_8036e734, @function
-func_8036e734:
-/* 8036E734 7C0802A6 */ mflr r0
-/* 8036E738 90010004 */ stw r0, 4(r1)
-/* 8036E73C 9421FF70 */ stwu r1, -0x90(r1)
-/* 8036E740 93E1008C */ stw r31, 0x8c(r1)
-/* 8036E744 93C10088 */ stw r30, 0x88(r1)
-/* 8036E748 93A10084 */ stw r29, 0x84(r1)
-/* 8036E74C 93810080 */ stw r28, 0x80(r1)
-/* 8036E750 40860024 */ bne- cr1, lbl_8036e774
-/* 8036E754 D8210028 */ stfd f1, 0x28(r1)
-/* 8036E758 D8410030 */ stfd f2, 0x30(r1)
-/* 8036E75C D8610038 */ stfd f3, 0x38(r1)
-/* 8036E760 D8810040 */ stfd f4, 0x40(r1)
-/* 8036E764 D8A10048 */ stfd f5, 0x48(r1)
-/* 8036E768 D8C10050 */ stfd f6, 0x50(r1)
-/* 8036E76C D8E10058 */ stfd f7, 0x58(r1)
-/* 8036E770 D9010060 */ stfd f8, 0x60(r1)
-lbl_8036e774:
-/* 8036E774 90610008 */ stw r3, 8(r1)
-/* 8036E778 3B830000 */ addi r28, r3, 0x0
-/* 8036E77C 3BC40000 */ addi r30, r4, 0x0
-/* 8036E780 9081000C */ stw r4, 0xc(r1)
-/* 8036E784 3BA50000 */ addi r29, r5, 0x0
-/* 8036E788 90A10010 */ stw r5, 0x10(r1)
-/* 8036E78C 90C10014 */ stw r6, 0x14(r1)
-/* 8036E790 3CC0804F */ lis r6, lbl_804ef1f8@ha
-/* 8036E794 3BE6F1F8 */ addi r31, r6, lbl_804ef1f8@l
-/* 8036E798 90E10018 */ stw r7, 0x18(r1)
-/* 8036E79C 9101001C */ stw r8, 0x1c(r1)
-/* 8036E7A0 91210020 */ stw r9, 0x20(r1)
-/* 8036E7A4 91410024 */ stw r10, 0x24(r1)
-/* 8036E7A8 4800032D */ bl func_8036ead4
-/* 8036E7AC 3C000300 */ lis r0, 0x300
-/* 8036E7B0 90010074 */ stw r0, 0x74(r1)
-/* 8036E7B4 38010098 */ addi r0, r1, 0x98
-/* 8036E7B8 38810074 */ addi r4, r1, 0x74
-/* 8036E7BC 90010078 */ stw r0, 0x78(r1)
-/* 8036E7C0 38010008 */ addi r0, r1, 0x8
-/* 8036E7C4 387D0000 */ addi r3, r29, 0x0
-/* 8036E7C8 9001007C */ stw r0, 0x7c(r1)
-/* 8036E7CC 48028B59 */ bl func_80397324
-/* 8036E7D0 387F0000 */ addi r3, r31, 0x0
-/* 8036E7D4 4CC63182 */ crclr 6
-/* 8036E7D8 389C0000 */ addi r4, r28, 0x0
-/* 8036E7DC 38BE0000 */ addi r5, r30, 0x0
-/* 8036E7E0 4BFFFED5 */ bl func_8036e6b4
-/* 8036E7E4 387F0018 */ addi r3, r31, 0x18
-/* 8036E7E8 4CC63182 */ crclr 6
-/* 8036E7EC 4BFFFEC9 */ bl func_8036e6b4
-/* 8036E7F0 3BC00000 */ li r30, 0x0
-/* 8036E7F4 4BFFFA65 */ bl func_8036e258
-/* 8036E7F8 7C7D1B78 */ mr r29, r3
-/* 8036E7FC 48000020 */ b lbl_8036e81c
-lbl_8036e800:
-/* 8036E800 80BD0000 */ lwz r5, 0(r29)
-/* 8036E804 7FA4EB78 */ mr r4, r29
-/* 8036E808 80DD0004 */ lwz r6, 4(r29)
-/* 8036E80C 387F0040 */ addi r3, r31, 0x40
-/* 8036E810 4CC63182 */ crclr 6
-/* 8036E814 4BFFFEA1 */ bl func_8036e6b4
-/* 8036E818 83BD0000 */ lwz r29, 0(r29)
-lbl_8036e81c:
-/* 8036E81C 281D0000 */ cmplwi r29, 0
-/* 8036E820 4182001C */ beq- lbl_8036e83c
-/* 8036E824 3C1D0001 */ addis r0, r29, 1
-/* 8036E828 2800FFFF */ cmplwi r0, 0xffff
-/* 8036E82C 41820010 */ beq- lbl_8036e83c
-/* 8036E830 281E0010 */ cmplwi r30, 0x10
-/* 8036E834 3BDE0001 */ addi r30, r30, 0x1
-/* 8036E838 4180FFC8 */ blt+ lbl_8036e800
-lbl_8036e83c:
-/* 8036E83C 4BFFD97D */ bl func_8036c1b8
-/* 8036E840 80010094 */ lwz r0, 0x94(r1)
-/* 8036E844 83E1008C */ lwz r31, 0x8c(r1)
-/* 8036E848 83C10088 */ lwz r30, 0x88(r1)
-/* 8036E84C 83A10084 */ lwz r29, 0x84(r1)
-/* 8036E850 83810080 */ lwz r28, 0x80(r1)
-/* 8036E854 38210090 */ addi r1, r1, 0x90
-/* 8036E858 7C0803A6 */ mtlr r0
-/* 8036E85C 4E800020 */ blr
-.size func_8036e734, . - func_8036e734
-
-
-.global func_8036e860
-.type func_8036e860, @function
-func_8036e860:
-/* 8036E860 3CA08054 */ lis r5, lbl_8053ec30@ha
-/* 8036E864 546313BA */ rlwinm r3, r3, 2, 0xe, 0x1d
-/* 8036E868 3805EC30 */ addi r0, r5, lbl_8053ec30@l
-/* 8036E86C 7CA01A14 */ add r5, r0, r3
-/* 8036E870 80650000 */ lwz r3, 0(r5)
-/* 8036E874 90850000 */ stw r4, 0(r5)
-/* 8036E878 4E800020 */ blr
-.size func_8036e860, . - func_8036e860
-
-
-.global func_8036e87c
-.type func_8036e87c, @function
-func_8036e87c:
-/* 8036E87C 7C0802A6 */ mflr r0
-/* 8036E880 90010004 */ stw r0, 4(r1)
-/* 8036E884 9421FFC8 */ stwu r1, -0x38(r1)
-/* 8036E888 BF21001C */ stmw r25, 0x1c(r1)
-/* 8036E88C 7C9F2378 */ mr r31, r4
-/* 8036E890 3B230000 */ addi r25, r3, 0x0
-/* 8036E894 3B450000 */ addi r26, r5, 0x0
-/* 8036E898 3B660000 */ addi r27, r6, 0x0
-/* 8036E89C 8004019C */ lwz r0, 0x19c(r4)
-/* 8036E8A0 3C80804F */ lis r4, lbl_804ef1f8@ha
-/* 8036E8A4 3BA4F1F8 */ addi r29, r4, lbl_804ef1f8@l
-/* 8036E8A8 540007BD */ rlwinm. r0, r0, 0, 0x1e, 0x1e
-/* 8036E8AC 40820018 */ bne- lbl_8036e8c4
-/* 8036E8B0 387D005C */ addi r3, r29, 0x5c
-/* 8036E8B4 4CC63182 */ crclr 6
-/* 8036E8B8 5724063E */ clrlwi r4, r25, 0x18
-/* 8036E8BC 4BFFFDF9 */ bl func_8036e6b4
-/* 8036E8C0 4800007C */ b lbl_8036e93c
-lbl_8036e8c4:
-/* 8036E8C4 573E063E */ clrlwi r30, r25, 0x18
-/* 8036E8C8 3C608054 */ lis r3, lbl_8053ec30@ha
-/* 8036E8CC 572415BA */ rlwinm r4, r25, 2, 0x16, 0x1d
-/* 8036E8D0 3803EC30 */ addi r0, r3, lbl_8053ec30@l
-/* 8036E8D4 7F802214 */ add r28, r0, r4
-/* 8036E8D8 801C0000 */ lwz r0, 0(r28)
-/* 8036E8DC 28000000 */ cmplwi r0, 0
-/* 8036E8E0 41820038 */ beq- lbl_8036e918
-/* 8036E8E4 48002ED1 */ bl func_803717b4
-/* 8036E8E8 819C0000 */ lwz r12, 0(r28)
-/* 8036E8EC 387E0000 */ addi r3, r30, 0x0
-/* 8036E8F0 389F0000 */ addi r4, r31, 0x0
-/* 8036E8F4 4CC63182 */ crclr 6
-/* 8036E8F8 7D8803A6 */ mtlr r12
-/* 8036E8FC 38BA0000 */ addi r5, r26, 0x0
-/* 8036E900 38DB0000 */ addi r6, r27, 0x0
-/* 8036E904 4E800021 */ blrl
-/* 8036E908 48002EED */ bl func_803717f4
-/* 8036E90C 480033DD */ bl func_80371ce8
-/* 8036E910 7FE3FB78 */ mr r3, r31
-/* 8036E914 4BFFF86D */ bl func_8036e180
-lbl_8036e918:
-/* 8036E918 5720063E */ clrlwi r0, r25, 0x18
-/* 8036E91C 28000008 */ cmplwi r0, 8
-/* 8036E920 4082000C */ bne- lbl_8036e92c
-/* 8036E924 7FE3FB78 */ mr r3, r31
-/* 8036E928 4BFFF859 */ bl func_8036e180
-lbl_8036e92c:
-/* 8036E92C 387D007C */ addi r3, r29, 0x7c
-/* 8036E930 4CC63182 */ crclr 6
-/* 8036E934 5724063E */ clrlwi r4, r25, 0x18
-/* 8036E938 4BFFFD7D */ bl func_8036e6b4
-lbl_8036e93c:
-/* 8036E93C 386D9F08 */ addi r3, 0, lbl_805c3d28@sda21
-/* 8036E940 4CC63182 */ crclr 6
-/* 8036E944 4BFFFD71 */ bl func_8036e6b4
-/* 8036E948 7FE3FB78 */ mr r3, r31
-/* 8036E94C 4BFFF9F5 */ bl func_8036e340
-/* 8036E950 389A0000 */ addi r4, r26, 0x0
-/* 8036E954 4CC63182 */ crclr 6
-/* 8036E958 38BB0000 */ addi r5, r27, 0x0
-/* 8036E95C 387D0094 */ addi r3, r29, 0x94
-/* 8036E960 4BFFFD55 */ bl func_8036e6b4
-/* 8036E964 48003E61 */ bl func_803727c4
-/* 8036E968 38A30000 */ addi r5, r3, 0x0
-/* 8036E96C 4CC63182 */ crclr 6
-/* 8036E970 38C40000 */ addi r6, r4, 0x0
-/* 8036E974 387D00C8 */ addi r3, r29, 0xc8
-/* 8036E978 4BFFFD3D */ bl func_8036e6b4
-/* 8036E97C 5720063E */ clrlwi r0, r25, 0x18
-/* 8036E980 2800000F */ cmplwi r0, 0xf
-/* 8036E984 418100C4 */ bgt- lbl_8036ea48
-/* 8036E988 3C60804F */ lis r3, jtbl_804ef4d4@ha
-/* 8036E98C 3863F4D4 */ addi r3, r3, jtbl_804ef4d4@l
-/* 8036E990 5400103A */ slwi r0, r0, 2
-/* 8036E994 7C03002E */ lwzx r0, r3, r0
-/* 8036E998 7C0903A6 */ mtctr r0
-/* 8036E99C 4E800420 */ bctr
-lbl_8036e9a0:
-.global jump_8036e9a0
-jump_8036e9a0:
-/* 8036E9A0 809F0198 */ lwz r4, 0x198(r31)
-/* 8036E9A4 38BB0000 */ addi r5, r27, 0x0
-/* 8036E9A8 387D00D8 */ addi r3, r29, 0xd8
-/* 8036E9AC 4CC63182 */ crclr 6
-/* 8036E9B0 4BFFFD05 */ bl func_8036e6b4
-/* 8036E9B4 48000094 */ b lbl_8036ea48
-lbl_8036e9b8:
-.global jump_8036e9b8
-jump_8036e9b8:
-/* 8036E9B8 809F0198 */ lwz r4, 0x198(r31)
-/* 8036E9BC 387D0138 */ addi r3, r29, 0x138
-/* 8036E9C0 4CC63182 */ crclr 6
-/* 8036E9C4 4BFFFCF1 */ bl func_8036e6b4
-/* 8036E9C8 48000080 */ b lbl_8036ea48
-lbl_8036e9cc:
-.global jump_8036e9cc
-jump_8036e9cc:
-/* 8036E9CC 809F0198 */ lwz r4, 0x198(r31)
-/* 8036E9D0 38BB0000 */ addi r5, r27, 0x0
-/* 8036E9D4 387D0184 */ addi r3, r29, 0x184
-/* 8036E9D8 4CC63182 */ crclr 6
-/* 8036E9DC 4BFFFCD9 */ bl func_8036e6b4
-/* 8036E9E0 48000068 */ b lbl_8036ea48
-lbl_8036e9e4:
-.global jump_8036e9e4
-jump_8036e9e4:
-/* 8036E9E4 809F0198 */ lwz r4, 0x198(r31)
-/* 8036E9E8 38BB0000 */ addi r5, r27, 0x0
-/* 8036E9EC 387D01E8 */ addi r3, r29, 0x1e8
-/* 8036E9F0 4CC63182 */ crclr 6
-/* 8036E9F4 4BFFFCC1 */ bl func_8036e6b4
-/* 8036E9F8 48000050 */ b lbl_8036ea48
-lbl_8036e9fc:
-.global jump_8036e9fc
-jump_8036e9fc:
-/* 8036E9FC 386D9F08 */ addi r3, 0, lbl_805c3d28@sda21
-/* 8036EA00 4CC63182 */ crclr 6
-/* 8036EA04 4BFFFCB1 */ bl func_8036e6b4
-/* 8036EA08 3FC0CC00 */ lis r30, 0xcc00
-/* 8036EA0C 4CC63182 */ crclr 6
-/* 8036EA10 3BFE5000 */ addi r31, r30, 0x5000
-/* 8036EA14 A09E5030 */ lhz r4, 0x5030(r30)
-/* 8036EA18 387D0248 */ addi r3, r29, 0x248
-/* 8036EA1C A0BE5032 */ lhz r5, 0x5032(r30)
-/* 8036EA20 4BFFFC95 */ bl func_8036e6b4
-/* 8036EA24 A09F0020 */ lhz r4, 0x20(r31)
-/* 8036EA28 387D0268 */ addi r3, r29, 0x268
-/* 8036EA2C A0BF0022 */ lhz r5, 0x22(r31)
-/* 8036EA30 4CC63182 */ crclr 6
-/* 8036EA34 4BFFFC81 */ bl func_8036e6b4
-/* 8036EA38 809E6014 */ lwz r4, 0x6014(r30)
-/* 8036EA3C 4CC63182 */ crclr 6
-/* 8036EA40 387D0288 */ addi r3, r29, 0x288
-/* 8036EA44 4BFFFC71 */ bl func_8036e6b4
-lbl_8036ea48:
-.global jump_8036ea48
-jump_8036ea48:
-/* 8036EA48 A88DCA50 */ lha r4, lbl_805c6870@sda21(0)
-/* 8036EA4C 387D02A4 */ addi r3, r29, 0x2a4
-/* 8036EA50 4CC63182 */ crclr 6
-/* 8036EA54 80ADCA4C */ lwz r5, lbl_805c686c@sda21(0)
-/* 8036EA58 80EDCA58 */ lwz r7, lbl_805c6878@sda21(0)
-/* 8036EA5C 810DCA5C */ lwz r8, lbl_805c687c@sda21(0)
-/* 8036EA60 4BFFFC55 */ bl func_8036e6b4
-/* 8036EA64 4BFFD755 */ bl func_8036c1b8
-/* 8036EA68 BB21001C */ lmw r25, 0x1c(r1)
-/* 8036EA6C 8001003C */ lwz r0, 0x3c(r1)
-/* 8036EA70 38210038 */ addi r1, r1, 0x38
-/* 8036EA74 7C0803A6 */ mtlr r0
-/* 8036EA78 4E800020 */ blr
-.size func_8036e87c, . - func_8036e87c
-
-
-.global func_8036ea7c
-.type func_8036ea7c, @function
-func_8036ea7c:
-/* 8036EA7C A06D9F10 */ lhz r3, lbl_805c3d30@sda21(0)
-/* 8036EA80 28030001 */ cmplwi r3, 1
-/* 8036EA84 4C810020 */ blelr-
-/* 8036EA88 3C608000 */ lis r3, 0x8000
-/* 8036EA8C 800300CC */ lwz r0, 0xcc(r3)
-/* 8036EA90 2C000000 */ cmpwi r0, 0x0
-/* 8036EA94 4182000C */ beq- lbl_8036eaa0
-/* 8036EA98 4180002C */ blt- lbl_8036eac4
-/* 8036EA9C 48000028 */ b lbl_8036eac4
-lbl_8036eaa0:
-/* 8036EAA0 3C60CC00 */ lis r3, 0xcc00
-/* 8036EAA4 A003206E */ lhz r0, 0x206e(r3)
-/* 8036EAA8 540007BD */ rlwinm. r0, r0, 0, 0x1e, 0x1e
-/* 8036EAAC 4182000C */ beq- lbl_8036eab8
-/* 8036EAB0 38000001 */ li r0, 0x1
-/* 8036EAB4 48000008 */ b lbl_8036eabc
-lbl_8036eab8:
-/* 8036EAB8 38000000 */ li r0, 0x0
-lbl_8036eabc:
-/* 8036EABC B00D9F10 */ sth r0, lbl_805c3d30@sda21(0)
-/* 8036EAC0 4800000C */ b lbl_8036eacc
-lbl_8036eac4:
-/* 8036EAC4 38000000 */ li r0, 0x0
-/* 8036EAC8 B00D9F10 */ sth r0, lbl_805c3d30@sda21(0)
-lbl_8036eacc:
-/* 8036EACC A06D9F10 */ lhz r3, lbl_805c3d30@sda21(0)
-/* 8036EAD0 4E800020 */ blr
-.size func_8036ea7c, . - func_8036ea7c
-
diff --git a/asm/Dolphin/os/OSInit.s b/asm/Dolphin/os/OSInit.s
deleted file mode 100644
index ba4ecba..0000000
--- a/asm/Dolphin/os/OSInit.s
+++ /dev/null
@@ -1,263 +0,0 @@
-.global func_8036c48c
-.type func_8036c48c, @function
-func_8036c48c:
-/* 8036C48C 7C0802A6 */ mflr r0
-/* 8036C490 90010004 */ stw r0, 4(r1)
-/* 8036C494 9421FFE8 */ stwu r1, -0x18(r1)
-/* 8036C498 93E10014 */ stw r31, 0x14(r1)
-/* 8036C49C 93C10010 */ stw r30, 0x10(r1)
-/* 8036C4A0 93A1000C */ stw r29, 0xc(r1)
-/* 8036C4A4 800DCA08 */ lwz r0, lbl_805c6828@sda21(0)
-/* 8036C4A8 3C808054 */ lis r4, lbl_8053ebe0@ha
-/* 8036C4AC 3C60804F */ lis r3, lbl_804eebb0@ha
-/* 8036C4B0 2C000000 */ cmpwi r0, 0x0
-/* 8036C4B4 3BC4EBE0 */ addi r30, r4, lbl_8053ebe0@l
-/* 8036C4B8 3BE3EBB0 */ addi r31, r3, lbl_804eebb0@l
-/* 8036C4BC 4082036C */ bne- lbl_8036c828
-/* 8036C4C0 38000001 */ li r0, 0x1
-/* 8036C4C4 900DCA08 */ stw r0, lbl_805c6828@sda21(0)
-/* 8036C4C8 4800631D */ bl func_803727e4
-/* 8036C4CC 908DCA24 */ stw r4, lbl_805c6844@sda21(0)
-/* 8036C4D0 906DCA20 */ stw r3, lbl_805c6840@sda21(0)
-/* 8036C4D4 48002601 */ bl func_8036ead4
-/* 8036C4D8 4BFFFD0D */ bl func_8036c1e4
-/* 8036C4DC 4BFFFD31 */ bl func_8036c20c
-/* 8036C4E0 38000000 */ li r0, 0x0
-/* 8036C4E4 3C808000 */ lis r4, 0x8000
-/* 8036C4E8 900DC9FC */ stw r0, lbl_805c681c@sda21(0)
-/* 8036C4EC 908DC9F8 */ stw r4, lbl_805c6818@sda21(0)
-/* 8036C4F0 900DCB04 */ stw r0, lbl_805c6924@sda21(0)
-/* 8036C4F4 806400F4 */ lwz r3, 0xf4(r4)
-/* 8036C4F8 28030000 */ cmplwi r3, 0
-/* 8036C4FC 41820034 */ beq- lbl_8036c530
-/* 8036C500 3803000C */ addi r0, r3, 0xc
-/* 8036C504 900DC9FC */ stw r0, lbl_805c681c@sda21(0)
-/* 8036C508 80030024 */ lwz r0, 0x24(r3)
-/* 8036C50C 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C510 900DCBDC */ stw r0, lbl_805c69fc@sda21(0)
-/* 8036C514 80030000 */ lwz r0, 0(r3)
-/* 8036C518 5400063E */ clrlwi r0, r0, 0x18
-/* 8036C51C 980430E8 */ stb r0, 0x30e8(r4)
-/* 8036C520 800DCBDC */ lwz r0, lbl_805c69fc@sda21(0)
-/* 8036C524 5400063E */ clrlwi r0, r0, 0x18
-/* 8036C528 980430E9 */ stb r0, 0x30e9(r4)
-/* 8036C52C 48000028 */ b lbl_8036c554
-lbl_8036c530:
-/* 8036C530 80040034 */ lwz r0, 0x34(r4)
-/* 8036C534 28000000 */ cmplwi r0, 0
-/* 8036C538 4182001C */ beq- lbl_8036c554
-/* 8036C53C 886430E8 */ lbz r3, 0x30e8(r4)
-/* 8036C540 380DCA00 */ addi r0, 0, lbl_805c6820@sda21
-/* 8036C544 906DCA00 */ stw r3, lbl_805c6820@sda21(0)
-/* 8036C548 900DC9FC */ stw r0, lbl_805c681c@sda21(0)
-/* 8036C54C 880430E9 */ lbz r0, 0x30e9(r4)
-/* 8036C550 900DCBDC */ stw r0, lbl_805c69fc@sda21(0)
-lbl_8036c554:
-/* 8036C554 38000001 */ li r0, 0x1
-/* 8036C558 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C55C 900DCB04 */ stw r0, lbl_805c6924@sda21(0)
-/* 8036C560 80630030 */ lwz r3, 0x30(r3)
-/* 8036C564 28030000 */ cmplwi r3, 0
-/* 8036C568 40820010 */ bne- lbl_8036c578
-/* 8036C56C 3C60805E */ lis r3, 0x805e
-/* 8036C570 386329E0 */ addi r3, r3, 0x29e0
-/* 8036C574 48000004 */ b lbl_8036c578
-lbl_8036c578:
-/* 8036C578 480010B9 */ bl func_8036d630
-/* 8036C57C 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C580 80030030 */ lwz r0, 0x30(r3)
-/* 8036C584 28000000 */ cmplwi r0, 0
-/* 8036C588 40820030 */ bne- lbl_8036c5b8
-/* 8036C58C 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C590 28030000 */ cmplwi r3, 0
-/* 8036C594 41820024 */ beq- lbl_8036c5b8
-/* 8036C598 80030000 */ lwz r0, 0(r3)
-/* 8036C59C 28000002 */ cmplwi r0, 2
-/* 8036C5A0 40800018 */ bge- lbl_8036c5b8
-/* 8036C5A4 3C60805E */ lis r3, 0x805e
-/* 8036C5A8 386309C8 */ addi r3, r3, 0x9c8
-/* 8036C5AC 3803001F */ addi r0, r3, 0x1f
-/* 8036C5B0 54030034 */ rlwinm r3, r0, 0, 0, 0x1a
-/* 8036C5B4 4800107D */ bl func_8036d630
-lbl_8036c5b8:
-/* 8036C5B8 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C5BC 80630034 */ lwz r3, 0x34(r3)
-/* 8036C5C0 28030000 */ cmplwi r3, 0
-/* 8036C5C4 40820010 */ bne- lbl_8036c5d4
-/* 8036C5C8 3C608170 */ lis r3, 0x8170
-/* 8036C5CC 38630000 */ addi r3, r3, 0x0
-/* 8036C5D0 48000004 */ b lbl_8036c5d4
-lbl_8036c5d4:
-/* 8036C5D4 48001055 */ bl func_8036d628
-/* 8036C5D8 4800026D */ bl func_8036c844
-/* 8036C5DC 48004FE1 */ bl func_803715bc
-/* 8036C5E0 4800067D */ bl func_8036cc5c
-/* 8036C5E4 480034C9 */ bl func_8036faac
-/* 8036C5E8 48002569 */ bl func_8036eb50
-/* 8036C5EC 3C608037 */ lis r3, func_803707e4@ha
-/* 8036C5F0 388307E4 */ addi r4, r3, func_803707e4@l
-/* 8036C5F4 38600016 */ li r3, 0x16
-/* 8036C5F8 48002529 */ bl func_8036eb20
-/* 8036C5FC 48002071 */ bl func_8036e66c
-/* 8036C600 48001759 */ bl func_8036dd58
-/* 8036C604 480C0065 */ bl func_8042c668
-/* 8036C608 480C1315 */ bl func_8042d91c
-/* 8036C60C 480046DD */ bl func_80370ce8
-/* 8036C610 48005011 */ bl func_80371620
-/* 8036C614 48001025 */ bl func_8036d638
-/* 8036C618 4BFFFBB5 */ bl func_8036c1cc
-/* 8036C61C 54630080 */ rlwinm r3, r3, 0, 2, 0
-/* 8036C620 4BFFFBB5 */ bl func_8036c1d4
-/* 8036C624 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C628 3883002C */ addi r4, r3, 0x2c
-/* 8036C62C 80040000 */ lwz r0, 0(r4)
-/* 8036C630 540000C6 */ rlwinm r0, r0, 0, 3, 3
-/* 8036C634 28000000 */ cmplwi r0, 0
-/* 8036C638 41820014 */ beq- lbl_8036c64c
-/* 8036C63C 3C601000 */ lis r3, 0x1000
-/* 8036C640 38030004 */ addi r0, r3, 0x4
-/* 8036C644 90040000 */ stw r0, 0(r4)
-/* 8036C648 4800000C */ b lbl_8036c654
-lbl_8036c64c:
-/* 8036C64C 38000001 */ li r0, 0x1
-/* 8036C650 90040000 */ stw r0, 0(r4)
-lbl_8036c654:
-/* 8036C654 3C60CC00 */ lis r3, 0xcc00
-/* 8036C658 808DC9F8 */ lwz r4, lbl_805c6818@sda21(0)
-/* 8036C65C 38633000 */ addi r3, r3, 0x3000
-/* 8036C660 8003002C */ lwz r0, 0x2c(r3)
-/* 8036C664 8064002C */ lwz r3, 0x2c(r4)
-/* 8036C668 54000006 */ rlwinm r0, r0, 0, 0, 3
-/* 8036C66C 5400273E */ srwi r0, r0, 0x1c
-/* 8036C670 7C030214 */ add r0, r3, r0
-/* 8036C674 9004002C */ stw r0, 0x2c(r4)
-/* 8036C678 800DCA18 */ lwz r0, lbl_805c6838@sda21(0)
-/* 8036C67C 2C000000 */ cmpwi r0, 0x0
-/* 8036C680 40820008 */ bne- lbl_8036c688
-/* 8036C684 48003805 */ bl func_8036fe88
-lbl_8036c688:
-/* 8036C688 7FE3FB78 */ mr r3, r31
-/* 8036C68C 4CC63182 */ crclr 6
-/* 8036C690 48002025 */ bl func_8036e6b4
-/* 8036C694 387F0020 */ addi r3, r31, 0x20
-/* 8036C698 4CC63182 */ crclr 6
-/* 8036C69C 389F0038 */ addi r4, r31, 0x38
-/* 8036C6A0 38BF0044 */ addi r5, r31, 0x44
-/* 8036C6A4 48002011 */ bl func_8036e6b4
-/* 8036C6A8 387F0050 */ addi r3, r31, 0x50
-/* 8036C6AC 4CC63182 */ crclr 6
-/* 8036C6B0 48002005 */ bl func_8036e6b4
-/* 8036C6B4 806DC9F8 */ lwz r3, lbl_805c6818@sda21(0)
-/* 8036C6B8 28030000 */ cmplwi r3, 0
-/* 8036C6BC 41820010 */ beq- lbl_8036c6cc
-/* 8036C6C0 8083002C */ lwz r4, 0x2c(r3)
-/* 8036C6C4 28040000 */ cmplwi r4, 0
-/* 8036C6C8 40820010 */ bne- lbl_8036c6d8
-lbl_8036c6cc:
-/* 8036C6CC 3C601000 */ lis r3, 0x1000
-/* 8036C6D0 38830002 */ addi r4, r3, 0x2
-/* 8036C6D4 48000004 */ b lbl_8036c6d8
-lbl_8036c6d8:
-/* 8036C6D8 548000C6 */ rlwinm r0, r4, 0, 3, 3
-/* 8036C6DC 28000000 */ cmplwi r0, 0
-/* 8036C6E0 40820014 */ bne- lbl_8036c6f4
-/* 8036C6E4 4CC63182 */ crclr 6
-/* 8036C6E8 387F0060 */ addi r3, r31, 0x60
-/* 8036C6EC 48001FC9 */ bl func_8036e6b4
-/* 8036C6F0 4800008C */ b lbl_8036c77c
-lbl_8036c6f4:
-/* 8036C6F4 3C601000 */ lis r3, 0x1000
-/* 8036C6F8 38030002 */ addi r0, r3, 0x2
-/* 8036C6FC 7C040000 */ cmpw r4, r0
-/* 8036C700 41820048 */ beq- lbl_8036c748
-/* 8036C704 40800014 */ bge- lbl_8036c718
-/* 8036C708 7C041800 */ cmpw r4, r3
-/* 8036C70C 4182001C */ beq- lbl_8036c728
-/* 8036C710 40800028 */ bge- lbl_8036c738
-/* 8036C714 48000054 */ b lbl_8036c768
-lbl_8036c718:
-/* 8036C718 38030004 */ addi r0, r3, 0x4
-/* 8036C71C 7C040000 */ cmpw r4, r0
-/* 8036C720 40800048 */ bge- lbl_8036c768
-/* 8036C724 48000034 */ b lbl_8036c758
-lbl_8036c728:
-/* 8036C728 387F006C */ addi r3, r31, 0x6c
-/* 8036C72C 4CC63182 */ crclr 6
-/* 8036C730 48001F85 */ bl func_8036e6b4
-/* 8036C734 48000048 */ b lbl_8036c77c
-lbl_8036c738:
-/* 8036C738 387F007C */ addi r3, r31, 0x7c
-/* 8036C73C 4CC63182 */ crclr 6
-/* 8036C740 48001F75 */ bl func_8036e6b4
-/* 8036C744 48000038 */ b lbl_8036c77c
-lbl_8036c748:
-/* 8036C748 387F008C */ addi r3, r31, 0x8c
-/* 8036C74C 4CC63182 */ crclr 6
-/* 8036C750 48001F65 */ bl func_8036e6b4
-/* 8036C754 48000028 */ b lbl_8036c77c
-lbl_8036c758:
-/* 8036C758 387F009C */ addi r3, r31, 0x9c
-/* 8036C75C 4CC63182 */ crclr 6
-/* 8036C760 48001F55 */ bl func_8036e6b4
-/* 8036C764 48000018 */ b lbl_8036c77c
-lbl_8036c768:
-/* 8036C768 3C84F000 */ addis r4, r4, 0xf000
-/* 8036C76C 4CC63182 */ crclr 6
-/* 8036C770 387F00AC */ addi r3, r31, 0xac
-/* 8036C774 3884FFFD */ addi r4, r4, -0x3
-/* 8036C778 48001F3D */ bl func_8036e6b4
-lbl_8036c77c:
-/* 8036C77C 808DC9F8 */ lwz r4, lbl_805c6818@sda21(0)
-/* 8036C780 387F00C0 */ addi r3, r31, 0xc0
-/* 8036C784 4CC63182 */ crclr 6
-/* 8036C788 80040028 */ lwz r0, 0x28(r4)
-/* 8036C78C 5404653E */ srwi r4, r0, 0x14
-/* 8036C790 48001F25 */ bl func_8036e6b4
-/* 8036C794 48000E85 */ bl func_8036d618
-/* 8036C798 7C7D1B78 */ mr r29, r3
-/* 8036C79C 48000E85 */ bl func_8036d620
-/* 8036C7A0 7C641B78 */ mr r4, r3
-/* 8036C7A4 4CC63182 */ crclr 6
-/* 8036C7A8 7FA5EB78 */ mr r5, r29
-/* 8036C7AC 387F00D0 */ addi r3, r31, 0xd0
-/* 8036C7B0 48001F05 */ bl func_8036e6b4
-/* 8036C7B4 806DC9FC */ lwz r3, lbl_805c681c@sda21(0)
-/* 8036C7B8 28030000 */ cmplwi r3, 0
-/* 8036C7BC 41820014 */ beq- lbl_8036c7d0
-/* 8036C7C0 80030000 */ lwz r0, 0(r3)
-/* 8036C7C4 28000002 */ cmplwi r0, 2
-/* 8036C7C8 41800008 */ blt- lbl_8036c7d0
-/* 8036C7CC 48025B45 */ bl func_80392310
-lbl_8036c7d0:
-/* 8036C7D0 4BFFFB59 */ bl func_8036c328
-/* 8036C7D4 48002315 */ bl func_8036eae8
-/* 8036C7D8 800DCA18 */ lwz r0, lbl_805c6838@sda21(0)
-/* 8036C7DC 2C000000 */ cmpwi r0, 0x0
-/* 8036C7E0 40820048 */ bne- lbl_8036c828
-/* 8036C7E4 48008929 */ bl func_8037510c
-/* 8036C7E8 800DCA04 */ lwz r0, lbl_805c6824@sda21(0)
-/* 8036C7EC 2C000000 */ cmpwi r0, 0x0
-/* 8036C7F0 41820018 */ beq- lbl_8036c808
-/* 8036C7F4 3C600001 */ lis r3, 1
-/* 8036C7F8 38039000 */ addi r0, r3, -0x7000
-/* 8036C7FC 3C608000 */ lis r3, 0x8000
-/* 8036C800 B00330E6 */ sth r0, 0x30e6(r3)
-/* 8036C804 48000024 */ b lbl_8036c828
-lbl_8036c808:
-/* 8036C808 7FC3F378 */ mr r3, r30
-/* 8036C80C 38800020 */ li r4, 0x20
-/* 8036C810 480010D1 */ bl func_8036d8e0
-/* 8036C814 3C608037 */ lis r3, func_8036c450@ha
-/* 8036C818 38A3C450 */ addi r5, r3, func_8036c450@l
-/* 8036C81C 7FC4F378 */ mr r4, r30
-/* 8036C820 387E0020 */ addi r3, r30, 0x20
-/* 8036C824 4800A609 */ bl func_80376e2c
-lbl_8036c828:
-/* 8036C828 8001001C */ lwz r0, 0x1c(r1)
-/* 8036C82C 83E10014 */ lwz r31, 0x14(r1)
-/* 8036C830 83C10010 */ lwz r30, 0x10(r1)
-/* 8036C834 83A1000C */ lwz r29, 0xc(r1)
-/* 8036C838 38210018 */ addi r1, r1, 0x18
-/* 8036C83C 7C0803A6 */ mtlr r0
-/* 8036C840 4E800020 */ blr
-.size func_8036c48c, . - func_8036c48c
diff --git a/asm/Dolphin/os/OSInterrupt-data.s b/asm/Dolphin/os/OSInterrupt-data.s
deleted file mode 100644
index 614d667..0000000
--- a/asm/Dolphin/os/OSInterrupt-data.s
+++ /dev/null
@@ -1,23 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804ef518
-.type lbl_804ef518, @object
-lbl_804ef518:
-/* 804EF518 00000100 */ .4byte 0x00000100
-/* 804EF51C 00000040 */ .4byte 0x00000040
-/* 804EF520 F8000000 */ .4byte 0xf8000000
-/* 804EF524 00000200 */ .4byte 0x00000200
-/* 804EF528 00000080 */ .4byte 0x00000080
-/* 804EF52C 00003000 */ .4byte 0x00003000
-/* 804EF530 00000020 */ .4byte 0x00000020
-/* 804EF534 03FF8C00 */ .4byte 0x03ff8c00
-/* 804EF538 04000000 */ .4byte 0x04000000
-/* 804EF53C 00004000 */ .4byte 0x00004000
-/* 804EF540 FFFFFFFF */ .4byte 0xffffffff
-/* 804EF544 00000000 */ .4byte 0x00000000
-.size lbl_804ef518, . - lbl_804ef518
-
diff --git a/asm/Dolphin/os/OSInterrupt.s b/asm/Dolphin/os/OSInterrupt.s
deleted file mode 100644
index 4578586..0000000
--- a/asm/Dolphin/os/OSInterrupt.s
+++ /dev/null
@@ -1,696 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036ead4
-.type func_8036ead4, @function
-func_8036ead4:
-/* 8036EAD4 7C6000A6 */ mfmsr r3
-/* 8036EAD8 5464045E */ rlwinm r4, r3, 0, 0x11, 0xf
-/* 8036EADC 7C800124 */ mtmsr r4
-/* 8036EAE0 54638FFE */ rlwinm r3, r3, 0x11, 0x1f, 0x1f
-.size func_8036ead4, . - func_8036ead4
-
-
-.global func_8036eae4
-.type func_8036eae4, @function
-func_8036eae4:
-/* 8036EAE4 4E800020 */ blr
-.size func_8036eae4, . - func_8036eae4
-
-
-.global func_8036eae8
-.type func_8036eae8, @function
-func_8036eae8:
-/* 8036EAE8 7C6000A6 */ mfmsr r3
-/* 8036EAEC 60648000 */ ori r4, r3, 0x8000
-/* 8036EAF0 7C800124 */ mtmsr r4
-/* 8036EAF4 54638FFE */ rlwinm r3, r3, 0x11, 0x1f, 0x1f
-/* 8036EAF8 4E800020 */ blr
-.size func_8036eae8, . - func_8036eae8
-
-
-.global func_8036eafc
-.type func_8036eafc, @function
-func_8036eafc:
-/* 8036EAFC 2C030000 */ cmpwi r3, 0x0
-/* 8036EB00 7C8000A6 */ mfmsr r4
-/* 8036EB04 4182000C */ beq- lbl_8036eb10
-/* 8036EB08 60858000 */ ori r5, r4, 0x8000
-/* 8036EB0C 48000008 */ b lbl_8036eb14
-lbl_8036eb10:
-/* 8036EB10 5485045E */ rlwinm r5, r4, 0, 0x11, 0xf
-lbl_8036eb14:
-/* 8036EB14 7CA00124 */ mtmsr r5
-/* 8036EB18 54838FFE */ rlwinm r3, r4, 0x11, 0x1f, 0x1f
-/* 8036EB1C 4E800020 */ blr
-.size func_8036eafc, . - func_8036eafc
-
-
-.global func_8036eb20
-.type func_8036eb20, @function
-func_8036eb20:
-/* 8036EB20 7C600734 */ extsh r0, r3
-/* 8036EB24 806DCA48 */ lwz r3, lbl_805c6868@sda21(0)
-/* 8036EB28 5400103A */ slwi r0, r0, 2
-/* 8036EB2C 7CA30214 */ add r5, r3, r0
-/* 8036EB30 80650000 */ lwz r3, 0(r5)
-/* 8036EB34 90850000 */ stw r4, 0(r5)
-/* 8036EB38 4E800020 */ blr
-.size func_8036eb20, . - func_8036eb20
-
-
-.global func_8036eb3c
-.type func_8036eb3c, @function
-func_8036eb3c:
-/* 8036EB3C 7C600734 */ extsh r0, r3
-/* 8036EB40 806DCA48 */ lwz r3, lbl_805c6868@sda21(0)
-/* 8036EB44 5400103A */ slwi r0, r0, 2
-/* 8036EB48 7C63002E */ lwzx r3, r3, r0
-/* 8036EB4C 4E800020 */ blr
-.size func_8036eb3c, . - func_8036eb3c
-
-
-.global func_8036eb50
-.type func_8036eb50, @function
-func_8036eb50:
-/* 8036EB50 7C0802A6 */ mflr r0
-/* 8036EB54 90010004 */ stw r0, 4(r1)
-/* 8036EB58 9421FFF0 */ stwu r1, -0x10(r1)
-/* 8036EB5C 93E1000C */ stw r31, 0xc(r1)
-/* 8036EB60 3FE08000 */ lis r31, 0x8000
-/* 8036EB64 381F3040 */ addi r0, r31, 0x3040
-/* 8036EB68 900DCA48 */ stw r0, lbl_805c6868@sda21(0)
-/* 8036EB6C 38800000 */ li r4, 0x0
-/* 8036EB70 38A00080 */ li r5, 0x80
-/* 8036EB74 806DCA48 */ lwz r3, lbl_805c6868@sda21(0)
-/* 8036EB78 4BC9F7BD */ bl func_8000e334
-/* 8036EB7C 38000000 */ li r0, 0x0
-/* 8036EB80 901F00C4 */ stw r0, 0xc4(r31)
-/* 8036EB84 3C60CC00 */ lis r3, 0xcc00
-/* 8036EB88 38833000 */ addi r4, r3, 0x3000
-/* 8036EB8C 901F00C8 */ stw r0, 0xc8(r31)
-/* 8036EB90 380000F0 */ li r0, 0xf0
-/* 8036EB94 3860FFE0 */ li r3, -0x20
-/* 8036EB98 90040004 */ stw r0, 4(r4)
-/* 8036EB9C 48000301 */ bl func_8036ee9c
-/* 8036EBA0 3C608037 */ lis r3, func_8036f2f0@ha
-/* 8036EBA4 3883F2F0 */ addi r4, r3, func_8036f2f0@l
-/* 8036EBA8 38600004 */ li r3, 0x4
-/* 8036EBAC 4BFFDF41 */ bl func_8036caec
-/* 8036EBB0 80010014 */ lwz r0, 0x14(r1)
-/* 8036EBB4 83E1000C */ lwz r31, 0xc(r1)
-/* 8036EBB8 38210010 */ addi r1, r1, 0x10
-/* 8036EBBC 7C0803A6 */ mtlr r0
-/* 8036EBC0 4E800020 */ blr
-.size func_8036eb50, . - func_8036eb50
-
-
-.global func_8036ebc4
-.type func_8036ebc4, @function
-func_8036ebc4:
-/* 8036EBC4 7C600034 */ cntlzw r0, r3
-/* 8036EBC8 2C00000C */ cmpwi r0, 0xc
-/* 8036EBCC 40800024 */ bge- lbl_8036ebf0
-/* 8036EBD0 2C000008 */ cmpwi r0, 0x8
-/* 8036EBD4 418200FC */ beq- lbl_8036ecd0
-/* 8036EBD8 40800128 */ bge- lbl_8036ed00
-/* 8036EBDC 2C000005 */ cmpwi r0, 0x5
-/* 8036EBE0 4080009C */ bge- lbl_8036ec7c
-/* 8036EBE4 2C000000 */ cmpwi r0, 0x0
-/* 8036EBE8 40800028 */ bge- lbl_8036ec10
-/* 8036EBEC 480002AC */ b lbl_8036ee98
-lbl_8036ebf0:
-/* 8036EBF0 2C000011 */ cmpwi r0, 0x11
-/* 8036EBF4 40800010 */ bge- lbl_8036ec04
-/* 8036EBF8 2C00000F */ cmpwi r0, 0xf
-/* 8036EBFC 408001A8 */ bge- lbl_8036eda4
-/* 8036EC00 48000150 */ b lbl_8036ed50
-lbl_8036ec04:
-/* 8036EC04 2C00001B */ cmpwi r0, 0x1b
-/* 8036EC08 40800290 */ bge- lbl_8036ee98
-/* 8036EC0C 480001D8 */ b lbl_8036ede4
-lbl_8036ec10:
-/* 8036EC10 54800000 */ rlwinm r0, r4, 0, 0, 0
-/* 8036EC14 28000000 */ cmplwi r0, 0
-/* 8036EC18 38A00000 */ li r5, 0x0
-/* 8036EC1C 40820008 */ bne- lbl_8036ec24
-/* 8036EC20 60A50001 */ ori r5, r5, 1
-lbl_8036ec24:
-/* 8036EC24 54800042 */ rlwinm r0, r4, 0, 1, 1
-/* 8036EC28 28000000 */ cmplwi r0, 0
-/* 8036EC2C 40820008 */ bne- lbl_8036ec34
-/* 8036EC30 60A50002 */ ori r5, r5, 2
-lbl_8036ec34:
-/* 8036EC34 54800084 */ rlwinm r0, r4, 0, 2, 2
-/* 8036EC38 28000000 */ cmplwi r0, 0
-/* 8036EC3C 40820008 */ bne- lbl_8036ec44
-/* 8036EC40 60A50004 */ ori r5, r5, 4
-lbl_8036ec44:
-/* 8036EC44 548000C6 */ rlwinm r0, r4, 0, 3, 3
-/* 8036EC48 28000000 */ cmplwi r0, 0
-/* 8036EC4C 40820008 */ bne- lbl_8036ec54
-/* 8036EC50 60A50008 */ ori r5, r5, 8
-lbl_8036ec54:
-/* 8036EC54 54800108 */ rlwinm r0, r4, 0, 4, 4
-/* 8036EC58 28000000 */ cmplwi r0, 0
-/* 8036EC5C 40820008 */ bne- lbl_8036ec64
-/* 8036EC60 60A50010 */ ori r5, r5, 0x10
-lbl_8036ec64:
-/* 8036EC64 3C80CC00 */ lis r4, 0xcc00
-/* 8036EC68 54A0043E */ clrlwi r0, r5, 0x10
-/* 8036EC6C 38844000 */ addi r4, r4, 0x4000
-/* 8036EC70 B004001C */ sth r0, 0x1c(r4)
-/* 8036EC74 5463017E */ clrlwi r3, r3, 5
-/* 8036EC78 48000220 */ b lbl_8036ee98
-lbl_8036ec7c:
-/* 8036EC7C 3CA0CC00 */ lis r5, 0xcc00
-/* 8036EC80 38A55000 */ addi r5, r5, 0x5000
-/* 8036EC84 38A5000A */ addi r5, r5, 0xa
-/* 8036EC88 5480014A */ rlwinm r0, r4, 0, 5, 5
-/* 8036EC8C A0C50000 */ lhz r6, 0(r5)
-/* 8036EC90 28000000 */ cmplwi r0, 0
-/* 8036EC94 54C6076C */ rlwinm r6, r6, 0, 0x1d, 0x16
-/* 8036EC98 40820008 */ bne- lbl_8036eca0
-/* 8036EC9C 60C60010 */ ori r6, r6, 0x10
-lbl_8036eca0:
-/* 8036ECA0 5480018C */ rlwinm r0, r4, 0, 6, 6
-/* 8036ECA4 28000000 */ cmplwi r0, 0
-/* 8036ECA8 40820008 */ bne- lbl_8036ecb0
-/* 8036ECAC 60C60040 */ ori r6, r6, 0x40
-lbl_8036ecb0:
-/* 8036ECB0 548001CE */ rlwinm r0, r4, 0, 7, 7
-/* 8036ECB4 28000000 */ cmplwi r0, 0
-/* 8036ECB8 40820008 */ bne- lbl_8036ecc0
-/* 8036ECBC 60C60100 */ ori r6, r6, 0x100
-lbl_8036ecc0:
-/* 8036ECC0 54C0043E */ clrlwi r0, r6, 0x10
-/* 8036ECC4 B0050000 */ sth r0, 0(r5)
-/* 8036ECC8 54630208 */ rlwinm r3, r3, 0, 8, 4
-/* 8036ECCC 480001CC */ b lbl_8036ee98
-lbl_8036ecd0:
-/* 8036ECD0 54800210 */ rlwinm r0, r4, 0, 8, 8
-/* 8036ECD4 3C80CC00 */ lis r4, 0xcc00
-/* 8036ECD8 28000000 */ cmplwi r0, 0
-/* 8036ECDC 80A46C00 */ lwz r5, 0x6c00(r4)
-/* 8036ECE0 3800FFD3 */ li r0, -0x2d
-/* 8036ECE4 7CA50038 */ and r5, r5, r0
-/* 8036ECE8 40820008 */ bne- lbl_8036ecf0
-/* 8036ECEC 60A50004 */ ori r5, r5, 4
-lbl_8036ecf0:
-/* 8036ECF0 3C80CC00 */ lis r4, 0xcc00
-/* 8036ECF4 90A46C00 */ stw r5, 0x6c00(r4)
-/* 8036ECF8 5463024E */ rlwinm r3, r3, 0, 9, 7
-/* 8036ECFC 4800019C */ b lbl_8036ee98
-lbl_8036ed00:
-/* 8036ED00 54800252 */ rlwinm r0, r4, 0, 9, 9
-/* 8036ED04 3CA0CC00 */ lis r5, 0xcc00
-/* 8036ED08 28000000 */ cmplwi r0, 0
-/* 8036ED0C 80A56800 */ lwz r5, 0x6800(r5)
-/* 8036ED10 3800D3F0 */ li r0, -0x2c10
-/* 8036ED14 7CA50038 */ and r5, r5, r0
-/* 8036ED18 40820008 */ bne- lbl_8036ed20
-/* 8036ED1C 60A50001 */ ori r5, r5, 1
-lbl_8036ed20:
-/* 8036ED20 54800294 */ rlwinm r0, r4, 0, 0xa, 0xa
-/* 8036ED24 28000000 */ cmplwi r0, 0
-/* 8036ED28 40820008 */ bne- lbl_8036ed30
-/* 8036ED2C 60A50004 */ ori r5, r5, 4
-lbl_8036ed30:
-/* 8036ED30 548002D6 */ rlwinm r0, r4, 0, 0xb, 0xb
-/* 8036ED34 28000000 */ cmplwi r0, 0
-/* 8036ED38 40820008 */ bne- lbl_8036ed40
-/* 8036ED3C 60A50400 */ ori r5, r5, 0x400
-lbl_8036ed40:
-/* 8036ED40 3C80CC00 */ lis r4, 0xcc00
-/* 8036ED44 90A46800 */ stw r5, 0x6800(r4)
-/* 8036ED48 54630310 */ rlwinm r3, r3, 0, 0xc, 8
-/* 8036ED4C 4800014C */ b lbl_8036ee98
-lbl_8036ed50:
-/* 8036ED50 3CA0CC00 */ lis r5, 0xcc00
-/* 8036ED54 38C56800 */ addi r6, r5, 0x6800
-/* 8036ED58 38C60014 */ addi r6, r6, 0x14
-/* 8036ED5C 54800318 */ rlwinm r0, r4, 0, 0xc, 0xc
-/* 8036ED60 80E60000 */ lwz r7, 0(r6)
-/* 8036ED64 38A0F3F0 */ li r5, -0xc10
-/* 8036ED68 28000000 */ cmplwi r0, 0
-/* 8036ED6C 7CE72838 */ and r7, r7, r5
-/* 8036ED70 40820008 */ bne- lbl_8036ed78
-/* 8036ED74 60E70001 */ ori r7, r7, 1
-lbl_8036ed78:
-/* 8036ED78 5480035A */ rlwinm r0, r4, 0, 0xd, 0xd
-/* 8036ED7C 28000000 */ cmplwi r0, 0
-/* 8036ED80 40820008 */ bne- lbl_8036ed88
-/* 8036ED84 60E70004 */ ori r7, r7, 4
-lbl_8036ed88:
-/* 8036ED88 5480039C */ rlwinm r0, r4, 0, 0xe, 0xe
-/* 8036ED8C 28000000 */ cmplwi r0, 0
-/* 8036ED90 40820008 */ bne- lbl_8036ed98
-/* 8036ED94 60E70400 */ ori r7, r7, 0x400
-lbl_8036ed98:
-/* 8036ED98 90E60000 */ stw r7, 0(r6)
-/* 8036ED9C 546303D6 */ rlwinm r3, r3, 0, 0xf, 0xb
-/* 8036EDA0 480000F8 */ b lbl_8036ee98
-lbl_8036eda4:
-/* 8036EDA4 3CA0CC00 */ lis r5, 0xcc00
-/* 8036EDA8 38A56800 */ addi r5, r5, 0x6800
-/* 8036EDAC 38A50028 */ addi r5, r5, 0x28
-/* 8036EDB0 548003DE */ rlwinm r0, r4, 0, 0xf, 0xf
-/* 8036EDB4 80C50000 */ lwz r6, 0(r5)
-/* 8036EDB8 28000000 */ cmplwi r0, 0
-/* 8036EDBC 54C60036 */ rlwinm r6, r6, 0, 0, 0x1b
-/* 8036EDC0 40820008 */ bne- lbl_8036edc8
-/* 8036EDC4 60C60001 */ ori r6, r6, 1
-lbl_8036edc8:
-/* 8036EDC8 54800420 */ rlwinm r0, r4, 0, 0x10, 0x10
-/* 8036EDCC 28000000 */ cmplwi r0, 0
-/* 8036EDD0 40820008 */ bne- lbl_8036edd8
-/* 8036EDD4 60C60004 */ ori r6, r6, 4
-lbl_8036edd8:
-/* 8036EDD8 90C50000 */ stw r6, 0(r5)
-/* 8036EDDC 5463045C */ rlwinm r3, r3, 0, 0x11, 0xe
-/* 8036EDE0 480000B8 */ b lbl_8036ee98
-lbl_8036ede4:
-/* 8036EDE4 54800462 */ rlwinm r0, r4, 0, 0x11, 0x11
-/* 8036EDE8 28000000 */ cmplwi r0, 0
-/* 8036EDEC 38A000F0 */ li r5, 0xf0
-/* 8036EDF0 40820008 */ bne- lbl_8036edf8
-/* 8036EDF4 60A50800 */ ori r5, r5, 0x800
-lbl_8036edf8:
-/* 8036EDF8 54800528 */ rlwinm r0, r4, 0, 0x14, 0x14
-/* 8036EDFC 28000000 */ cmplwi r0, 0
-/* 8036EE00 40820008 */ bne- lbl_8036ee08
-/* 8036EE04 60A50008 */ ori r5, r5, 8
-lbl_8036ee08:
-/* 8036EE08 5480056A */ rlwinm r0, r4, 0, 0x15, 0x15
-/* 8036EE0C 28000000 */ cmplwi r0, 0
-/* 8036EE10 40820008 */ bne- lbl_8036ee18
-/* 8036EE14 60A50004 */ ori r5, r5, 4
-lbl_8036ee18:
-/* 8036EE18 548005AC */ rlwinm r0, r4, 0, 0x16, 0x16
-/* 8036EE1C 28000000 */ cmplwi r0, 0
-/* 8036EE20 40820008 */ bne- lbl_8036ee28
-/* 8036EE24 60A50002 */ ori r5, r5, 2
-lbl_8036ee28:
-/* 8036EE28 548005EE */ rlwinm r0, r4, 0, 0x17, 0x17
-/* 8036EE2C 28000000 */ cmplwi r0, 0
-/* 8036EE30 40820008 */ bne- lbl_8036ee38
-/* 8036EE34 60A50001 */ ori r5, r5, 1
-lbl_8036ee38:
-/* 8036EE38 54800630 */ rlwinm r0, r4, 0, 0x18, 0x18
-/* 8036EE3C 28000000 */ cmplwi r0, 0
-/* 8036EE40 40820008 */ bne- lbl_8036ee48
-/* 8036EE44 60A50100 */ ori r5, r5, 0x100
-lbl_8036ee48:
-/* 8036EE48 54800672 */ rlwinm r0, r4, 0, 0x19, 0x19
-/* 8036EE4C 28000000 */ cmplwi r0, 0
-/* 8036EE50 40820008 */ bne- lbl_8036ee58
-/* 8036EE54 60A51000 */ ori r5, r5, 0x1000
-lbl_8036ee58:
-/* 8036EE58 548004A4 */ rlwinm r0, r4, 0, 0x12, 0x12
-/* 8036EE5C 28000000 */ cmplwi r0, 0
-/* 8036EE60 40820008 */ bne- lbl_8036ee68
-/* 8036EE64 60A50200 */ ori r5, r5, 0x200
-lbl_8036ee68:
-/* 8036EE68 548004E6 */ rlwinm r0, r4, 0, 0x13, 0x13
-/* 8036EE6C 28000000 */ cmplwi r0, 0
-/* 8036EE70 40820008 */ bne- lbl_8036ee78
-/* 8036EE74 60A50400 */ ori r5, r5, 0x400
-lbl_8036ee78:
-/* 8036EE78 548006B4 */ rlwinm r0, r4, 0, 0x1a, 0x1a
-/* 8036EE7C 28000000 */ cmplwi r0, 0
-/* 8036EE80 40820008 */ bne- lbl_8036ee88
-/* 8036EE84 60A52000 */ ori r5, r5, 0x2000
-lbl_8036ee88:
-/* 8036EE88 3C80CC00 */ lis r4, 0xcc00
-/* 8036EE8C 38843000 */ addi r4, r4, 0x3000
-/* 8036EE90 90A40004 */ stw r5, 4(r4)
-/* 8036EE94 546306E0 */ rlwinm r3, r3, 0, 0x1b, 0x10
-lbl_8036ee98:
-/* 8036EE98 4E800020 */ blr
-.size func_8036ebc4, . - func_8036ebc4
-
-
-.global func_8036ee9c
-.type func_8036ee9c, @function
-func_8036ee9c:
-/* 8036EE9C 7C0802A6 */ mflr r0
-/* 8036EEA0 90010004 */ stw r0, 4(r1)
-/* 8036EEA4 9421FFE0 */ stwu r1, -0x20(r1)
-/* 8036EEA8 93E1001C */ stw r31, 0x1c(r1)
-/* 8036EEAC 93C10018 */ stw r30, 0x18(r1)
-/* 8036EEB0 93A10014 */ stw r29, 0x14(r1)
-/* 8036EEB4 7C7F1B78 */ mr r31, r3
-/* 8036EEB8 4BFFFC1D */ bl func_8036ead4
-/* 8036EEBC 3C808000 */ lis r4, 0x8000
-/* 8036EEC0 83A400C4 */ lwz r29, 0xc4(r4)
-/* 8036EEC4 7C7E1B78 */ mr r30, r3
-/* 8036EEC8 80A400C8 */ lwz r5, 0xc8(r4)
-/* 8036EECC 7FA02B78 */ or r0, r29, r5
-/* 8036EED0 7FE30078 */ andc r3, r31, r0
-/* 8036EED4 7FFFEB78 */ or r31, r31, r29
-/* 8036EED8 93E400C4 */ stw r31, 0xc4(r4)
-/* 8036EEDC 7FFF2B78 */ or r31, r31, r5
-/* 8036EEE0 48000004 */ b lbl_8036eee4
-lbl_8036eee4:
-/* 8036EEE4 48000004 */ b lbl_8036eee8
-lbl_8036eee8:
-/* 8036EEE8 4800000C */ b lbl_8036eef4
-lbl_8036eeec:
-/* 8036EEEC 7FE4FB78 */ mr r4, r31
-/* 8036EEF0 4BFFFCD5 */ bl func_8036ebc4
-lbl_8036eef4:
-/* 8036EEF4 28030000 */ cmplwi r3, 0
-/* 8036EEF8 4082FFF4 */ bne+ lbl_8036eeec
-/* 8036EEFC 7FC3F378 */ mr r3, r30
-/* 8036EF00 4BFFFBFD */ bl func_8036eafc
-/* 8036EF04 7FA3EB78 */ mr r3, r29
-/* 8036EF08 80010024 */ lwz r0, 0x24(r1)
-/* 8036EF0C 83E1001C */ lwz r31, 0x1c(r1)
-/* 8036EF10 83C10018 */ lwz r30, 0x18(r1)
-/* 8036EF14 83A10014 */ lwz r29, 0x14(r1)
-/* 8036EF18 38210020 */ addi r1, r1, 0x20
-/* 8036EF1C 7C0803A6 */ mtlr r0
-/* 8036EF20 4E800020 */ blr
-.size func_8036ee9c, . - func_8036ee9c
-
-
-.global func_8036ef24
-.type func_8036ef24, @function
-func_8036ef24:
-/* 8036EF24 7C0802A6 */ mflr r0
-/* 8036EF28 90010004 */ stw r0, 4(r1)
-/* 8036EF2C 9421FFE0 */ stwu r1, -0x20(r1)
-/* 8036EF30 93E1001C */ stw r31, 0x1c(r1)
-/* 8036EF34 93C10018 */ stw r30, 0x18(r1)
-/* 8036EF38 93A10014 */ stw r29, 0x14(r1)
-/* 8036EF3C 7C7F1B78 */ mr r31, r3
-/* 8036EF40 4BFFFB95 */ bl func_8036ead4
-/* 8036EF44 3C808000 */ lis r4, 0x8000
-/* 8036EF48 83A400C4 */ lwz r29, 0xc4(r4)
-/* 8036EF4C 7C7E1B78 */ mr r30, r3
-/* 8036EF50 80A400C8 */ lwz r5, 0xc8(r4)
-/* 8036EF54 7FA02B78 */ or r0, r29, r5
-/* 8036EF58 7FE30038 */ and r3, r31, r0
-/* 8036EF5C 7FBFF878 */ andc r31, r29, r31
-/* 8036EF60 93E400C4 */ stw r31, 0xc4(r4)
-/* 8036EF64 7FFF2B78 */ or r31, r31, r5
-/* 8036EF68 48000004 */ b lbl_8036ef6c
-lbl_8036ef6c:
-/* 8036EF6C 48000004 */ b lbl_8036ef70
-lbl_8036ef70:
-/* 8036EF70 4800000C */ b lbl_8036ef7c
-lbl_8036ef74:
-/* 8036EF74 7FE4FB78 */ mr r4, r31
-/* 8036EF78 4BFFFC4D */ bl func_8036ebc4
-lbl_8036ef7c:
-/* 8036EF7C 28030000 */ cmplwi r3, 0
-/* 8036EF80 4082FFF4 */ bne+ lbl_8036ef74
-/* 8036EF84 7FC3F378 */ mr r3, r30
-/* 8036EF88 4BFFFB75 */ bl func_8036eafc
-/* 8036EF8C 7FA3EB78 */ mr r3, r29
-/* 8036EF90 80010024 */ lwz r0, 0x24(r1)
-/* 8036EF94 83E1001C */ lwz r31, 0x1c(r1)
-/* 8036EF98 83C10018 */ lwz r30, 0x18(r1)
-/* 8036EF9C 83A10014 */ lwz r29, 0x14(r1)
-/* 8036EFA0 38210020 */ addi r1, r1, 0x20
-/* 8036EFA4 7C0803A6 */ mtlr r0
-/* 8036EFA8 4E800020 */ blr
-.size func_8036ef24, . - func_8036ef24
-
-
-.global func_8036efac
-.type func_8036efac, @function
-func_8036efac:
-/* 8036EFAC 7C0802A6 */ mflr r0
-/* 8036EFB0 90010004 */ stw r0, 4(r1)
-/* 8036EFB4 9421FFD8 */ stwu r1, -0x28(r1)
-/* 8036EFB8 93E10024 */ stw r31, 0x24(r1)
-/* 8036EFBC 93C10020 */ stw r30, 0x20(r1)
-/* 8036EFC0 93A1001C */ stw r29, 0x1c(r1)
-/* 8036EFC4 7C9E2378 */ mr r30, r4
-/* 8036EFC8 3C60CC00 */ lis r3, 0xcc00
-/* 8036EFCC 83E33000 */ lwz r31, 0x3000(r3)
-/* 8036EFD0 57FF041C */ rlwinm r31, r31, 0, 0x10, 0xe
-/* 8036EFD4 281F0000 */ cmplwi r31, 0
-/* 8036EFD8 41820018 */ beq- lbl_8036eff0
-/* 8036EFDC 38633000 */ addi r3, r3, 0x3000
-/* 8036EFE0 80030004 */ lwz r0, 4(r3)
-/* 8036EFE4 7FE00038 */ and r0, r31, r0
-/* 8036EFE8 28000000 */ cmplwi r0, 0
-/* 8036EFEC 4082000C */ bne- lbl_8036eff8
-lbl_8036eff0:
-/* 8036EFF0 7FC3F378 */ mr r3, r30
-/* 8036EFF4 4BFFF18D */ bl func_8036e180
-lbl_8036eff8:
-/* 8036EFF8 57E00630 */ rlwinm r0, r31, 0, 0x18, 0x18
-/* 8036EFFC 28000000 */ cmplwi r0, 0
-/* 8036F000 38000000 */ li r0, 0x0
-/* 8036F004 41820060 */ beq- lbl_8036f064
-/* 8036F008 3C60CC00 */ lis r3, 0xcc00
-/* 8036F00C 38634000 */ addi r3, r3, 0x4000
-/* 8036F010 A083001E */ lhz r4, 0x1e(r3)
-/* 8036F014 548307FE */ clrlwi r3, r4, 0x1f
-/* 8036F018 28030000 */ cmplwi r3, 0
-/* 8036F01C 41820008 */ beq- lbl_8036f024
-/* 8036F020 64008000 */ oris r0, r0, 0x8000
-lbl_8036f024:
-/* 8036F024 548307BC */ rlwinm r3, r4, 0, 0x1e, 0x1e
-/* 8036F028 28030000 */ cmplwi r3, 0
-/* 8036F02C 41820008 */ beq- lbl_8036f034
-/* 8036F030 64004000 */ oris r0, r0, 0x4000
-lbl_8036f034:
-/* 8036F034 5483077A */ rlwinm r3, r4, 0, 0x1d, 0x1d
-/* 8036F038 28030000 */ cmplwi r3, 0
-/* 8036F03C 41820008 */ beq- lbl_8036f044
-/* 8036F040 64002000 */ oris r0, r0, 0x2000
-lbl_8036f044:
-/* 8036F044 54830738 */ rlwinm r3, r4, 0, 0x1c, 0x1c
-/* 8036F048 28030000 */ cmplwi r3, 0
-/* 8036F04C 41820008 */ beq- lbl_8036f054
-/* 8036F050 64001000 */ oris r0, r0, 0x1000
-lbl_8036f054:
-/* 8036F054 548306F6 */ rlwinm r3, r4, 0, 0x1b, 0x1b
-/* 8036F058 28030000 */ cmplwi r3, 0
-/* 8036F05C 41820008 */ beq- lbl_8036f064
-/* 8036F060 64000800 */ oris r0, r0, 0x800
-lbl_8036f064:
-/* 8036F064 57E30672 */ rlwinm r3, r31, 0, 0x19, 0x19
-/* 8036F068 28030000 */ cmplwi r3, 0
-/* 8036F06C 41820040 */ beq- lbl_8036f0ac
-/* 8036F070 3C60CC00 */ lis r3, 0xcc00
-/* 8036F074 38635000 */ addi r3, r3, 0x5000
-/* 8036F078 A083000A */ lhz r4, 0xa(r3)
-/* 8036F07C 54830738 */ rlwinm r3, r4, 0, 0x1c, 0x1c
-/* 8036F080 28030000 */ cmplwi r3, 0
-/* 8036F084 41820008 */ beq- lbl_8036f08c
-/* 8036F088 64000400 */ oris r0, r0, 0x400
-lbl_8036f08c:
-/* 8036F08C 548306B4 */ rlwinm r3, r4, 0, 0x1a, 0x1a
-/* 8036F090 28030000 */ cmplwi r3, 0
-/* 8036F094 41820008 */ beq- lbl_8036f09c
-/* 8036F098 64000200 */ oris r0, r0, 0x200
-lbl_8036f09c:
-/* 8036F09C 54830630 */ rlwinm r3, r4, 0, 0x18, 0x18
-/* 8036F0A0 28030000 */ cmplwi r3, 0
-/* 8036F0A4 41820008 */ beq- lbl_8036f0ac
-/* 8036F0A8 64000100 */ oris r0, r0, 0x100
-lbl_8036f0ac:
-/* 8036F0AC 57E306B4 */ rlwinm r3, r31, 0, 0x1a, 0x1a
-/* 8036F0B0 28030000 */ cmplwi r3, 0
-/* 8036F0B4 4182001C */ beq- lbl_8036f0d0
-/* 8036F0B8 3C60CC00 */ lis r3, 0xcc00
-/* 8036F0BC 80636C00 */ lwz r3, 0x6c00(r3)
-/* 8036F0C0 54630738 */ rlwinm r3, r3, 0, 0x1c, 0x1c
-/* 8036F0C4 28030000 */ cmplwi r3, 0
-/* 8036F0C8 41820008 */ beq- lbl_8036f0d0
-/* 8036F0CC 64000080 */ oris r0, r0, 0x80
-lbl_8036f0d0:
-/* 8036F0D0 57E306F6 */ rlwinm r3, r31, 0, 0x1b, 0x1b
-/* 8036F0D4 28030000 */ cmplwi r3, 0
-/* 8036F0D8 418200A4 */ beq- lbl_8036f17c
-/* 8036F0DC 3C60CC00 */ lis r3, 0xcc00
-/* 8036F0E0 80836800 */ lwz r4, 0x6800(r3)
-/* 8036F0E4 548307BC */ rlwinm r3, r4, 0, 0x1e, 0x1e
-/* 8036F0E8 28030000 */ cmplwi r3, 0
-/* 8036F0EC 41820008 */ beq- lbl_8036f0f4
-/* 8036F0F0 64000040 */ oris r0, r0, 0x40
-lbl_8036f0f4:
-/* 8036F0F4 54830738 */ rlwinm r3, r4, 0, 0x1c, 0x1c
-/* 8036F0F8 28030000 */ cmplwi r3, 0
-/* 8036F0FC 41820008 */ beq- lbl_8036f104
-/* 8036F100 64000020 */ oris r0, r0, 0x20
-lbl_8036f104:
-/* 8036F104 54830528 */ rlwinm r3, r4, 0, 0x14, 0x14
-/* 8036F108 28030000 */ cmplwi r3, 0
-/* 8036F10C 41820008 */ beq- lbl_8036f114
-/* 8036F110 64000010 */ oris r0, r0, 0x10
-lbl_8036f114:
-/* 8036F114 3C60CC00 */ lis r3, 0xcc00
-/* 8036F118 38636800 */ addi r3, r3, 0x6800
-/* 8036F11C 80830014 */ lwz r4, 0x14(r3)
-/* 8036F120 548307BC */ rlwinm r3, r4, 0, 0x1e, 0x1e
-/* 8036F124 28030000 */ cmplwi r3, 0
-/* 8036F128 41820008 */ beq- lbl_8036f130
-/* 8036F12C 64000008 */ oris r0, r0, 8
-lbl_8036f130:
-/* 8036F130 54830738 */ rlwinm r3, r4, 0, 0x1c, 0x1c
-/* 8036F134 28030000 */ cmplwi r3, 0
-/* 8036F138 41820008 */ beq- lbl_8036f140
-/* 8036F13C 64000004 */ oris r0, r0, 4
-lbl_8036f140:
-/* 8036F140 54830528 */ rlwinm r3, r4, 0, 0x14, 0x14
-/* 8036F144 28030000 */ cmplwi r3, 0
-/* 8036F148 41820008 */ beq- lbl_8036f150
-/* 8036F14C 64000002 */ oris r0, r0, 2
-lbl_8036f150:
-/* 8036F150 3C60CC00 */ lis r3, 0xcc00
-/* 8036F154 38636800 */ addi r3, r3, 0x6800
-/* 8036F158 80830028 */ lwz r4, 0x28(r3)
-/* 8036F15C 548307BC */ rlwinm r3, r4, 0, 0x1e, 0x1e
-/* 8036F160 28030000 */ cmplwi r3, 0
-/* 8036F164 41820008 */ beq- lbl_8036f16c
-/* 8036F168 64000001 */ oris r0, r0, 1
-lbl_8036f16c:
-/* 8036F16C 54830738 */ rlwinm r3, r4, 0, 0x1c, 0x1c
-/* 8036F170 28030000 */ cmplwi r3, 0
-/* 8036F174 41820008 */ beq- lbl_8036f17c
-/* 8036F178 60008000 */ ori r0, r0, 0x8000
-lbl_8036f17c:
-/* 8036F17C 57E304A4 */ rlwinm r3, r31, 0, 0x12, 0x12
-/* 8036F180 28030000 */ cmplwi r3, 0
-/* 8036F184 41820008 */ beq- lbl_8036f18c
-/* 8036F188 60000020 */ ori r0, r0, 0x20
-lbl_8036f18c:
-/* 8036F18C 57E304E6 */ rlwinm r3, r31, 0, 0x13, 0x13
-/* 8036F190 28030000 */ cmplwi r3, 0
-/* 8036F194 41820008 */ beq- lbl_8036f19c
-/* 8036F198 60000040 */ ori r0, r0, 0x40
-lbl_8036f19c:
-/* 8036F19C 57E3056A */ rlwinm r3, r31, 0, 0x15, 0x15
-/* 8036F1A0 28030000 */ cmplwi r3, 0
-/* 8036F1A4 41820008 */ beq- lbl_8036f1ac
-/* 8036F1A8 60001000 */ ori r0, r0, 0x1000
-lbl_8036f1ac:
-/* 8036F1AC 57E305AC */ rlwinm r3, r31, 0, 0x16, 0x16
-/* 8036F1B0 28030000 */ cmplwi r3, 0
-/* 8036F1B4 41820008 */ beq- lbl_8036f1bc
-/* 8036F1B8 60002000 */ ori r0, r0, 0x2000
-lbl_8036f1bc:
-/* 8036F1BC 57E305EE */ rlwinm r3, r31, 0, 0x17, 0x17
-/* 8036F1C0 28030000 */ cmplwi r3, 0
-/* 8036F1C4 41820008 */ beq- lbl_8036f1cc
-/* 8036F1C8 60000080 */ ori r0, r0, 0x80
-lbl_8036f1cc:
-/* 8036F1CC 57E30738 */ rlwinm r3, r31, 0, 0x1c, 0x1c
-/* 8036F1D0 28030000 */ cmplwi r3, 0
-/* 8036F1D4 41820008 */ beq- lbl_8036f1dc
-/* 8036F1D8 60000800 */ ori r0, r0, 0x800
-lbl_8036f1dc:
-/* 8036F1DC 57E3077A */ rlwinm r3, r31, 0, 0x1d, 0x1d
-/* 8036F1E0 28030000 */ cmplwi r3, 0
-/* 8036F1E4 41820008 */ beq- lbl_8036f1ec
-/* 8036F1E8 60000400 */ ori r0, r0, 0x400
-lbl_8036f1ec:
-/* 8036F1EC 57E307BC */ rlwinm r3, r31, 0, 0x1e, 0x1e
-/* 8036F1F0 28030000 */ cmplwi r3, 0
-/* 8036F1F4 41820008 */ beq- lbl_8036f1fc
-/* 8036F1F8 60000200 */ ori r0, r0, 0x200
-lbl_8036f1fc:
-/* 8036F1FC 57E30528 */ rlwinm r3, r31, 0, 0x14, 0x14
-/* 8036F200 28030000 */ cmplwi r3, 0
-/* 8036F204 41820008 */ beq- lbl_8036f20c
-/* 8036F208 60004000 */ ori r0, r0, 0x4000
-lbl_8036f20c:
-/* 8036F20C 57E307FE */ clrlwi r3, r31, 0x1f
-/* 8036F210 28030000 */ cmplwi r3, 0
-/* 8036F214 41820008 */ beq- lbl_8036f21c
-/* 8036F218 60000100 */ ori r0, r0, 0x100
-lbl_8036f21c:
-/* 8036F21C 3C608000 */ lis r3, 0x8000
-/* 8036F220 808300C4 */ lwz r4, 0xc4(r3)
-/* 8036F224 806300C8 */ lwz r3, 0xc8(r3)
-/* 8036F228 7C831B78 */ or r3, r4, r3
-/* 8036F22C 7C041878 */ andc r4, r0, r3
-/* 8036F230 28040000 */ cmplwi r4, 0
-/* 8036F234 41820098 */ beq- lbl_8036f2cc
-/* 8036F238 3C60804F */ lis r3, lbl_804ef518@ha
-/* 8036F23C 3803F518 */ addi r0, r3, lbl_804ef518@l
-/* 8036F240 7C030378 */ mr r3, r0
-/* 8036F244 48000004 */ b lbl_8036f248
-lbl_8036f248:
-/* 8036F248 48000004 */ b lbl_8036f24c
-lbl_8036f24c:
-/* 8036F24C 80030000 */ lwz r0, 0(r3)
-/* 8036F250 7C800038 */ and r0, r4, r0
-/* 8036F254 28000000 */ cmplwi r0, 0
-/* 8036F258 41820010 */ beq- lbl_8036f268
-/* 8036F25C 7C000034 */ cntlzw r0, r0
-/* 8036F260 7C1D0734 */ extsh r29, r0
-/* 8036F264 4800000C */ b lbl_8036f270
-lbl_8036f268:
-/* 8036F268 38630004 */ addi r3, r3, 0x4
-/* 8036F26C 4BFFFFE0 */ b lbl_8036f24c
-lbl_8036f270:
-/* 8036F270 806DCA48 */ lwz r3, lbl_805c6868@sda21(0)
-/* 8036F274 57A0103A */ slwi r0, r29, 2
-/* 8036F278 7FE3002E */ lwzx r31, r3, r0
-/* 8036F27C 281F0000 */ cmplwi r31, 0
-/* 8036F280 4182004C */ beq- lbl_8036f2cc
-/* 8036F284 2C1D0004 */ cmpwi r29, 0x4
-/* 8036F288 4081001C */ ble- lbl_8036f2a4
-/* 8036F28C B3ADCA50 */ sth r29, lbl_805c6870@sda21(0)
-/* 8036F290 48003535 */ bl func_803727c4
-/* 8036F294 908DCA5C */ stw r4, lbl_805c687c@sda21(0)
-/* 8036F298 906DCA58 */ stw r3, lbl_805c6878@sda21(0)
-/* 8036F29C 801E0198 */ lwz r0, 0x198(r30)
-/* 8036F2A0 900DCA4C */ stw r0, lbl_805c686c@sda21(0)
-lbl_8036f2a4:
-/* 8036F2A4 48002511 */ bl func_803717b4
-/* 8036F2A8 7FA3EB78 */ mr r3, r29
-/* 8036F2AC 7FC4F378 */ mr r4, r30
-/* 8036F2B0 7FECFB78 */ mr r12, r31
-/* 8036F2B4 7D8803A6 */ mtlr r12
-/* 8036F2B8 4E800021 */ blrl
-/* 8036F2BC 48002539 */ bl func_803717f4
-/* 8036F2C0 48002A29 */ bl func_80371ce8
-/* 8036F2C4 7FC3F378 */ mr r3, r30
-/* 8036F2C8 4BFFEEB9 */ bl func_8036e180
-lbl_8036f2cc:
-/* 8036F2CC 7FC3F378 */ mr r3, r30
-/* 8036F2D0 4BFFEEB1 */ bl func_8036e180
-/* 8036F2D4 8001002C */ lwz r0, 0x2c(r1)
-/* 8036F2D8 83E10024 */ lwz r31, 0x24(r1)
-/* 8036F2DC 83C10020 */ lwz r30, 0x20(r1)
-/* 8036F2E0 83A1001C */ lwz r29, 0x1c(r1)
-/* 8036F2E4 38210028 */ addi r1, r1, 0x28
-/* 8036F2E8 7C0803A6 */ mtlr r0
-/* 8036F2EC 4E800020 */ blr
-.size func_8036efac, . - func_8036efac
-
-
-.global func_8036f2f0
-.type func_8036f2f0, @function
-func_8036f2f0:
-/* 8036F2F0 90040000 */ stw r0, 0(r4)
-/* 8036F2F4 90240004 */ stw r1, 4(r4)
-/* 8036F2F8 90440008 */ stw r2, 8(r4)
-/* 8036F2FC BCC40018 */ stmw r6, 0x18(r4)
-/* 8036F300 7C11E2A6 */ mfspr r0, 0x391
-/* 8036F304 900401A8 */ stw r0, 0x1a8(r4)
-/* 8036F308 7C12E2A6 */ mfspr r0, 0x392
-/* 8036F30C 900401AC */ stw r0, 0x1ac(r4)
-/* 8036F310 7C13E2A6 */ mfspr r0, 0x393
-/* 8036F314 900401B0 */ stw r0, 0x1b0(r4)
-/* 8036F318 7C14E2A6 */ mfspr r0, 0x394
-/* 8036F31C 900401B4 */ stw r0, 0x1b4(r4)
-/* 8036F320 7C15E2A6 */ mfspr r0, 0x395
-/* 8036F324 900401B8 */ stw r0, 0x1b8(r4)
-/* 8036F328 7C16E2A6 */ mfspr r0, 0x396
-/* 8036F32C 900401BC */ stw r0, 0x1bc(r4)
-/* 8036F330 7C17E2A6 */ mfspr r0, 0x397
-/* 8036F334 900401C0 */ stw r0, 0x1c0(r4)
-/* 8036F338 9421FFF8 */ stwu r1, -8(r1)
-/* 8036F33C 4BFFFC70 */ b func_8036efac
-.size func_8036f2f0, . - func_8036f2f0
-
diff --git a/asm/Dolphin/os/OSLink-data.s b/asm/Dolphin/os/OSLink-data.s
deleted file mode 100644
index 0a23f10..0000000
--- a/asm/Dolphin/os/OSLink-data.s
+++ /dev/null
@@ -1,37 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804ef548
-.type lbl_804ef548, @object
-lbl_804ef548:
-/* 804EF548 4F534C69 */ .4byte 0x4f534c69
-/* 804EF54C 6E6B3A20 */ .4byte 0x6e6b3a20
-/* 804EF550 756E6B6E */ .4byte 0x756e6b6e
-/* 804EF554 6F776E20 */ .4byte 0x6f776e20
-/* 804EF558 72656C6F */ .4byte 0x72656c6f
-/* 804EF55C 63617469 */ .4byte 0x63617469
-/* 804EF560 6F6E2074 */ .4byte 0x6f6e2074
-/* 804EF564 79706520 */ .4byte 0x79706520
-/* 804EF568 2533640A */ .4byte 0x2533640a
-/* 804EF56C 00000000 */ .4byte 0x00000000
-.size lbl_804ef548, . - lbl_804ef548
-
-
-.global lbl_804ef570
-.type lbl_804ef570, @object
-lbl_804ef570:
-/* 804EF570 4F53556E */ .4byte 0x4f53556e
-/* 804EF574 6C696E6B */ .4byte 0x6c696e6b
-/* 804EF578 3A20756E */ .4byte 0x3a20756e
-/* 804EF57C 6B6E6F77 */ .4byte 0x6b6e6f77
-/* 804EF580 6E207265 */ .4byte 0x6e207265
-/* 804EF584 6C6F6361 */ .4byte 0x6c6f6361
-/* 804EF588 74696F6E */ .4byte 0x74696f6e
-/* 804EF58C 20747970 */ .4byte 0x20747970
-/* 804EF590 65202533 */ .4byte 0x65202533
-/* 804EF594 640A0000 */ .4byte 0x640a0000
-.size lbl_804ef570, . - lbl_804ef570
-
diff --git a/asm/Dolphin/os/OSLink.s b/asm/Dolphin/os/OSLink.s
deleted file mode 100644
index af86ed2..0000000
--- a/asm/Dolphin/os/OSLink.s
+++ /dev/null
@@ -1,604 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036f340
-.type func_8036f340, @function
-func_8036f340:
-/* 8036F340 4E800020 */ blr
-.size func_8036f340, . - func_8036f340
-
-
-.global func_8036f344
-.type func_8036f344, @function
-func_8036f344:
-/* 8036F344 4E800020 */ blr
-.size func_8036f344, . - func_8036f344
-
-
-.global func_8036f348
-.type func_8036f348, @function
-func_8036f348:
-/* 8036F348 7C0802A6 */ mflr r0
-/* 8036F34C 90010004 */ stw r0, 4(r1)
-/* 8036F350 9421FFC0 */ stwu r1, -0x40(r1)
-/* 8036F354 BEE1001C */ stmw r23, 0x1c(r1)
-/* 8036F358 7C7A1B79 */ or. r26, r3, r3
-/* 8036F35C 3B640000 */ addi r27, r4, 0x0
-/* 8036F360 4182000C */ beq- lbl_8036f36c
-/* 8036F364 83FA0000 */ lwz r31, 0(r26)
-/* 8036F368 48000008 */ b lbl_8036f370
-lbl_8036f36c:
-/* 8036F36C 3BE00000 */ li r31, 0x0
-lbl_8036f370:
-/* 8036F370 807B0028 */ lwz r3, 0x28(r27)
-/* 8036F374 801B002C */ lwz r0, 0x2c(r27)
-/* 8036F378 38830000 */ addi r4, r3, 0x0
-/* 8036F37C 7C630214 */ add r3, r3, r0
-/* 8036F380 38030007 */ addi r0, r3, 0x7
-/* 8036F384 7C040050 */ subf r0, r4, r0
-/* 8036F388 5400E8FE */ srwi r0, r0, 3
-/* 8036F38C 7C041840 */ cmplw r4, r3
-/* 8036F390 7C0903A6 */ mtctr r0
-/* 8036F394 40800018 */ bge- lbl_8036f3ac
-lbl_8036f398:
-/* 8036F398 80040000 */ lwz r0, 0(r4)
-/* 8036F39C 7C00F840 */ cmplw r0, r31
-/* 8036F3A0 41820014 */ beq- lbl_8036f3b4
-/* 8036F3A4 38840008 */ addi r4, r4, 0x8
-/* 8036F3A8 4200FFF0 */ bdnz lbl_8036f398
-lbl_8036f3ac:
-/* 8036F3AC 38600000 */ li r3, 0x0
-/* 8036F3B0 480001F8 */ b lbl_8036f5a8
-lbl_8036f3b4:
-/* 8036F3B4 3C60804F */ lis r3, lbl_804ef548@ha
-/* 8036F3B8 83C40004 */ lwz r30, 4(r4)
-/* 8036F3BC 3B23F548 */ addi r25, r3, lbl_804ef548@l
-/* 8036F3C0 3BA00000 */ li r29, 0x0
-/* 8036F3C4 480001AC */ b lbl_8036f570
-lbl_8036f3c8:
-/* 8036F3C8 A01E0000 */ lhz r0, 0(r30)
-/* 8036F3CC 281F0000 */ cmplwi r31, 0
-/* 8036F3D0 7F9C0214 */ add r28, r28, r0
-/* 8036F3D4 4182001C */ beq- lbl_8036f3f0
-/* 8036F3D8 881E0003 */ lbz r0, 3(r30)
-/* 8036F3DC 807A0010 */ lwz r3, 0x10(r26)
-/* 8036F3E0 54001838 */ slwi r0, r0, 3
-/* 8036F3E4 7C03002E */ lwzx r0, r3, r0
-/* 8036F3E8 5405003C */ rlwinm r5, r0, 0, 0, 0x1e
-/* 8036F3EC 48000008 */ b lbl_8036f3f4
-lbl_8036f3f0:
-/* 8036F3F0 38A00000 */ li r5, 0x0
-lbl_8036f3f4:
-/* 8036F3F4 2C040006 */ cmpwi r4, 0x6
-/* 8036F3F8 418200B8 */ beq- lbl_8036f4b0
-/* 8036F3FC 40800030 */ bge- lbl_8036f42c
-/* 8036F400 2C040002 */ cmpwi r4, 0x2
-/* 8036F404 4182005C */ beq- lbl_8036f460
-/* 8036F408 40800014 */ bge- lbl_8036f41c
-/* 8036F40C 2C040000 */ cmpwi r4, 0x0
-/* 8036F410 4182015C */ beq- lbl_8036f56c
-/* 8036F414 4080003C */ bge- lbl_8036f450
-/* 8036F418 48000148 */ b lbl_8036f560
-lbl_8036f41c:
-/* 8036F41C 2C040004 */ cmpwi r4, 0x4
-/* 8036F420 4182006C */ beq- lbl_8036f48c
-/* 8036F424 40800078 */ bge- lbl_8036f49c
-/* 8036F428 48000054 */ b lbl_8036f47c
-lbl_8036f42c:
-/* 8036F42C 2C0400C9 */ cmpwi r4, 0xc9
-/* 8036F430 4182013C */ beq- lbl_8036f56c
-/* 8036F434 40800010 */ bge- lbl_8036f444
-/* 8036F438 2C04000A */ cmpwi r4, 0xa
-/* 8036F43C 418200A0 */ beq- lbl_8036f4dc
-/* 8036F440 48000120 */ b lbl_8036f560
-lbl_8036f444:
-/* 8036F444 2C0400CB */ cmpwi r4, 0xcb
-/* 8036F448 40800118 */ bge- lbl_8036f560
-/* 8036F44C 480000B0 */ b lbl_8036f4fc
-lbl_8036f450:
-/* 8036F450 801E0004 */ lwz r0, 4(r30)
-/* 8036F454 7C050214 */ add r0, r5, r0
-/* 8036F458 901C0000 */ stw r0, 0(r28)
-/* 8036F45C 48000110 */ b lbl_8036f56c
-lbl_8036f460:
-/* 8036F460 801E0004 */ lwz r0, 4(r30)
-/* 8036F464 807C0000 */ lwz r3, 0(r28)
-/* 8036F468 7C050214 */ add r0, r5, r0
-/* 8036F46C 5463078A */ rlwinm r3, r3, 0, 0x1e, 5
-/* 8036F470 500301BA */ rlwimi r3, r0, 0, 6, 0x1d
-/* 8036F474 907C0000 */ stw r3, 0(r28)
-/* 8036F478 480000F4 */ b lbl_8036f56c
-lbl_8036f47c:
-/* 8036F47C 801E0004 */ lwz r0, 4(r30)
-/* 8036F480 7C050214 */ add r0, r5, r0
-/* 8036F484 B01C0000 */ sth r0, 0(r28)
-/* 8036F488 480000E4 */ b lbl_8036f56c
-lbl_8036f48c:
-/* 8036F48C 801E0004 */ lwz r0, 4(r30)
-/* 8036F490 7C050214 */ add r0, r5, r0
-/* 8036F494 B01C0000 */ sth r0, 0(r28)
-/* 8036F498 480000D4 */ b lbl_8036f56c
-lbl_8036f49c:
-/* 8036F49C 801E0004 */ lwz r0, 4(r30)
-/* 8036F4A0 7C050214 */ add r0, r5, r0
-/* 8036F4A4 5400843E */ srwi r0, r0, 0x10
-/* 8036F4A8 B01C0000 */ sth r0, 0(r28)
-/* 8036F4AC 480000C0 */ b lbl_8036f56c
-lbl_8036f4b0:
-/* 8036F4B0 801E0004 */ lwz r0, 4(r30)
-/* 8036F4B4 7C850214 */ add r4, r5, r0
-/* 8036F4B8 54800421 */ rlwinm. r0, r4, 0, 0x10, 0x10
-/* 8036F4BC 4182000C */ beq- lbl_8036f4c8
-/* 8036F4C0 38600001 */ li r3, 0x1
-/* 8036F4C4 48000008 */ b lbl_8036f4cc
-lbl_8036f4c8:
-/* 8036F4C8 38600000 */ li r3, 0x0
-lbl_8036f4cc:
-/* 8036F4CC 5480843E */ srwi r0, r4, 0x10
-/* 8036F4D0 7C001A14 */ add r0, r0, r3
-/* 8036F4D4 B01C0000 */ sth r0, 0(r28)
-/* 8036F4D8 48000094 */ b lbl_8036f56c
-lbl_8036f4dc:
-/* 8036F4DC 801E0004 */ lwz r0, 4(r30)
-/* 8036F4E0 807C0000 */ lwz r3, 0(r28)
-/* 8036F4E4 7C050214 */ add r0, r5, r0
-/* 8036F4E8 7C1C0050 */ subf r0, r28, r0
-/* 8036F4EC 5463078A */ rlwinm r3, r3, 0, 0x1e, 5
-/* 8036F4F0 500301BA */ rlwimi r3, r0, 0, 6, 0x1d
-/* 8036F4F4 907C0000 */ stw r3, 0(r28)
-/* 8036F4F8 48000074 */ b lbl_8036f56c
-lbl_8036f4fc:
-/* 8036F4FC 881E0003 */ lbz r0, 3(r30)
-/* 8036F500 281D0000 */ cmplwi r29, 0
-/* 8036F504 807B0010 */ lwz r3, 0x10(r27)
-/* 8036F508 54001838 */ slwi r0, r0, 3
-/* 8036F50C 7C630214 */ add r3, r3, r0
-/* 8036F510 80030000 */ lwz r0, 0(r3)
-/* 8036F514 3AE30000 */ addi r23, r3, 0x0
-/* 8036F518 541C003C */ rlwinm r28, r0, 0, 0, 0x1e
-/* 8036F51C 41820024 */ beq- lbl_8036f540
-/* 8036F520 801D0000 */ lwz r0, 0(r29)
-/* 8036F524 809D0004 */ lwz r4, 4(r29)
-/* 8036F528 5418003C */ rlwinm r24, r0, 0, 0, 0x1e
-/* 8036F52C 38780000 */ addi r3, r24, 0x0
-/* 8036F530 4BFFE3E1 */ bl func_8036d910
-/* 8036F534 7F03C378 */ mr r3, r24
-/* 8036F538 809D0004 */ lwz r4, 4(r29)
-/* 8036F53C 4BFFE49D */ bl func_8036d9d8
-lbl_8036f540:
-/* 8036F540 80170000 */ lwz r0, 0(r23)
-/* 8036F544 540007FF */ clrlwi. r0, r0, 0x1f
-/* 8036F548 4182000C */ beq- lbl_8036f554
-/* 8036F54C 7EE0BB78 */ mr r0, r23
-/* 8036F550 48000008 */ b lbl_8036f558
-lbl_8036f554:
-/* 8036F554 38000000 */ li r0, 0x0
-lbl_8036f558:
-/* 8036F558 7C1D0378 */ mr r29, r0
-/* 8036F55C 48000010 */ b lbl_8036f56c
-lbl_8036f560:
-/* 8036F560 38790000 */ addi r3, r25, 0x0
-/* 8036F564 4CC63182 */ crclr 6
-/* 8036F568 4BFFF14D */ bl func_8036e6b4
-lbl_8036f56c:
-/* 8036F56C 3BDE0008 */ addi r30, r30, 0x8
-lbl_8036f570:
-/* 8036F570 889E0002 */ lbz r4, 2(r30)
-/* 8036F574 280400CB */ cmplwi r4, 0xcb
-/* 8036F578 4082FE50 */ bne+ lbl_8036f3c8
-/* 8036F57C 281D0000 */ cmplwi r29, 0
-/* 8036F580 41820024 */ beq- lbl_8036f5a4
-/* 8036F584 801D0000 */ lwz r0, 0(r29)
-/* 8036F588 809D0004 */ lwz r4, 4(r29)
-/* 8036F58C 5419003C */ rlwinm r25, r0, 0, 0, 0x1e
-/* 8036F590 38790000 */ addi r3, r25, 0x0
-/* 8036F594 4BFFE37D */ bl func_8036d910
-/* 8036F598 7F23CB78 */ mr r3, r25
-/* 8036F59C 809D0004 */ lwz r4, 4(r29)
-/* 8036F5A0 4BFFE439 */ bl func_8036d9d8
-lbl_8036f5a4:
-/* 8036F5A4 38600001 */ li r3, 0x1
-lbl_8036f5a8:
-/* 8036F5A8 BAE1001C */ lmw r23, 0x1c(r1)
-/* 8036F5AC 80010044 */ lwz r0, 0x44(r1)
-/* 8036F5B0 38210040 */ addi r1, r1, 0x40
-/* 8036F5B4 7C0803A6 */ mtlr r0
-/* 8036F5B8 4E800020 */ blr
-.size func_8036f348, . - func_8036f348
-
-
-.global func_8036f5bc
-.type func_8036f5bc, @function
-func_8036f5bc:
-/* 8036F5BC 7C0802A6 */ mflr r0
-/* 8036F5C0 90010004 */ stw r0, 4(r1)
-/* 8036F5C4 9421FFE0 */ stwu r1, -0x20(r1)
-/* 8036F5C8 93E1001C */ stw r31, 0x1c(r1)
-/* 8036F5CC 7C7F1B78 */ mr r31, r3
-/* 8036F5D0 93C10018 */ stw r30, 0x18(r1)
-/* 8036F5D4 3BC40000 */ addi r30, r4, 0x0
-/* 8036F5D8 93A10014 */ stw r29, 0x14(r1)
-/* 8036F5DC 8003001C */ lwz r0, 0x1c(r3)
-/* 8036F5E0 28000002 */ cmplwi r0, 2
-/* 8036F5E4 41810040 */ bgt- lbl_8036f624
-/* 8036F5E8 41800044 */ blt- lbl_8036f62c
-/* 8036F5EC 807F0040 */ lwz r3, 0x40(r31)
-/* 8036F5F0 28030000 */ cmplwi r3, 0
-/* 8036F5F4 41820014 */ beq- lbl_8036f608
-/* 8036F5F8 7C1F1B96 */ divwu r0, r31, r3
-/* 8036F5FC 7C0019D6 */ mullw r0, r0, r3
-/* 8036F600 7C00F851 */ subf. r0, r0, r31
-/* 8036F604 40820020 */ bne- lbl_8036f624
-lbl_8036f608:
-/* 8036F608 807F0044 */ lwz r3, 0x44(r31)
-/* 8036F60C 28030000 */ cmplwi r3, 0
-/* 8036F610 4182001C */ beq- lbl_8036f62c
-/* 8036F614 7C1E1B96 */ divwu r0, r30, r3
-/* 8036F618 7C0019D6 */ mullw r0, r0, r3
-/* 8036F61C 7C00F051 */ subf. r0, r0, r30
-/* 8036F620 4182000C */ beq- lbl_8036f62c
-lbl_8036f624:
-/* 8036F624 38600000 */ li r3, 0x0
-/* 8036F628 480001C8 */ b lbl_8036f7f0
-lbl_8036f62c:
-/* 8036F62C 3C608000 */ lis r3, 0x8000
-/* 8036F630 38A330C8 */ addi r5, r3, 0x30c8
-/* 8036F634 84850004 */ lwzu r4, 4(r5)
-/* 8036F638 28040000 */ cmplwi r4, 0
-/* 8036F63C 4082000C */ bne- lbl_8036f648
-/* 8036F640 93E330C8 */ stw r31, 0x30c8(r3)
-/* 8036F644 48000008 */ b lbl_8036f64c
-lbl_8036f648:
-/* 8036F648 93E40004 */ stw r31, 4(r4)
-lbl_8036f64c:
-/* 8036F64C 909F0008 */ stw r4, 8(r31)
-/* 8036F650 3BA00000 */ li r29, 0x0
-/* 8036F654 387E0000 */ addi r3, r30, 0x0
-/* 8036F658 93BF0004 */ stw r29, 4(r31)
-/* 8036F65C 38800000 */ li r4, 0x0
-/* 8036F660 93E50000 */ stw r31, 0(r5)
-/* 8036F664 80BF0020 */ lwz r5, 0x20(r31)
-/* 8036F668 4BC9ECCD */ bl func_8000e334
-/* 8036F66C 801F0010 */ lwz r0, 0x10(r31)
-/* 8036F670 38800000 */ li r4, 0x0
-/* 8036F674 7C00FA14 */ add r0, r0, r31
-/* 8036F678 901F0010 */ stw r0, 0x10(r31)
-/* 8036F67C 801F0024 */ lwz r0, 0x24(r31)
-/* 8036F680 7C00FA14 */ add r0, r0, r31
-/* 8036F684 901F0024 */ stw r0, 0x24(r31)
-/* 8036F688 801F0028 */ lwz r0, 0x28(r31)
-/* 8036F68C 7C00FA14 */ add r0, r0, r31
-/* 8036F690 901F0028 */ stw r0, 0x28(r31)
-/* 8036F694 48000044 */ b lbl_8036f6d8
-lbl_8036f698:
-/* 8036F698 801F0010 */ lwz r0, 0x10(r31)
-/* 8036F69C 7C60EA14 */ add r3, r0, r29
-/* 8036F6A0 80030000 */ lwz r0, 0(r3)
-/* 8036F6A4 28000000 */ cmplwi r0, 0
-/* 8036F6A8 41820010 */ beq- lbl_8036f6b8
-/* 8036F6AC 7C00FA14 */ add r0, r0, r31
-/* 8036F6B0 90030000 */ stw r0, 0(r3)
-/* 8036F6B4 4800001C */ b lbl_8036f6d0
-lbl_8036f6b8:
-/* 8036F6B8 80030004 */ lwz r0, 4(r3)
-/* 8036F6BC 28000000 */ cmplwi r0, 0
-/* 8036F6C0 41820010 */ beq- lbl_8036f6d0
-/* 8036F6C4 93C30000 */ stw r30, 0(r3)
-/* 8036F6C8 80030004 */ lwz r0, 4(r3)
-/* 8036F6CC 7FDE0214 */ add r30, r30, r0
-lbl_8036f6d0:
-/* 8036F6D0 3BBD0008 */ addi r29, r29, 0x8
-/* 8036F6D4 38840001 */ addi r4, r4, 0x1
-lbl_8036f6d8:
-/* 8036F6D8 801F000C */ lwz r0, 0xc(r31)
-/* 8036F6DC 7C040040 */ cmplw r4, r0
-/* 8036F6E0 4180FFB8 */ blt+ lbl_8036f698
-/* 8036F6E4 809F0028 */ lwz r4, 0x28(r31)
-/* 8036F6E8 48000014 */ b lbl_8036f6fc
-lbl_8036f6ec:
-/* 8036F6EC 80040004 */ lwz r0, 4(r4)
-/* 8036F6F0 7C00FA14 */ add r0, r0, r31
-/* 8036F6F4 90040004 */ stw r0, 4(r4)
-/* 8036F6F8 38840008 */ addi r4, r4, 0x8
-lbl_8036f6fc:
-/* 8036F6FC 807F0028 */ lwz r3, 0x28(r31)
-/* 8036F700 801F002C */ lwz r0, 0x2c(r31)
-/* 8036F704 7C030214 */ add r0, r3, r0
-/* 8036F708 7C040040 */ cmplw r4, r0
-/* 8036F70C 4180FFE0 */ blt+ lbl_8036f6ec
-/* 8036F710 881F0030 */ lbz r0, 0x30(r31)
-/* 8036F714 28000000 */ cmplwi r0, 0
-/* 8036F718 41820020 */ beq- lbl_8036f738
-/* 8036F71C 807F0010 */ lwz r3, 0x10(r31)
-/* 8036F720 54001838 */ slwi r0, r0, 3
-/* 8036F724 809F0034 */ lwz r4, 0x34(r31)
-/* 8036F728 7C03002E */ lwzx r0, r3, r0
-/* 8036F72C 5400003C */ rlwinm r0, r0, 0, 0, 0x1e
-/* 8036F730 7C040214 */ add r0, r4, r0
-/* 8036F734 901F0034 */ stw r0, 0x34(r31)
-lbl_8036f738:
-/* 8036F738 881F0031 */ lbz r0, 0x31(r31)
-/* 8036F73C 28000000 */ cmplwi r0, 0
-/* 8036F740 41820020 */ beq- lbl_8036f760
-/* 8036F744 807F0010 */ lwz r3, 0x10(r31)
-/* 8036F748 54001838 */ slwi r0, r0, 3
-/* 8036F74C 809F0038 */ lwz r4, 0x38(r31)
-/* 8036F750 7C03002E */ lwzx r0, r3, r0
-/* 8036F754 5400003C */ rlwinm r0, r0, 0, 0, 0x1e
-/* 8036F758 7C040214 */ add r0, r4, r0
-/* 8036F75C 901F0038 */ stw r0, 0x38(r31)
-lbl_8036f760:
-/* 8036F760 881F0032 */ lbz r0, 0x32(r31)
-/* 8036F764 28000000 */ cmplwi r0, 0
-/* 8036F768 41820020 */ beq- lbl_8036f788
-/* 8036F76C 807F0010 */ lwz r3, 0x10(r31)
-/* 8036F770 54001838 */ slwi r0, r0, 3
-/* 8036F774 809F003C */ lwz r4, 0x3c(r31)
-/* 8036F778 7C03002E */ lwzx r0, r3, r0
-/* 8036F77C 5400003C */ rlwinm r0, r0, 0, 0, 0x1e
-/* 8036F780 7C040214 */ add r0, r4, r0
-/* 8036F784 901F003C */ stw r0, 0x3c(r31)
-lbl_8036f788:
-/* 8036F788 3C608000 */ lis r3, 0x8000
-/* 8036F78C 806330D0 */ lwz r3, 0x30d0(r3)
-/* 8036F790 28030000 */ cmplwi r3, 0
-/* 8036F794 41820010 */ beq- lbl_8036f7a4
-/* 8036F798 801F0014 */ lwz r0, 0x14(r31)
-/* 8036F79C 7C001A14 */ add r0, r0, r3
-/* 8036F7A0 901F0014 */ stw r0, 0x14(r31)
-lbl_8036f7a4:
-/* 8036F7A4 38600000 */ li r3, 0x0
-/* 8036F7A8 389F0000 */ addi r4, r31, 0x0
-/* 8036F7AC 4BFFFB9D */ bl func_8036f348
-/* 8036F7B0 3C608000 */ lis r3, 0x8000
-/* 8036F7B4 83A330C8 */ lwz r29, 0x30c8(r3)
-/* 8036F7B8 48000028 */ b lbl_8036f7e0
-lbl_8036f7bc:
-/* 8036F7BC 387F0000 */ addi r3, r31, 0x0
-/* 8036F7C0 389D0000 */ addi r4, r29, 0x0
-/* 8036F7C4 4BFFFB85 */ bl func_8036f348
-/* 8036F7C8 7C1DF840 */ cmplw r29, r31
-/* 8036F7CC 41820010 */ beq- lbl_8036f7dc
-/* 8036F7D0 387D0000 */ addi r3, r29, 0x0
-/* 8036F7D4 389F0000 */ addi r4, r31, 0x0
-/* 8036F7D8 4BFFFB71 */ bl func_8036f348
-lbl_8036f7dc:
-/* 8036F7DC 83BD0004 */ lwz r29, 4(r29)
-lbl_8036f7e0:
-/* 8036F7E0 281D0000 */ cmplwi r29, 0
-/* 8036F7E4 4082FFD8 */ bne+ lbl_8036f7bc
-/* 8036F7E8 4BFFFB59 */ bl func_8036f340
-/* 8036F7EC 38600001 */ li r3, 0x1
-lbl_8036f7f0:
-/* 8036F7F0 80010024 */ lwz r0, 0x24(r1)
-/* 8036F7F4 83E1001C */ lwz r31, 0x1c(r1)
-/* 8036F7F8 83C10018 */ lwz r30, 0x18(r1)
-/* 8036F7FC 83A10014 */ lwz r29, 0x14(r1)
-/* 8036F800 38210020 */ addi r1, r1, 0x20
-/* 8036F804 7C0803A6 */ mtlr r0
-/* 8036F808 4E800020 */ blr
-.size func_8036f5bc, . - func_8036f5bc
-
-
-.global func_8036f80c
-.type func_8036f80c, @function
-func_8036f80c:
-/* 8036F80C 7C0802A6 */ mflr r0
-/* 8036F810 90010004 */ stw r0, 4(r1)
-/* 8036F814 9421FFC8 */ stwu r1, -0x38(r1)
-/* 8036F818 BF21001C */ stmw r25, 0x1c(r1)
-/* 8036F81C 7C9C2378 */ mr r28, r4
-/* 8036F820 80830000 */ lwz r4, 0(r3)
-/* 8036F824 807C0028 */ lwz r3, 0x28(r28)
-/* 8036F828 801C002C */ lwz r0, 0x2c(r28)
-/* 8036F82C 38A30000 */ addi r5, r3, 0x0
-/* 8036F830 7C630214 */ add r3, r3, r0
-/* 8036F834 38030007 */ addi r0, r3, 0x7
-/* 8036F838 7C050050 */ subf r0, r5, r0
-/* 8036F83C 5400E8FE */ srwi r0, r0, 3
-/* 8036F840 7C051840 */ cmplw r5, r3
-/* 8036F844 7C0903A6 */ mtctr r0
-/* 8036F848 40800018 */ bge- lbl_8036f860
-lbl_8036f84c:
-/* 8036F84C 80050000 */ lwz r0, 0(r5)
-/* 8036F850 7C002040 */ cmplw r0, r4
-/* 8036F854 41820014 */ beq- lbl_8036f868
-/* 8036F858 38A50008 */ addi r5, r5, 0x8
-/* 8036F85C 4200FFF0 */ bdnz lbl_8036f84c
-lbl_8036f860:
-/* 8036F860 38600000 */ li r3, 0x0
-/* 8036F864 480001A0 */ b lbl_8036fa04
-lbl_8036f868:
-/* 8036F868 3C60804F */ lis r3, lbl_804ef570@ha
-/* 8036F86C 83E50004 */ lwz r31, 4(r5)
-/* 8036F870 3B63F570 */ addi r27, r3, lbl_804ef570@l
-/* 8036F874 3BC00000 */ li r30, 0x0
-/* 8036F878 48000154 */ b lbl_8036f9cc
-lbl_8036f87c:
-/* 8036F87C A01F0000 */ lhz r0, 0(r31)
-/* 8036F880 2C040006 */ cmpwi r4, 0x6
-/* 8036F884 38600000 */ li r3, 0x0
-/* 8036F888 7FBD0214 */ add r29, r29, r0
-/* 8036F88C 41820098 */ beq- lbl_8036f924
-/* 8036F890 40800030 */ bge- lbl_8036f8c0
-/* 8036F894 2C040002 */ cmpwi r4, 0x2
-/* 8036F898 41820058 */ beq- lbl_8036f8f0
-/* 8036F89C 40800014 */ bge- lbl_8036f8b0
-/* 8036F8A0 2C040000 */ cmpwi r4, 0x0
-/* 8036F8A4 41820124 */ beq- lbl_8036f9c8
-/* 8036F8A8 4080003C */ bge- lbl_8036f8e4
-/* 8036F8AC 48000110 */ b lbl_8036f9bc
-lbl_8036f8b0:
-/* 8036F8B0 2C040004 */ cmpwi r4, 0x4
-/* 8036F8B4 41820058 */ beq- lbl_8036f90c
-/* 8036F8B8 40800060 */ bge- lbl_8036f918
-/* 8036F8BC 48000044 */ b lbl_8036f900
-lbl_8036f8c0:
-/* 8036F8C0 2C0400C9 */ cmpwi r4, 0xc9
-/* 8036F8C4 41820104 */ beq- lbl_8036f9c8
-/* 8036F8C8 40800010 */ bge- lbl_8036f8d8
-/* 8036F8CC 2C04000A */ cmpwi r4, 0xa
-/* 8036F8D0 41820060 */ beq- lbl_8036f930
-/* 8036F8D4 480000E8 */ b lbl_8036f9bc
-lbl_8036f8d8:
-/* 8036F8D8 2C0400CB */ cmpwi r4, 0xcb
-/* 8036F8DC 408000E0 */ bge- lbl_8036f9bc
-/* 8036F8E0 48000078 */ b lbl_8036f958
-lbl_8036f8e4:
-/* 8036F8E4 38000000 */ li r0, 0x0
-/* 8036F8E8 901D0000 */ stw r0, 0(r29)
-/* 8036F8EC 480000DC */ b lbl_8036f9c8
-lbl_8036f8f0:
-/* 8036F8F0 801D0000 */ lwz r0, 0(r29)
-/* 8036F8F4 5400078A */ rlwinm r0, r0, 0, 0x1e, 5
-/* 8036F8F8 901D0000 */ stw r0, 0(r29)
-/* 8036F8FC 480000CC */ b lbl_8036f9c8
-lbl_8036f900:
-/* 8036F900 38000000 */ li r0, 0x0
-/* 8036F904 B01D0000 */ sth r0, 0(r29)
-/* 8036F908 480000C0 */ b lbl_8036f9c8
-lbl_8036f90c:
-/* 8036F90C 38000000 */ li r0, 0x0
-/* 8036F910 B01D0000 */ sth r0, 0(r29)
-/* 8036F914 480000B4 */ b lbl_8036f9c8
-lbl_8036f918:
-/* 8036F918 38000000 */ li r0, 0x0
-/* 8036F91C B01D0000 */ sth r0, 0(r29)
-/* 8036F920 480000A8 */ b lbl_8036f9c8
-lbl_8036f924:
-/* 8036F924 38000000 */ li r0, 0x0
-/* 8036F928 B01D0000 */ sth r0, 0(r29)
-/* 8036F92C 4800009C */ b lbl_8036f9c8
-lbl_8036f930:
-/* 8036F930 881C0032 */ lbz r0, 0x32(r28)
-/* 8036F934 28000000 */ cmplwi r0, 0
-/* 8036F938 4182000C */ beq- lbl_8036f944
-/* 8036F93C 801C003C */ lwz r0, 0x3c(r28)
-/* 8036F940 7C7D0050 */ subf r3, r29, r0
-lbl_8036f944:
-/* 8036F944 801D0000 */ lwz r0, 0(r29)
-/* 8036F948 5400078A */ rlwinm r0, r0, 0, 0x1e, 5
-/* 8036F94C 506001BA */ rlwimi r0, r3, 0, 6, 0x1d
-/* 8036F950 901D0000 */ stw r0, 0(r29)
-/* 8036F954 48000074 */ b lbl_8036f9c8
-lbl_8036f958:
-/* 8036F958 881F0003 */ lbz r0, 3(r31)
-/* 8036F95C 281E0000 */ cmplwi r30, 0
-/* 8036F960 807C0010 */ lwz r3, 0x10(r28)
-/* 8036F964 54001838 */ slwi r0, r0, 3
-/* 8036F968 7C630214 */ add r3, r3, r0
-/* 8036F96C 80030000 */ lwz r0, 0(r3)
-/* 8036F970 3B430000 */ addi r26, r3, 0x0
-/* 8036F974 541D003C */ rlwinm r29, r0, 0, 0, 0x1e
-/* 8036F978 41820024 */ beq- lbl_8036f99c
-/* 8036F97C 801E0000 */ lwz r0, 0(r30)
-/* 8036F980 809E0004 */ lwz r4, 4(r30)
-/* 8036F984 5419003C */ rlwinm r25, r0, 0, 0, 0x1e
-/* 8036F988 38790000 */ addi r3, r25, 0x0
-/* 8036F98C 4BFFDF85 */ bl func_8036d910
-/* 8036F990 7F23CB78 */ mr r3, r25
-/* 8036F994 809E0004 */ lwz r4, 4(r30)
-/* 8036F998 4BFFE041 */ bl func_8036d9d8
-lbl_8036f99c:
-/* 8036F99C 801A0000 */ lwz r0, 0(r26)
-/* 8036F9A0 540007FF */ clrlwi. r0, r0, 0x1f
-/* 8036F9A4 4182000C */ beq- lbl_8036f9b0
-/* 8036F9A8 7F40D378 */ mr r0, r26
-/* 8036F9AC 48000008 */ b lbl_8036f9b4
-lbl_8036f9b0:
-/* 8036F9B0 38000000 */ li r0, 0x0
-lbl_8036f9b4:
-/* 8036F9B4 7C1E0378 */ mr r30, r0
-/* 8036F9B8 48000010 */ b lbl_8036f9c8
-lbl_8036f9bc:
-/* 8036F9BC 387B0000 */ addi r3, r27, 0x0
-/* 8036F9C0 4CC63182 */ crclr 6
-/* 8036F9C4 4BFFECF1 */ bl func_8036e6b4
-lbl_8036f9c8:
-/* 8036F9C8 3BFF0008 */ addi r31, r31, 0x8
-lbl_8036f9cc:
-/* 8036F9CC 889F0002 */ lbz r4, 2(r31)
-/* 8036F9D0 280400CB */ cmplwi r4, 0xcb
-/* 8036F9D4 4082FEA8 */ bne+ lbl_8036f87c
-/* 8036F9D8 281E0000 */ cmplwi r30, 0
-/* 8036F9DC 41820024 */ beq- lbl_8036fa00
-/* 8036F9E0 801E0000 */ lwz r0, 0(r30)
-/* 8036F9E4 809E0004 */ lwz r4, 4(r30)
-/* 8036F9E8 541B003C */ rlwinm r27, r0, 0, 0, 0x1e
-/* 8036F9EC 387B0000 */ addi r3, r27, 0x0
-/* 8036F9F0 4BFFDF21 */ bl func_8036d910
-/* 8036F9F4 7F63DB78 */ mr r3, r27
-/* 8036F9F8 809E0004 */ lwz r4, 4(r30)
-/* 8036F9FC 4BFFDFDD */ bl func_8036d9d8
-lbl_8036fa00:
-/* 8036FA00 38600001 */ li r3, 0x1
-lbl_8036fa04:
-/* 8036FA04 BB21001C */ lmw r25, 0x1c(r1)
-/* 8036FA08 8001003C */ lwz r0, 0x3c(r1)
-/* 8036FA0C 38210038 */ addi r1, r1, 0x38
-/* 8036FA10 7C0803A6 */ mtlr r0
-/* 8036FA14 4E800020 */ blr
-.size func_8036f80c, . - func_8036f80c
-
-
-.global func_8036fa18
-.type func_8036fa18, @function
-func_8036fa18:
-/* 8036FA18 7C0802A6 */ mflr r0
-/* 8036FA1C 90010004 */ stw r0, 4(r1)
-/* 8036FA20 9421FFE8 */ stwu r1, -0x18(r1)
-/* 8036FA24 93E10014 */ stw r31, 0x14(r1)
-/* 8036FA28 7C7F1B78 */ mr r31, r3
-/* 8036FA2C 93C10010 */ stw r30, 0x10(r1)
-/* 8036FA30 80830004 */ lwz r4, 4(r3)
-/* 8036FA34 80A30008 */ lwz r5, 8(r3)
-/* 8036FA38 28040000 */ cmplwi r4, 0
-/* 8036FA3C 40820010 */ bne- lbl_8036fa4c
-/* 8036FA40 3C608000 */ lis r3, 0x8000
-/* 8036FA44 90A330CC */ stw r5, 0x30cc(r3)
-/* 8036FA48 48000008 */ b lbl_8036fa50
-lbl_8036fa4c:
-/* 8036FA4C 90A40008 */ stw r5, 8(r4)
-lbl_8036fa50:
-/* 8036FA50 28050000 */ cmplwi r5, 0
-/* 8036FA54 40820010 */ bne- lbl_8036fa64
-/* 8036FA58 3C608000 */ lis r3, 0x8000
-/* 8036FA5C 908330C8 */ stw r4, 0x30c8(r3)
-/* 8036FA60 48000008 */ b lbl_8036fa68
-lbl_8036fa64:
-/* 8036FA64 90850004 */ stw r4, 4(r5)
-lbl_8036fa68:
-/* 8036FA68 3C608000 */ lis r3, 0x8000
-/* 8036FA6C 83C330C8 */ lwz r30, 0x30c8(r3)
-/* 8036FA70 48000014 */ b lbl_8036fa84
-lbl_8036fa74:
-/* 8036FA74 387F0000 */ addi r3, r31, 0x0
-/* 8036FA78 389E0000 */ addi r4, r30, 0x0
-/* 8036FA7C 4BFFFD91 */ bl func_8036f80c
-/* 8036FA80 83DE0004 */ lwz r30, 4(r30)
-lbl_8036fa84:
-/* 8036FA84 281E0000 */ cmplwi r30, 0
-/* 8036FA88 4082FFEC */ bne+ lbl_8036fa74
-/* 8036FA8C 4BFFF8B9 */ bl func_8036f344
-/* 8036FA90 8001001C */ lwz r0, 0x1c(r1)
-/* 8036FA94 38600001 */ li r3, 0x1
-/* 8036FA98 83E10014 */ lwz r31, 0x14(r1)
-/* 8036FA9C 83C10010 */ lwz r30, 0x10(r1)
-/* 8036FAA0 38210018 */ addi r1, r1, 0x18
-/* 8036FAA4 7C0803A6 */ mtlr r0
-/* 8036FAA8 4E800020 */ blr
-.size func_8036fa18, . - func_8036fa18
-
-
-.global func_8036faac
-.type func_8036faac, @function
-func_8036faac:
-/* 8036FAAC 3C808000 */ lis r4, 0x8000
-/* 8036FAB0 38000000 */ li r0, 0x0
-/* 8036FAB4 900430CC */ stw r0, 0x30cc(r4)
-/* 8036FAB8 900430C8 */ stw r0, 0x30c8(r4)
-/* 8036FABC 900430D0 */ stw r0, 0x30d0(r4)
-/* 8036FAC0 4E800020 */ blr
-.size func_8036faac, . - func_8036faac
-
diff --git a/asm/Dolphin/os/OSMemory-data.s b/asm/Dolphin/os/OSMemory-data.s
deleted file mode 100644
index 1b4ff0c..0000000
--- a/asm/Dolphin/os/OSMemory-data.s
+++ /dev/null
@@ -1,15 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804ef598
-.type lbl_804ef598, @object
-lbl_804ef598:
-/* 804EF598 8036FCC8 */ .4byte func_8036fcc8
-/* 804EF59C 0000007F */ .4byte 0x0000007f
-/* 804EF5A0 00000000 */ .4byte 0x00000000
-/* 804EF5A4 00000000 */ .4byte 0x00000000
-.size lbl_804ef598, . - lbl_804ef598
-
diff --git a/asm/Dolphin/os/OSMemory.s b/asm/Dolphin/os/OSMemory.s
deleted file mode 100644
index d7c9a45..0000000
--- a/asm/Dolphin/os/OSMemory.s
+++ /dev/null
@@ -1,229 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036fcc8
-.type func_8036fcc8, @function
-func_8036fcc8:
-/* 8036FCC8 7C0802A6 */ mflr r0
-/* 8036FCCC 2C030000 */ cmpwi r3, 0x0
-/* 8036FCD0 90010004 */ stw r0, 4(r1)
-/* 8036FCD4 9421FFF8 */ stwu r1, -8(r1)
-/* 8036FCD8 41820018 */ beq- lbl_8036fcf0
-/* 8036FCDC 3C60CC00 */ lis r3, 0xcc00
-/* 8036FCE0 380000FF */ li r0, 0xff
-/* 8036FCE4 B0034010 */ sth r0, 0x4010(r3)
-/* 8036FCE8 3C60F000 */ lis r3, 0xf000
-/* 8036FCEC 4BFFF1B1 */ bl func_8036ee9c
-lbl_8036fcf0:
-/* 8036FCF0 38600001 */ li r3, 0x1
-/* 8036FCF4 8001000C */ lwz r0, 0xc(r1)
-/* 8036FCF8 38210008 */ addi r1, r1, 0x8
-/* 8036FCFC 7C0803A6 */ mtlr r0
-/* 8036FD00 4E800020 */ blr
-.size func_8036fcc8, . - func_8036fcc8
-
-
-.global func_8036fd04
-.type func_8036fd04, @function
-func_8036fd04:
-/* 8036FD04 7C0802A6 */ mflr r0
-/* 8036FD08 3C60CC00 */ lis r3, 0xcc00
-/* 8036FD0C 90010004 */ stw r0, 4(r1)
-/* 8036FD10 39034000 */ addi r8, r3, 0x4000
-/* 8036FD14 38000000 */ li r0, 0x0
-/* 8036FD18 9421FFF8 */ stwu r1, -8(r1)
-/* 8036FD1C A0E34024 */ lhz r7, 0x4024(r3)
-/* 8036FD20 3C608054 */ lis r3, lbl_8053ec30@ha
-/* 8036FD24 A0C80022 */ lhz r6, 0x22(r8)
-/* 8036FD28 3863EC30 */ addi r3, r3, lbl_8053ec30@l
-/* 8036FD2C A0A8001E */ lhz r5, 0x1e(r8)
-/* 8036FD30 50E6819E */ rlwimi r6, r7, 0x10, 6, 0xf
-/* 8036FD34 B0080020 */ sth r0, 0x20(r8)
-/* 8036FD38 8183003C */ lwz r12, 0x3c(r3)
-/* 8036FD3C 280C0000 */ cmplwi r12, 0
-/* 8036FD40 41820018 */ beq- lbl_8036fd58
-/* 8036FD44 7D8803A6 */ mtlr r12
-/* 8036FD48 3860000F */ li r3, 0xf
-/* 8036FD4C 4CC63182 */ crclr 6
-/* 8036FD50 4E800021 */ blrl
-/* 8036FD54 4800000C */ b lbl_8036fd60
-lbl_8036fd58:
-/* 8036FD58 3860000F */ li r3, 0xf
-/* 8036FD5C 4BFFEB21 */ bl func_8036e87c
-lbl_8036fd60:
-/* 8036FD60 8001000C */ lwz r0, 0xc(r1)
-/* 8036FD64 38210008 */ addi r1, r1, 0x8
-/* 8036FD68 7C0803A6 */ mtlr r0
-/* 8036FD6C 4E800020 */ blr
-.size func_8036fd04, . - func_8036fd04
-
-
-.global func_8036fd70
-.type func_8036fd70, @function
-func_8036fd70:
-/* 8036FD70 38E00000 */ li r7, 0x0
-/* 8036FD74 3C800000 */ lis r4, 0
-/* 8036FD78 38840002 */ addi r4, r4, 0x2
-/* 8036FD7C 3C608000 */ lis r3, 0x8000
-/* 8036FD80 386301FF */ addi r3, r3, 0x1ff
-/* 8036FD84 3CC00100 */ lis r6, 0x100
-/* 8036FD88 38C60002 */ addi r6, r6, 0x2
-/* 8036FD8C 3CA08100 */ lis r5, 0x8100
-/* 8036FD90 38A500FF */ addi r5, r5, 0xff
-/* 8036FD94 4C00012C */ isync
-/* 8036FD98 7CF883A6 */ mtdbatu 0, r7
-/* 8036FD9C 7C9983A6 */ mtdbatl 0, r4
-/* 8036FDA0 7C7883A6 */ mtdbatu 0, r3
-/* 8036FDA4 4C00012C */ isync
-/* 8036FDA8 7CF083A6 */ mtibatu 0, r7
-/* 8036FDAC 7C9183A6 */ mtibatl 0, r4
-/* 8036FDB0 7C7083A6 */ mtibatu 0, r3
-/* 8036FDB4 4C00012C */ isync
-/* 8036FDB8 7CFC83A6 */ mtdbatu 2, r7
-/* 8036FDBC 7CDD83A6 */ mtdbatl 2, r6
-/* 8036FDC0 7CBC83A6 */ mtdbatu 2, r5
-/* 8036FDC4 4C00012C */ isync
-/* 8036FDC8 7CF483A6 */ mtibatu 2, r7
-/* 8036FDCC 7CD583A6 */ mtibatl 2, r6
-/* 8036FDD0 7CB483A6 */ mtibatu 2, r5
-/* 8036FDD4 4C00012C */ isync
-/* 8036FDD8 7C6000A6 */ mfmsr r3
-/* 8036FDDC 60630030 */ ori r3, r3, 0x30
-/* 8036FDE0 7C7B03A6 */ mtspr 0x1b, r3
-/* 8036FDE4 7C6802A6 */ mflr r3
-/* 8036FDE8 7C7A03A6 */ mtspr 0x1a, r3
-/* 8036FDEC 4C000064 */ rfi
-.size func_8036fd70, . - func_8036fd70
-
-
-.global func_8036fdf0
-.type func_8036fdf0, @function
-func_8036fdf0:
-/* 8036FDF0 38E00000 */ li r7, 0x0
-/* 8036FDF4 3C800000 */ lis r4, 0
-/* 8036FDF8 38840002 */ addi r4, r4, 0x2
-/* 8036FDFC 3C608000 */ lis r3, 0x8000
-/* 8036FE00 386303FF */ addi r3, r3, 0x3ff
-/* 8036FE04 3CC00200 */ lis r6, 0x200
-/* 8036FE08 38C60002 */ addi r6, r6, 0x2
-/* 8036FE0C 3CA08200 */ lis r5, 0x8200
-/* 8036FE10 38A501FF */ addi r5, r5, 0x1ff
-/* 8036FE14 4C00012C */ isync
-/* 8036FE18 7CF883A6 */ mtdbatu 0, r7
-/* 8036FE1C 7C9983A6 */ mtdbatl 0, r4
-/* 8036FE20 7C7883A6 */ mtdbatu 0, r3
-/* 8036FE24 4C00012C */ isync
-/* 8036FE28 7CF083A6 */ mtibatu 0, r7
-/* 8036FE2C 7C9183A6 */ mtibatl 0, r4
-/* 8036FE30 7C7083A6 */ mtibatu 0, r3
-/* 8036FE34 4C00012C */ isync
-/* 8036FE38 7CFC83A6 */ mtdbatu 2, r7
-/* 8036FE3C 7CDD83A6 */ mtdbatl 2, r6
-/* 8036FE40 7CBC83A6 */ mtdbatu 2, r5
-/* 8036FE44 4C00012C */ isync
-/* 8036FE48 7CF483A6 */ mtibatu 2, r7
-/* 8036FE4C 7CD583A6 */ mtibatl 2, r6
-/* 8036FE50 7CB483A6 */ mtibatu 2, r5
-/* 8036FE54 4C00012C */ isync
-/* 8036FE58 7C6000A6 */ mfmsr r3
-/* 8036FE5C 60630030 */ ori r3, r3, 0x30
-/* 8036FE60 7C7B03A6 */ mtspr 0x1b, r3
-/* 8036FE64 7C6802A6 */ mflr r3
-/* 8036FE68 7C7A03A6 */ mtspr 0x1a, r3
-/* 8036FE6C 4C000064 */ rfi
-.size func_8036fdf0, . - func_8036fdf0
-
-
-.global func_8036fe70
-.type func_8036fe70, @function
-func_8036fe70:
-/* 8036FE70 546300BE */ clrlwi r3, r3, 2
-/* 8036FE74 7C7A03A6 */ mtspr 0x1a, r3
-/* 8036FE78 7C6000A6 */ mfmsr r3
-/* 8036FE7C 54630732 */ rlwinm r3, r3, 0, 0x1c, 0x19
-/* 8036FE80 7C7B03A6 */ mtspr 0x1b, r3
-/* 8036FE84 4C000064 */ rfi
-.size func_8036fe70, . - func_8036fe70
-
-
-.global func_8036fe88
-.type func_8036fe88, @function
-func_8036fe88:
-/* 8036FE88 7C0802A6 */ mflr r0
-/* 8036FE8C 90010004 */ stw r0, 4(r1)
-/* 8036FE90 9421FFB8 */ stwu r1, -0x48(r1)
-/* 8036FE94 93E10044 */ stw r31, 0x44(r1)
-/* 8036FE98 93C10040 */ stw r30, 0x40(r1)
-/* 8036FE9C 93A1003C */ stw r29, 0x3c(r1)
-/* 8036FEA0 3C608000 */ lis r3, 0x8000
-/* 8036FEA4 83A300F0 */ lwz r29, 0xf0(r3)
-/* 8036FEA8 4BFFEC2D */ bl func_8036ead4
-/* 8036FEAC 3C000180 */ lis r0, 0x180
-/* 8036FEB0 7C1D0040 */ cmplw r29, r0
-/* 8036FEB4 7C7F1B78 */ mr r31, r3
-/* 8036FEB8 41810014 */ bgt- lbl_8036fecc
-/* 8036FEBC 3C608037 */ lis r3, func_8036fd70@ha
-/* 8036FEC0 3863FD70 */ addi r3, r3, func_8036fd70@l
-/* 8036FEC4 4BFFFFAD */ bl func_8036fe70
-/* 8036FEC8 4800001C */ b lbl_8036fee4
-lbl_8036fecc:
-/* 8036FECC 3C000300 */ lis r0, 0x300
-/* 8036FED0 7C1D0040 */ cmplw r29, r0
-/* 8036FED4 41810010 */ bgt- lbl_8036fee4
-/* 8036FED8 3C608037 */ lis r3, func_8036fdf0@ha
-/* 8036FEDC 3863FDF0 */ addi r3, r3, func_8036fdf0@l
-/* 8036FEE0 4BFFFF91 */ bl func_8036fe70
-lbl_8036fee4:
-/* 8036FEE4 3C60CC00 */ lis r3, 0xcc00
-/* 8036FEE8 3BA34000 */ addi r29, r3, 0x4000
-/* 8036FEEC 38000000 */ li r0, 0x0
-/* 8036FEF0 B01D0020 */ sth r0, 0x20(r29)
-/* 8036FEF4 380000FF */ li r0, 0xff
-/* 8036FEF8 3C60F000 */ lis r3, 0xf000
-/* 8036FEFC B01D0010 */ sth r0, 0x10(r29)
-/* 8036FF00 4BFFEF9D */ bl func_8036ee9c
-/* 8036FF04 3C608037 */ lis r3, func_8036fd04@ha
-/* 8036FF08 3BC3FD04 */ addi r30, r3, func_8036fd04@l
-/* 8036FF0C 7FC4F378 */ mr r4, r30
-/* 8036FF10 38600000 */ li r3, 0x0
-/* 8036FF14 4BFFEC0D */ bl func_8036eb20
-/* 8036FF18 7FC4F378 */ mr r4, r30
-/* 8036FF1C 38600001 */ li r3, 0x1
-/* 8036FF20 4BFFEC01 */ bl func_8036eb20
-/* 8036FF24 7FC4F378 */ mr r4, r30
-/* 8036FF28 38600002 */ li r3, 0x2
-/* 8036FF2C 4BFFEBF5 */ bl func_8036eb20
-/* 8036FF30 7FC4F378 */ mr r4, r30
-/* 8036FF34 38600003 */ li r3, 0x3
-/* 8036FF38 4BFFEBE9 */ bl func_8036eb20
-/* 8036FF3C 7FC4F378 */ mr r4, r30
-/* 8036FF40 38600004 */ li r3, 0x4
-/* 8036FF44 4BFFEBDD */ bl func_8036eb20
-/* 8036FF48 3C60804F */ lis r3, lbl_804ef598@ha
-/* 8036FF4C 3863F598 */ addi r3, r3, lbl_804ef598@l
-/* 8036FF50 480004B1 */ bl func_80370400
-/* 8036FF54 3C608000 */ lis r3, 0x8000
-/* 8036FF58 808300F0 */ lwz r4, 0xf0(r3)
-/* 8036FF5C 80030028 */ lwz r0, 0x28(r3)
-/* 8036FF60 7C040040 */ cmplw r4, r0
-/* 8036FF64 40800018 */ bge- lbl_8036ff7c
-/* 8036FF68 3C04FE80 */ addis r0, r4, 0xfe80
-/* 8036FF6C 28000000 */ cmplwi r0, 0
-/* 8036FF70 4082000C */ bne- lbl_8036ff7c
-/* 8036FF74 38000002 */ li r0, 0x2
-/* 8036FF78 B01D0028 */ sth r0, 0x28(r29)
-lbl_8036ff7c:
-/* 8036FF7C 3C600800 */ lis r3, 0x800
-/* 8036FF80 4BFFEFA5 */ bl func_8036ef24
-/* 8036FF84 7FE3FB78 */ mr r3, r31
-/* 8036FF88 4BFFEB75 */ bl func_8036eafc
-/* 8036FF8C 8001004C */ lwz r0, 0x4c(r1)
-/* 8036FF90 83E10044 */ lwz r31, 0x44(r1)
-/* 8036FF94 83C10040 */ lwz r30, 0x40(r1)
-/* 8036FF98 83A1003C */ lwz r29, 0x3c(r1)
-/* 8036FF9C 38210048 */ addi r1, r1, 0x48
-/* 8036FFA0 7C0803A6 */ mtlr r0
-/* 8036FFA4 4E800020 */ blr
-.size func_8036fe88, . - func_8036fe88
-
diff --git a/asm/Dolphin/os/OSMessages.s b/asm/Dolphin/os/OSMessages.s
deleted file mode 100644
index 1e7d350..0000000
--- a/asm/Dolphin/os/OSMessages.s
+++ /dev/null
@@ -1,159 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036fac4
-.type func_8036fac4, @function
-func_8036fac4:
-/* 8036FAC4 7C0802A6 */ mflr r0
-/* 8036FAC8 90010004 */ stw r0, 4(r1)
-/* 8036FACC 9421FFD8 */ stwu r1, -0x28(r1)
-/* 8036FAD0 93E10024 */ stw r31, 0x24(r1)
-/* 8036FAD4 3BE50000 */ addi r31, r5, 0x0
-/* 8036FAD8 93C10020 */ stw r30, 0x20(r1)
-/* 8036FADC 3BC40000 */ addi r30, r4, 0x0
-/* 8036FAE0 93A1001C */ stw r29, 0x1c(r1)
-/* 8036FAE4 3BA30000 */ addi r29, r3, 0x0
-/* 8036FAE8 48001C61 */ bl func_80371748
-/* 8036FAEC 387D0008 */ addi r3, r29, 0x8
-/* 8036FAF0 48001C59 */ bl func_80371748
-/* 8036FAF4 93DD0010 */ stw r30, 0x10(r29)
-/* 8036FAF8 38000000 */ li r0, 0x0
-/* 8036FAFC 93FD0014 */ stw r31, 0x14(r29)
-/* 8036FB00 901D0018 */ stw r0, 0x18(r29)
-/* 8036FB04 901D001C */ stw r0, 0x1c(r29)
-/* 8036FB08 8001002C */ lwz r0, 0x2c(r1)
-/* 8036FB0C 83E10024 */ lwz r31, 0x24(r1)
-/* 8036FB10 83C10020 */ lwz r30, 0x20(r1)
-/* 8036FB14 83A1001C */ lwz r29, 0x1c(r1)
-/* 8036FB18 38210028 */ addi r1, r1, 0x28
-/* 8036FB1C 7C0803A6 */ mtlr r0
-/* 8036FB20 4E800020 */ blr
-.size func_8036fac4, . - func_8036fac4
-
-
-.global func_8036fb24
-.type func_8036fb24, @function
-func_8036fb24:
-/* 8036FB24 7C0802A6 */ mflr r0
-/* 8036FB28 90010004 */ stw r0, 4(r1)
-/* 8036FB2C 9421FFD8 */ stwu r1, -0x28(r1)
-/* 8036FB30 93E10024 */ stw r31, 0x24(r1)
-/* 8036FB34 3BE50000 */ addi r31, r5, 0x0
-/* 8036FB38 93C10020 */ stw r30, 0x20(r1)
-/* 8036FB3C 93A1001C */ stw r29, 0x1c(r1)
-/* 8036FB40 3BA40000 */ addi r29, r4, 0x0
-/* 8036FB44 93810018 */ stw r28, 0x18(r1)
-/* 8036FB48 3B830000 */ addi r28, r3, 0x0
-/* 8036FB4C 4BFFEF89 */ bl func_8036ead4
-/* 8036FB50 3BC30000 */ addi r30, r3, 0x0
-/* 8036FB54 57FF07FE */ clrlwi r31, r31, 0x1f
-/* 8036FB58 48000024 */ b lbl_8036fb7c
-lbl_8036fb5c:
-/* 8036FB5C 2C1F0000 */ cmpwi r31, 0x0
-/* 8036FB60 40820014 */ bne- lbl_8036fb74
-/* 8036FB64 7FC3F378 */ mr r3, r30
-/* 8036FB68 4BFFEF95 */ bl func_8036eafc
-/* 8036FB6C 38600000 */ li r3, 0x0
-/* 8036FB70 4800005C */ b lbl_8036fbcc
-lbl_8036fb74:
-/* 8036FB74 7F83E378 */ mr r3, r28
-/* 8036FB78 48002995 */ bl func_8037250c
-lbl_8036fb7c:
-/* 8036FB7C 80DC0014 */ lwz r6, 0x14(r28)
-/* 8036FB80 809C001C */ lwz r4, 0x1c(r28)
-/* 8036FB84 7C062000 */ cmpw r6, r4
-/* 8036FB88 4081FFD4 */ ble+ lbl_8036fb5c
-/* 8036FB8C 801C0018 */ lwz r0, 0x18(r28)
-/* 8036FB90 387C0008 */ addi r3, r28, 0x8
-/* 8036FB94 80BC0010 */ lwz r5, 0x10(r28)
-/* 8036FB98 7C802214 */ add r4, r0, r4
-/* 8036FB9C 7C0433D6 */ divw r0, r4, r6
-/* 8036FBA0 7C0031D6 */ mullw r0, r0, r6
-/* 8036FBA4 7C002050 */ subf r0, r0, r4
-/* 8036FBA8 5400103A */ slwi r0, r0, 2
-/* 8036FBAC 7FA5012E */ stwx r29, r5, r0
-/* 8036FBB0 809C001C */ lwz r4, 0x1c(r28)
-/* 8036FBB4 38040001 */ addi r0, r4, 0x1
-/* 8036FBB8 901C001C */ stw r0, 0x1c(r28)
-/* 8036FBBC 48002A3D */ bl func_803725f8
-/* 8036FBC0 7FC3F378 */ mr r3, r30
-/* 8036FBC4 4BFFEF39 */ bl func_8036eafc
-/* 8036FBC8 38600001 */ li r3, 0x1
-lbl_8036fbcc:
-/* 8036FBCC 8001002C */ lwz r0, 0x2c(r1)
-/* 8036FBD0 83E10024 */ lwz r31, 0x24(r1)
-/* 8036FBD4 83C10020 */ lwz r30, 0x20(r1)
-/* 8036FBD8 83A1001C */ lwz r29, 0x1c(r1)
-/* 8036FBDC 83810018 */ lwz r28, 0x18(r1)
-/* 8036FBE0 38210028 */ addi r1, r1, 0x28
-/* 8036FBE4 7C0803A6 */ mtlr r0
-/* 8036FBE8 4E800020 */ blr
-.size func_8036fb24, . - func_8036fb24
-
-
-.global func_8036fbec
-.type func_8036fbec, @function
-func_8036fbec:
-/* 8036FBEC 7C0802A6 */ mflr r0
-/* 8036FBF0 90010004 */ stw r0, 4(r1)
-/* 8036FBF4 9421FFD8 */ stwu r1, -0x28(r1)
-/* 8036FBF8 93E10024 */ stw r31, 0x24(r1)
-/* 8036FBFC 3BE30000 */ addi r31, r3, 0x0
-/* 8036FC00 93C10020 */ stw r30, 0x20(r1)
-/* 8036FC04 3BC50000 */ addi r30, r5, 0x0
-/* 8036FC08 93A1001C */ stw r29, 0x1c(r1)
-/* 8036FC0C 93810018 */ stw r28, 0x18(r1)
-/* 8036FC10 3B840000 */ addi r28, r4, 0x0
-/* 8036FC14 4BFFEEC1 */ bl func_8036ead4
-/* 8036FC18 3BA30000 */ addi r29, r3, 0x0
-/* 8036FC1C 57DE07FE */ clrlwi r30, r30, 0x1f
-/* 8036FC20 48000024 */ b lbl_8036fc44
-lbl_8036fc24:
-/* 8036FC24 2C1E0000 */ cmpwi r30, 0x0
-/* 8036FC28 40820014 */ bne- lbl_8036fc3c
-/* 8036FC2C 7FA3EB78 */ mr r3, r29
-/* 8036FC30 4BFFEECD */ bl func_8036eafc
-/* 8036FC34 38600000 */ li r3, 0x0
-/* 8036FC38 48000070 */ b lbl_8036fca8
-lbl_8036fc3c:
-/* 8036FC3C 387F0008 */ addi r3, r31, 0x8
-/* 8036FC40 480028CD */ bl func_8037250c
-lbl_8036fc44:
-/* 8036FC44 801F001C */ lwz r0, 0x1c(r31)
-/* 8036FC48 2C000000 */ cmpwi r0, 0x0
-/* 8036FC4C 4182FFD8 */ beq+ lbl_8036fc24
-/* 8036FC50 281C0000 */ cmplwi r28, 0
-/* 8036FC54 41820018 */ beq- lbl_8036fc6c
-/* 8036FC58 801F0018 */ lwz r0, 0x18(r31)
-/* 8036FC5C 807F0010 */ lwz r3, 0x10(r31)
-/* 8036FC60 5400103A */ slwi r0, r0, 2
-/* 8036FC64 7C03002E */ lwzx r0, r3, r0
-/* 8036FC68 901C0000 */ stw r0, 0(r28)
-lbl_8036fc6c:
-/* 8036FC6C 80BF0018 */ lwz r5, 0x18(r31)
-/* 8036FC70 7FE3FB78 */ mr r3, r31
-/* 8036FC74 809F0014 */ lwz r4, 0x14(r31)
-/* 8036FC78 38A50001 */ addi r5, r5, 0x1
-/* 8036FC7C 7C0523D6 */ divw r0, r5, r4
-/* 8036FC80 7C0021D6 */ mullw r0, r0, r4
-/* 8036FC84 7C002850 */ subf r0, r0, r5
-/* 8036FC88 901F0018 */ stw r0, 0x18(r31)
-/* 8036FC8C 809F001C */ lwz r4, 0x1c(r31)
-/* 8036FC90 3804FFFF */ addi r0, r4, -0x1
-/* 8036FC94 901F001C */ stw r0, 0x1c(r31)
-/* 8036FC98 48002961 */ bl func_803725f8
-/* 8036FC9C 7FA3EB78 */ mr r3, r29
-/* 8036FCA0 4BFFEE5D */ bl func_8036eafc
-/* 8036FCA4 38600001 */ li r3, 0x1
-lbl_8036fca8:
-/* 8036FCA8 8001002C */ lwz r0, 0x2c(r1)
-/* 8036FCAC 83E10024 */ lwz r31, 0x24(r1)
-/* 8036FCB0 83C10020 */ lwz r30, 0x20(r1)
-/* 8036FCB4 83A1001C */ lwz r29, 0x1c(r1)
-/* 8036FCB8 83810018 */ lwz r28, 0x18(r1)
-/* 8036FCBC 38210028 */ addi r1, r1, 0x28
-/* 8036FCC0 7C0803A6 */ mtlr r0
-/* 8036FCC4 4E800020 */ blr
-.size func_8036fbec, . - func_8036fbec
-
diff --git a/asm/Dolphin/os/OSMutex.s b/asm/Dolphin/os/OSMutex.s
deleted file mode 100644
index a5d8a48..0000000
--- a/asm/Dolphin/os/OSMutex.s
+++ /dev/null
@@ -1,190 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8036ffa8
-.type func_8036ffa8, @function
-func_8036ffa8:
-/* 8036FFA8 7C0802A6 */ mflr r0
-/* 8036FFAC 90010004 */ stw r0, 4(r1)
-/* 8036FFB0 9421FFE8 */ stwu r1, -0x18(r1)
-/* 8036FFB4 93E10014 */ stw r31, 0x14(r1)
-/* 8036FFB8 7C7F1B78 */ mr r31, r3
-/* 8036FFBC 4800178D */ bl func_80371748
-/* 8036FFC0 38000000 */ li r0, 0x0
-/* 8036FFC4 901F0008 */ stw r0, 8(r31)
-/* 8036FFC8 901F000C */ stw r0, 0xc(r31)
-/* 8036FFCC 8001001C */ lwz r0, 0x1c(r1)
-/* 8036FFD0 83E10014 */ lwz r31, 0x14(r1)
-/* 8036FFD4 38210018 */ addi r1, r1, 0x18
-/* 8036FFD8 7C0803A6 */ mtlr r0
-/* 8036FFDC 4E800020 */ blr
-.size func_8036ffa8, . - func_8036ffa8
-
-
-.global func_8036ffe0
-.type func_8036ffe0, @function
-func_8036ffe0:
-/* 8036FFE0 7C0802A6 */ mflr r0
-/* 8036FFE4 90010004 */ stw r0, 4(r1)
-/* 8036FFE8 9421FFE0 */ stwu r1, -0x20(r1)
-/* 8036FFEC 93E1001C */ stw r31, 0x1c(r1)
-/* 8036FFF0 93C10018 */ stw r30, 0x18(r1)
-/* 8036FFF4 93A10014 */ stw r29, 0x14(r1)
-/* 8036FFF8 93810010 */ stw r28, 0x10(r1)
-/* 8036FFFC 7C7C1B78 */ mr r28, r3
-/* 80370000 4BFFEAD5 */ bl func_8036ead4
-/* 80370004 7C7D1B78 */ mr r29, r3
-/* 80370008 48001751 */ bl func_80371758
-/* 8037000C 3BC30000 */ addi r30, r3, 0x0
-/* 80370010 3BE00000 */ li r31, 0x0
-lbl_80370014:
-/* 80370014 801C0008 */ lwz r0, 8(r28)
-/* 80370018 28000000 */ cmplwi r0, 0
-/* 8037001C 40820040 */ bne- lbl_8037005c
-/* 80370020 93DC0008 */ stw r30, 8(r28)
-/* 80370024 807C000C */ lwz r3, 0xc(r28)
-/* 80370028 38030001 */ addi r0, r3, 0x1
-/* 8037002C 901C000C */ stw r0, 0xc(r28)
-/* 80370030 807E02F8 */ lwz r3, 0x2f8(r30)
-/* 80370034 28030000 */ cmplwi r3, 0
-/* 80370038 4082000C */ bne- lbl_80370044
-/* 8037003C 939E02F4 */ stw r28, 0x2f4(r30)
-/* 80370040 48000008 */ b lbl_80370048
-lbl_80370044:
-/* 80370044 93830010 */ stw r28, 0x10(r3)
-lbl_80370048:
-/* 80370048 907C0014 */ stw r3, 0x14(r28)
-/* 8037004C 38000000 */ li r0, 0x0
-/* 80370050 901C0010 */ stw r0, 0x10(r28)
-/* 80370054 939E02F8 */ stw r28, 0x2f8(r30)
-/* 80370058 4800003C */ b lbl_80370094
-lbl_8037005c:
-/* 8037005C 7C00F040 */ cmplw r0, r30
-/* 80370060 40820014 */ bne- lbl_80370074
-/* 80370064 807C000C */ lwz r3, 0xc(r28)
-/* 80370068 38030001 */ addi r0, r3, 0x1
-/* 8037006C 901C000C */ stw r0, 0xc(r28)
-/* 80370070 48000024 */ b lbl_80370094
-lbl_80370074:
-/* 80370074 939E02F0 */ stw r28, 0x2f0(r30)
-/* 80370078 807C0008 */ lwz r3, 8(r28)
-/* 8037007C 809E02D0 */ lwz r4, 0x2d0(r30)
-/* 80370080 48001A19 */ bl func_80371a98
-/* 80370084 7F83E378 */ mr r3, r28
-/* 80370088 48002485 */ bl func_8037250c
-/* 8037008C 93FE02F0 */ stw r31, 0x2f0(r30)
-/* 80370090 4BFFFF84 */ b lbl_80370014
-lbl_80370094:
-/* 80370094 7FA3EB78 */ mr r3, r29
-/* 80370098 4BFFEA65 */ bl func_8036eafc
-/* 8037009C 80010024 */ lwz r0, 0x24(r1)
-/* 803700A0 83E1001C */ lwz r31, 0x1c(r1)
-/* 803700A4 83C10018 */ lwz r30, 0x18(r1)
-/* 803700A8 83A10014 */ lwz r29, 0x14(r1)
-/* 803700AC 83810010 */ lwz r28, 0x10(r1)
-/* 803700B0 38210020 */ addi r1, r1, 0x20
-/* 803700B4 7C0803A6 */ mtlr r0
-/* 803700B8 4E800020 */ blr
-.size func_8036ffe0, . - func_8036ffe0
-
-
-.global func_803700bc
-.type func_803700bc, @function
-func_803700bc:
-/* 803700BC 7C0802A6 */ mflr r0
-/* 803700C0 90010004 */ stw r0, 4(r1)
-/* 803700C4 9421FFE0 */ stwu r1, -0x20(r1)
-/* 803700C8 93E1001C */ stw r31, 0x1c(r1)
-/* 803700CC 93C10018 */ stw r30, 0x18(r1)
-/* 803700D0 93A10014 */ stw r29, 0x14(r1)
-/* 803700D4 7C7D1B78 */ mr r29, r3
-/* 803700D8 4BFFE9FD */ bl func_8036ead4
-/* 803700DC 7C7F1B78 */ mr r31, r3
-/* 803700E0 48001679 */ bl func_80371758
-/* 803700E4 801D0008 */ lwz r0, 8(r29)
-/* 803700E8 3BC30000 */ addi r30, r3, 0x0
-/* 803700EC 7C00F040 */ cmplw r0, r30
-/* 803700F0 40820070 */ bne- lbl_80370160
-/* 803700F4 807D000C */ lwz r3, 0xc(r29)
-/* 803700F8 3403FFFF */ addic. r0, r3, -0x1
-/* 803700FC 901D000C */ stw r0, 0xc(r29)
-/* 80370100 40820060 */ bne- lbl_80370160
-/* 80370104 807D0010 */ lwz r3, 0x10(r29)
-/* 80370108 809D0014 */ lwz r4, 0x14(r29)
-/* 8037010C 28030000 */ cmplwi r3, 0
-/* 80370110 4082000C */ bne- lbl_8037011c
-/* 80370114 909E02F8 */ stw r4, 0x2f8(r30)
-/* 80370118 48000008 */ b lbl_80370120
-lbl_8037011c:
-/* 8037011C 90830014 */ stw r4, 0x14(r3)
-lbl_80370120:
-/* 80370120 28040000 */ cmplwi r4, 0
-/* 80370124 4082000C */ bne- lbl_80370130
-/* 80370128 907E02F4 */ stw r3, 0x2f4(r30)
-/* 8037012C 48000008 */ b lbl_80370134
-lbl_80370130:
-/* 80370130 90640010 */ stw r3, 0x10(r4)
-lbl_80370134:
-/* 80370134 38000000 */ li r0, 0x0
-/* 80370138 901D0008 */ stw r0, 8(r29)
-/* 8037013C 807E02D0 */ lwz r3, 0x2d0(r30)
-/* 80370140 801E02D4 */ lwz r0, 0x2d4(r30)
-/* 80370144 7C030000 */ cmpw r3, r0
-/* 80370148 40800010 */ bge- lbl_80370158
-/* 8037014C 7FC3F378 */ mr r3, r30
-/* 80370150 4800174D */ bl func_8037189c
-/* 80370154 907E02D0 */ stw r3, 0x2d0(r30)
-lbl_80370158:
-/* 80370158 7FA3EB78 */ mr r3, r29
-/* 8037015C 4800249D */ bl func_803725f8
-lbl_80370160:
-/* 80370160 7FE3FB78 */ mr r3, r31
-/* 80370164 4BFFE999 */ bl func_8036eafc
-/* 80370168 80010024 */ lwz r0, 0x24(r1)
-/* 8037016C 83E1001C */ lwz r31, 0x1c(r1)
-/* 80370170 83C10018 */ lwz r30, 0x18(r1)
-/* 80370174 83A10014 */ lwz r29, 0x14(r1)
-/* 80370178 38210020 */ addi r1, r1, 0x20
-/* 8037017C 7C0803A6 */ mtlr r0
-/* 80370180 4E800020 */ blr
-.size func_803700bc, . - func_803700bc
-
-
-.global func_80370184
-.type func_80370184, @function
-func_80370184:
-/* 80370184 7C0802A6 */ mflr r0
-/* 80370188 90010004 */ stw r0, 4(r1)
-/* 8037018C 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80370190 93E10014 */ stw r31, 0x14(r1)
-/* 80370194 3BE00000 */ li r31, 0x0
-/* 80370198 93C10010 */ stw r30, 0x10(r1)
-/* 8037019C 3BC30000 */ addi r30, r3, 0x0
-/* 803701A0 48000030 */ b lbl_803701d0
-lbl_803701a4:
-/* 803701A4 80A40010 */ lwz r5, 0x10(r4)
-/* 803701A8 38640000 */ addi r3, r4, 0x0
-/* 803701AC 28050000 */ cmplwi r5, 0
-/* 803701B0 4082000C */ bne- lbl_803701bc
-/* 803701B4 93FE02F8 */ stw r31, 0x2f8(r30)
-/* 803701B8 48000008 */ b lbl_803701c0
-lbl_803701bc:
-/* 803701BC 93E50014 */ stw r31, 0x14(r5)
-lbl_803701c0:
-/* 803701C0 90BE02F4 */ stw r5, 0x2f4(r30)
-/* 803701C4 93E4000C */ stw r31, 0xc(r4)
-/* 803701C8 93E40008 */ stw r31, 8(r4)
-/* 803701CC 4800242D */ bl func_803725f8
-lbl_803701d0:
-/* 803701D0 809E02F4 */ lwz r4, 0x2f4(r30)
-/* 803701D4 28040000 */ cmplwi r4, 0
-/* 803701D8 4082FFCC */ bne+ lbl_803701a4
-/* 803701DC 8001001C */ lwz r0, 0x1c(r1)
-/* 803701E0 83E10014 */ lwz r31, 0x14(r1)
-/* 803701E4 83C10010 */ lwz r30, 0x10(r1)
-/* 803701E8 38210018 */ addi r1, r1, 0x18
-/* 803701EC 7C0803A6 */ mtlr r0
-/* 803701F0 4E800020 */ blr
-.size func_80370184, . - func_80370184
-
diff --git a/asm/Dolphin/os/OSReboot.s b/asm/Dolphin/os/OSReboot.s
deleted file mode 100644
index dded641..0000000
--- a/asm/Dolphin/os/OSReboot.s
+++ /dev/null
@@ -1,173 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_803701f4
-.type func_803701f4, @function
-func_803701f4:
-/* 803701F4 7C0802A6 */ mflr r0
-/* 803701F8 90010004 */ stw r0, 4(r1)
-/* 803701FC 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80370200 93E10014 */ stw r31, 0x14(r1)
-/* 80370204 7C7F1B78 */ mr r31, r3
-/* 80370208 4BFFE8CD */ bl func_8036ead4
-/* 8037020C 4BFFD805 */ bl func_8036da10
-/* 80370210 7C0004AC */ sync 0
-/* 80370214 4C00012C */ isync
-/* 80370218 7FE803A6 */ mtlr r31
-/* 8037021C 4E800020 */ blr
-.size func_803701f4, . - func_803701f4
-
-
-.global func_80370220
-.type func_80370220, @function
-func_80370220:
-/* 80370220 8001001C */ lwz r0, 0x1c(r1)
-/* 80370224 83E10014 */ lwz r31, 0x14(r1)
-/* 80370228 38210018 */ addi r1, r1, 0x18
-/* 8037022C 7C0803A6 */ mtlr r0
-/* 80370230 4E800020 */ blr
-.size func_80370220, . - func_80370220
-
-
-.global func_80370234
-.type func_80370234, @function
-func_80370234:
-/* 80370234 38000001 */ li r0, 0x1
-/* 80370238 900DCA68 */ stw r0, lbl_805c6888@sda21(0)
-/* 8037023C 4E800020 */ blr
-.size func_80370234, . - func_80370234
-
-
-.global func_80370240
-.type func_80370240, @function
-func_80370240:
-/* 80370240 7C0802A6 */ mflr r0
-/* 80370244 90010004 */ stw r0, 4(r1)
-/* 80370248 9421FCC0 */ stwu r1, -0x340(r1)
-/* 8037024C 93E1033C */ stw r31, 0x33c(r1)
-/* 80370250 93C10338 */ stw r30, 0x338(r1)
-/* 80370254 3C608054 */ lis r3, lbl_8053ec80@ha
-/* 80370258 3BC3EC80 */ addi r30, r3, lbl_8053ec80@l
-/* 8037025C 4BFFE879 */ bl func_8036ead4
-/* 80370260 80ADCA60 */ lwz r5, lbl_805c6880@sda21(0)
-/* 80370264 3C808130 */ lis r4, 0x8130
-/* 80370268 800DCA64 */ lwz r0, lbl_805c6884@sda21(0)
-/* 8037026C 38600000 */ li r3, 0x0
-/* 80370270 3FE08180 */ lis r31, 0x8180
-/* 80370274 38E00001 */ li r7, 0x1
-/* 80370278 907FFFFC */ stw r3, -4(r31)
-/* 8037027C 3CC08000 */ lis r6, 0x8000
-/* 80370280 907FFFF8 */ stw r3, -8(r31)
-/* 80370284 38610070 */ addi r3, r1, 0x70
-/* 80370288 98E630E2 */ stb r7, 0x30e2(r6)
-/* 8037028C 90A4DFF0 */ stw r5, -0x2010(r4)
-/* 80370290 9004DFEC */ stw r0, -0x2014(r4)
-/* 80370294 4BFFDFCD */ bl func_8036e260
-/* 80370298 38610070 */ addi r3, r1, 0x70
-/* 8037029C 4BFFDDFD */ bl func_8036e098
-/* 803702A0 48004E6D */ bl func_8037510c
-/* 803702A4 38600001 */ li r3, 0x1
-/* 803702A8 48006D91 */ bl func_80377038
-/* 803702AC 3C608037 */ lis r3, func_80370234@ha
-/* 803702B0 38630234 */ addi r3, r3, func_80370234@l
-/* 803702B4 480071C1 */ bl func_80377474
-/* 803702B8 480070D9 */ bl func_80377390
-/* 803702BC 2C030000 */ cmpwi r3, 0x0
-/* 803702C0 4082000C */ bne- lbl_803702cc
-/* 803702C4 807FFFFC */ lwz r3, -4(r31)
-/* 803702C8 4800022D */ bl func_803704f4
-lbl_803702cc:
-/* 803702CC 3860FFE0 */ li r3, -0x20
-/* 803702D0 4BFFEBCD */ bl func_8036ee9c
-/* 803702D4 38600400 */ li r3, 0x400
-/* 803702D8 4BFFEC4D */ bl func_8036ef24
-/* 803702DC 4BFFE80D */ bl func_8036eae8
-/* 803702E0 48000004 */ b lbl_803702e4
-lbl_803702e4:
-/* 803702E4 48000004 */ b lbl_803702e8
-lbl_803702e8:
-/* 803702E8 800DCA68 */ lwz r0, lbl_805c6888@sda21(0)
-/* 803702EC 2C000000 */ cmpwi r0, 0x0
-/* 803702F0 4182FFF8 */ beq+ lbl_803702e8
-/* 803702F4 7FC4F378 */ mr r4, r30
-/* 803702F8 38610040 */ addi r3, r1, 0x40
-/* 803702FC 38A00020 */ li r5, 0x20
-/* 80370300 38C02440 */ li r6, 0x2440
-/* 80370304 38E00000 */ li r7, 0x0
-/* 80370308 48006981 */ bl func_80376c88
-/* 8037030C 3FE08180 */ lis r31, 0x8180
-/* 80370310 48000004 */ b lbl_80370314
-lbl_80370314:
-/* 80370314 48000004 */ b lbl_80370318
-lbl_80370318:
-/* 80370318 8001004C */ lwz r0, 0x4c(r1)
-/* 8037031C 2C000001 */ cmpwi r0, 0x1
-/* 80370320 4182FFF8 */ beq+ lbl_80370318
-/* 80370324 40800014 */ bge- lbl_80370338
-/* 80370328 2C00FFFF */ cmpwi r0, -0x1
-/* 8037032C 41820018 */ beq- lbl_80370344
-/* 80370330 40800020 */ bge- lbl_80370350
-/* 80370334 4BFFFFE4 */ b lbl_80370318
-lbl_80370338:
-/* 80370338 2C00000C */ cmpwi r0, 0xc
-/* 8037033C 4080FFDC */ bge+ lbl_80370318
-/* 80370340 48000004 */ b lbl_80370344
-lbl_80370344:
-/* 80370344 807FFFFC */ lwz r3, -4(r31)
-/* 80370348 480001AD */ bl func_803704f4
-/* 8037034C 4BFFFFCC */ b lbl_80370318
-lbl_80370350:
-/* 80370350 807E0018 */ lwz r3, 0x18(r30)
-/* 80370354 809E0014 */ lwz r4, 0x14(r30)
-/* 80370358 3803001F */ addi r0, r3, 0x1f
-/* 8037035C 38840020 */ addi r4, r4, 0x20
-/* 80370360 541E0034 */ rlwinm r30, r0, 0, 0, 0x1a
-/* 80370364 48000004 */ b lbl_80370368
-lbl_80370368:
-/* 80370368 48000004 */ b lbl_8037036c
-lbl_8037036c:
-/* 8037036C 800DCA68 */ lwz r0, lbl_805c6888@sda21(0)
-/* 80370370 2C000000 */ cmpwi r0, 0x0
-/* 80370374 4182FFF8 */ beq+ lbl_8037036c
-/* 80370378 7FC5F378 */ mr r5, r30
-/* 8037037C 38610010 */ addi r3, r1, 0x10
-/* 80370380 38C42440 */ addi r6, r4, 0x2440
-/* 80370384 3C808130 */ lis r4, 0x8130
-/* 80370388 38E00000 */ li r7, 0x0
-/* 8037038C 480068FD */ bl func_80376c88
-/* 80370390 3FE08180 */ lis r31, 0x8180
-/* 80370394 48000004 */ b lbl_80370398
-lbl_80370398:
-/* 80370398 48000004 */ b lbl_8037039c
-lbl_8037039c:
-/* 8037039C 8001001C */ lwz r0, 0x1c(r1)
-/* 803703A0 2C000001 */ cmpwi r0, 0x1
-/* 803703A4 4182FFF8 */ beq+ lbl_8037039c
-/* 803703A8 40800014 */ bge- lbl_803703bc
-/* 803703AC 2C00FFFF */ cmpwi r0, -0x1
-/* 803703B0 41820018 */ beq- lbl_803703c8
-/* 803703B4 40800020 */ bge- lbl_803703d4
-/* 803703B8 4BFFFFE4 */ b lbl_8037039c
-lbl_803703bc:
-/* 803703BC 2C00000C */ cmpwi r0, 0xc
-/* 803703C0 4080FFDC */ bge+ lbl_8037039c
-/* 803703C4 48000004 */ b lbl_803703c8
-lbl_803703c8:
-/* 803703C8 807FFFFC */ lwz r3, -4(r31)
-/* 803703CC 48000129 */ bl func_803704f4
-/* 803703D0 4BFFFFCC */ b lbl_8037039c
-lbl_803703d4:
-/* 803703D4 3C608130 */ lis r3, 0x8130
-/* 803703D8 7FC4F378 */ mr r4, r30
-/* 803703DC 4BFFD5FD */ bl func_8036d9d8
-/* 803703E0 3C608130 */ lis r3, 0x8130
-/* 803703E4 4BFFFE11 */ bl func_803701f4
-/* 803703E8 80010344 */ lwz r0, 0x344(r1)
-/* 803703EC 83E1033C */ lwz r31, 0x33c(r1)
-/* 803703F0 83C10338 */ lwz r30, 0x338(r1)
-/* 803703F4 38210340 */ addi r1, r1, 0x340
-/* 803703F8 7C0803A6 */ mtlr r0
-/* 803703FC 4E800020 */ blr
-.size func_80370240, . - func_80370240
-
diff --git a/asm/Dolphin/os/OSReset.s b/asm/Dolphin/os/OSReset.s
deleted file mode 100644
index a7b42f7..0000000
--- a/asm/Dolphin/os/OSReset.s
+++ /dev/null
@@ -1,330 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_80370400
-.type func_80370400, @function
-func_80370400:
-/* 80370400 80ADCA70 */ lwz r5, lbl_805c6890@sda21(0)
-/* 80370404 48000008 */ b lbl_8037040c
-lbl_80370408:
-/* 80370408 80A50008 */ lwz r5, 8(r5)
-lbl_8037040c:
-/* 8037040C 28050000 */ cmplwi r5, 0
-/* 80370410 41820014 */ beq- lbl_80370424
-/* 80370414 80850004 */ lwz r4, 4(r5)
-/* 80370418 80030004 */ lwz r0, 4(r3)
-/* 8037041C 7C040040 */ cmplw r4, r0
-/* 80370420 4081FFE8 */ ble+ lbl_80370408
-lbl_80370424:
-/* 80370424 28050000 */ cmplwi r5, 0
-/* 80370428 40820034 */ bne- lbl_8037045c
-/* 8037042C 38ADCA70 */ addi r5, 0, lbl_805c6890@sda21
-/* 80370430 84850004 */ lwzu r4, 4(r5)
-/* 80370434 28040000 */ cmplwi r4, 0
-/* 80370438 4082000C */ bne- lbl_80370444
-/* 8037043C 906DCA70 */ stw r3, lbl_805c6890@sda21(0)
-/* 80370440 48000008 */ b lbl_80370448
-lbl_80370444:
-/* 80370444 90640008 */ stw r3, 8(r4)
-lbl_80370448:
-/* 80370448 9083000C */ stw r4, 0xc(r3)
-/* 8037044C 38000000 */ li r0, 0x0
-/* 80370450 90030008 */ stw r0, 8(r3)
-/* 80370454 90650000 */ stw r3, 0(r5)
-/* 80370458 4E800020 */ blr
-lbl_8037045c:
-/* 8037045C 90A30008 */ stw r5, 8(r3)
-/* 80370460 8085000C */ lwz r4, 0xc(r5)
-/* 80370464 9065000C */ stw r3, 0xc(r5)
-/* 80370468 28040000 */ cmplwi r4, 0
-/* 8037046C 9083000C */ stw r4, 0xc(r3)
-/* 80370470 4082000C */ bne- lbl_8037047c
-/* 80370474 906DCA70 */ stw r3, lbl_805c6890@sda21(0)
-/* 80370478 4E800020 */ blr
-lbl_8037047c:
-/* 8037047C 90640008 */ stw r3, 8(r4)
-/* 80370480 4E800020 */ blr
-.size func_80370400, . - func_80370400
-
-
-.global func_80370484
-.type func_80370484, @function
-func_80370484:
-/* 80370484 48000020 */ b lbl_803704a4
-lbl_80370488:
-/* 80370488 7D10FAA6 */ mfspr r8, 0x3f0
-/* 8037048C 61080008 */ ori r8, r8, 8
-/* 80370490 7D10FBA6 */ mtspr 0x3f0, r8
-/* 80370494 4C00012C */ isync
-/* 80370498 7C0004AC */ sync 0
-/* 8037049C 60000000 */ nop
-/* 803704A0 48000008 */ b lbl_803704a8
-lbl_803704a4:
-/* 803704A4 48000020 */ b lbl_803704c4
-lbl_803704a8:
-/* 803704A8 7CAC42E6 */ mftb r5, 0x10c
-lbl_803704ac:
-/* 803704AC 7CCC42E6 */ mftb r6, 0x10c
-/* 803704B0 7CE53050 */ subf r7, r5, r6
-/* 803704B4 28071124 */ cmplwi r7, 0x1124
-/* 803704B8 4180FFF4 */ blt+ lbl_803704ac
-/* 803704BC 60000000 */ nop
-/* 803704C0 48000008 */ b lbl_803704c8
-lbl_803704c4:
-/* 803704C4 48000020 */ b lbl_803704e4
-lbl_803704c8:
-/* 803704C8 3D00CC00 */ lis r8, 0xcc00
-/* 803704CC 61083000 */ ori r8, r8, 0x3000
-/* 803704D0 38800003 */ li r4, 0x3
-/* 803704D4 90880024 */ stw r4, 0x24(r8)
-/* 803704D8 90680024 */ stw r3, 0x24(r8)
-/* 803704DC 60000000 */ nop
-/* 803704E0 48000008 */ b lbl_803704e8
-lbl_803704e4:
-/* 803704E4 4800000C */ b lbl_803704f0
-lbl_803704e8:
-/* 803704E8 60000000 */ nop
-/* 803704EC 4BFFFFFC */ b lbl_803704e8
-lbl_803704f0:
-/* 803704F0 4BFFFF98 */ b lbl_80370488
-.size func_80370484, . - func_80370484
-
-
-.global func_803704f4
-.type func_803704f4, @function
-func_803704f4:
-/* 803704F4 7C0802A6 */ mflr r0
-/* 803704F8 90010004 */ stw r0, 4(r1)
-/* 803704FC 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80370500 93E10014 */ stw r31, 0x14(r1)
-/* 80370504 7C7F1B78 */ mr r31, r3
-/* 80370508 4BFFE5CD */ bl func_8036ead4
-/* 8037050C 3C60CC00 */ lis r3, 0xcc00
-/* 80370510 38632000 */ addi r3, r3, 0x2000
-/* 80370514 38000000 */ li r0, 0x0
-/* 80370518 B0030002 */ sth r0, 2(r3)
-/* 8037051C 4BFFD4F5 */ bl func_8036da10
-/* 80370520 57E31838 */ slwi r3, r31, 3
-/* 80370524 4BFFFF61 */ bl func_80370484
-/* 80370528 8001001C */ lwz r0, 0x1c(r1)
-/* 8037052C 83E10014 */ lwz r31, 0x14(r1)
-/* 80370530 38210018 */ addi r1, r1, 0x18
-/* 80370534 7C0803A6 */ mtlr r0
-/* 80370538 4E800020 */ blr
-.size func_803704f4, . - func_803704f4
-
-
-.global func_8037053c
-.type func_8037053c, @function
-func_8037053c:
-/* 8037053C 7C0802A6 */ mflr r0
-/* 80370540 90010004 */ stw r0, 4(r1)
-/* 80370544 9421FFC0 */ stwu r1, -0x40(r1)
-/* 80370548 BF410028 */ stmw r26, 0x28(r1)
-/* 8037054C 7C7A1B78 */ mr r26, r3
-/* 80370550 7C9D2378 */ mr r29, r4
-/* 80370554 7CBE2B78 */ mr r30, r5
-/* 80370558 4800125D */ bl func_803717b4
-/* 8037055C 4BFFD299 */ bl func_8036d7f4
-/* 80370560 2C1A0002 */ cmpwi r26, 0x2
-/* 80370564 40820010 */ bne- lbl_80370574
-/* 80370568 38600001 */ li r3, 0x1
-/* 8037056C 4800AAC1 */ bl func_8037b02c
-/* 80370570 7C7F1B78 */ mr r31, r3
-lbl_80370574:
-/* 80370574 48000004 */ b lbl_80370578
-lbl_80370578:
-/* 80370578 48000004 */ b lbl_8037057c
-lbl_8037057c:
-/* 8037057C 836DCA70 */ lwz r27, lbl_805c6890@sda21(0)
-/* 80370580 3B800000 */ li r28, 0x0
-/* 80370584 48000004 */ b lbl_80370588
-lbl_80370588:
-/* 80370588 48000004 */ b lbl_8037058c
-lbl_8037058c:
-/* 8037058C 48000024 */ b lbl_803705b0
-lbl_80370590:
-/* 80370590 38600000 */ li r3, 0x0
-/* 80370594 819B0000 */ lwz r12, 0(r27)
-/* 80370598 7D8803A6 */ mtlr r12
-/* 8037059C 4E800021 */ blrl
-/* 803705A0 7C600034 */ cntlzw r0, r3
-/* 803705A4 837B0008 */ lwz r27, 8(r27)
-/* 803705A8 5400D97E */ srwi r0, r0, 5
-/* 803705AC 7F9C0378 */ or r28, r28, r0
-lbl_803705b0:
-/* 803705B0 281B0000 */ cmplwi r27, 0
-/* 803705B4 4082FFDC */ bne+ lbl_80370590
-/* 803705B8 48000C6D */ bl func_80371224
-/* 803705BC 7C600034 */ cntlzw r0, r3
-/* 803705C0 5400D97E */ srwi r0, r0, 5
-/* 803705C4 7F9C0378 */ or r28, r28, r0
-/* 803705C8 2C1C0000 */ cmpwi r28, 0x0
-/* 803705CC 4182000C */ beq- lbl_803705d8
-/* 803705D0 38000000 */ li r0, 0x0
-/* 803705D4 48000008 */ b lbl_803705dc
-lbl_803705d8:
-/* 803705D8 38000001 */ li r0, 0x1
-lbl_803705dc:
-/* 803705DC 2C000000 */ cmpwi r0, 0x0
-/* 803705E0 4182FF9C */ beq+ lbl_8037057c
-/* 803705E4 2C1A0001 */ cmpwi r26, 0x1
-/* 803705E8 40820038 */ bne- lbl_80370620
-/* 803705EC 2C1E0000 */ cmpwi r30, 0x0
-/* 803705F0 41820030 */ beq- lbl_80370620
-/* 803705F4 48000829 */ bl func_80370e1c
-/* 803705F8 88030013 */ lbz r0, 0x13(r3)
-/* 803705FC 60000040 */ ori r0, r0, 0x40
-/* 80370600 98030013 */ stb r0, 0x13(r3)
-/* 80370604 38600001 */ li r3, 0x1
-/* 80370608 48000BD5 */ bl func_803711dc
-/* 8037060C 48000004 */ b lbl_80370610
-lbl_80370610:
-/* 80370610 48000004 */ b lbl_80370614
-lbl_80370614:
-/* 80370614 48000C11 */ bl func_80371224
-/* 80370618 2C030000 */ cmpwi r3, 0x0
-/* 8037061C 4182FFF8 */ beq+ lbl_80370614
-lbl_80370620:
-/* 80370620 4BFFE4B5 */ bl func_8036ead4
-/* 80370624 838DCA70 */ lwz r28, lbl_805c6890@sda21(0)
-/* 80370628 3B600000 */ li r27, 0x0
-/* 8037062C 48000004 */ b lbl_80370630
-lbl_80370630:
-/* 80370630 48000004 */ b lbl_80370634
-lbl_80370634:
-/* 80370634 48000024 */ b lbl_80370658
-lbl_80370638:
-/* 80370638 38600001 */ li r3, 0x1
-/* 8037063C 819C0000 */ lwz r12, 0(r28)
-/* 80370640 7D8803A6 */ mtlr r12
-/* 80370644 4E800021 */ blrl
-/* 80370648 7C600034 */ cntlzw r0, r3
-/* 8037064C 839C0008 */ lwz r28, 8(r28)
-/* 80370650 5400D97E */ srwi r0, r0, 5
-/* 80370654 7F7B0378 */ or r27, r27, r0
-lbl_80370658:
-/* 80370658 281C0000 */ cmplwi r28, 0
-/* 8037065C 4082FFDC */ bne+ lbl_80370638
-/* 80370660 48000BC5 */ bl func_80371224
-/* 80370664 4BFFD4D5 */ bl func_8036db38
-/* 80370668 2C1A0001 */ cmpwi r26, 0x1
-/* 8037066C 40820028 */ bne- lbl_80370694
-/* 80370670 4BFFE465 */ bl func_8036ead4
-/* 80370674 3C60CC00 */ lis r3, 0xcc00
-/* 80370678 38632000 */ addi r3, r3, 0x2000
-/* 8037067C 38000000 */ li r0, 0x0
-/* 80370680 B0030002 */ sth r0, 2(r3)
-/* 80370684 4BFFD38D */ bl func_8036da10
-/* 80370688 57A31838 */ slwi r3, r29, 3
-/* 8037068C 4BFFFDF9 */ bl func_80370484
-/* 80370690 48000060 */ b lbl_803706f0
-lbl_80370694:
-/* 80370694 2C1A0000 */ cmpwi r26, 0x0
-/* 80370698 40820058 */ bne- lbl_803706f0
-/* 8037069C 3C608000 */ lis r3, 0x8000
-/* 803706A0 806300DC */ lwz r3, 0xdc(r3)
-/* 803706A4 48000004 */ b lbl_803706a8
-lbl_803706a8:
-/* 803706A8 48000004 */ b lbl_803706ac
-lbl_803706ac:
-/* 803706AC 4800002C */ b lbl_803706d8
-lbl_803706b0:
-/* 803706B0 A00302C8 */ lhz r0, 0x2c8(r3)
-/* 803706B4 836302FC */ lwz r27, 0x2fc(r3)
-/* 803706B8 2C000004 */ cmpwi r0, 0x4
-/* 803706BC 41820014 */ beq- lbl_803706d0
-/* 803706C0 40800014 */ bge- lbl_803706d4
-/* 803706C4 2C000001 */ cmpwi r0, 0x1
-/* 803706C8 41820008 */ beq- lbl_803706d0
-/* 803706CC 48000008 */ b lbl_803706d4
-lbl_803706d0:
-/* 803706D0 48001889 */ bl func_80371f58
-lbl_803706d4:
-/* 803706D4 7F63DB78 */ mr r3, r27
-lbl_803706d8:
-/* 803706D8 28030000 */ cmplwi r3, 0
-/* 803706DC 4082FFD4 */ bne+ lbl_803706b0
-/* 803706E0 48001115 */ bl func_803717f4
-/* 803706E4 7FA3EB78 */ mr r3, r29
-/* 803706E8 7FC4F378 */ mr r4, r30
-/* 803706EC 4BFFFB55 */ bl func_80370240
-lbl_803706f0:
-/* 803706F0 3C608000 */ lis r3, 0x8000
-/* 803706F4 806300DC */ lwz r3, 0xdc(r3)
-/* 803706F8 48000004 */ b lbl_803706fc
-lbl_803706fc:
-/* 803706FC 48000004 */ b lbl_80370700
-lbl_80370700:
-/* 80370700 4800002C */ b lbl_8037072c
-lbl_80370704:
-/* 80370704 A00302C8 */ lhz r0, 0x2c8(r3)
-/* 80370708 836302FC */ lwz r27, 0x2fc(r3)
-/* 8037070C 2C000004 */ cmpwi r0, 0x4
-/* 80370710 41820014 */ beq- lbl_80370724
-/* 80370714 40800014 */ bge- lbl_80370728
-/* 80370718 2C000001 */ cmpwi r0, 0x1
-/* 8037071C 41820008 */ beq- lbl_80370724
-/* 80370720 48000008 */ b lbl_80370728
-lbl_80370724:
-/* 80370724 48001835 */ bl func_80371f58
-lbl_80370728:
-/* 80370728 7F63DB78 */ mr r3, r27
-lbl_8037072c:
-/* 8037072C 28030000 */ cmplwi r3, 0
-/* 80370730 4082FFD4 */ bne+ lbl_80370704
-/* 80370734 3FA08000 */ lis r29, 0x8000
-/* 80370738 387D0040 */ addi r3, r29, 0x40
-/* 8037073C 38800000 */ li r4, 0x0
-/* 80370740 38A0008C */ li r5, 0x8c
-/* 80370744 4BC9DBF1 */ bl func_8000e334
-/* 80370748 387D00D4 */ addi r3, r29, 0xd4
-/* 8037074C 38800000 */ li r4, 0x0
-/* 80370750 38A00014 */ li r5, 0x14
-/* 80370754 4BC9DBE1 */ bl func_8000e334
-/* 80370758 387D00F4 */ addi r3, r29, 0xf4
-/* 8037075C 38800000 */ li r4, 0x0
-/* 80370760 38A00004 */ li r5, 0x4
-/* 80370764 4BC9DBD1 */ bl func_8000e334
-/* 80370768 387D3000 */ addi r3, r29, 0x3000
-/* 8037076C 38800000 */ li r4, 0x0
-/* 80370770 38A000C0 */ li r5, 0xc0
-/* 80370774 4BC9DBC1 */ bl func_8000e334
-/* 80370778 387D30C8 */ addi r3, r29, 0x30c8
-/* 8037077C 38800000 */ li r4, 0x0
-/* 80370780 38A0000C */ li r5, 0xc
-/* 80370784 4BC9DBB1 */ bl func_8000e334
-/* 80370788 387D30E2 */ addi r3, r29, 0x30e2
-/* 8037078C 38800000 */ li r4, 0x0
-/* 80370790 38A00001 */ li r5, 0x1
-/* 80370794 4BC9DBA1 */ bl func_8000e334
-/* 80370798 7FE3FB78 */ mr r3, r31
-/* 8037079C 4800A891 */ bl func_8037b02c
-/* 803707A0 BB410028 */ lmw r26, 0x28(r1)
-/* 803707A4 80010044 */ lwz r0, 0x44(r1)
-/* 803707A8 38210040 */ addi r1, r1, 0x40
-/* 803707AC 7C0803A6 */ mtlr r0
-/* 803707B0 4E800020 */ blr
-.size func_8037053c, . - func_8037053c
-
-
-.global func_803707b4
-.type func_803707b4, @function
-func_803707b4:
-/* 803707B4 3C608000 */ lis r3, 0x8000
-/* 803707B8 880330E2 */ lbz r0, 0x30e2(r3)
-/* 803707BC 28000000 */ cmplwi r0, 0
-/* 803707C0 4182000C */ beq- lbl_803707cc
-/* 803707C4 3C608000 */ lis r3, 0x8000
-/* 803707C8 48000018 */ b lbl_803707e0
-lbl_803707cc:
-/* 803707CC 3C60CC00 */ lis r3, 0xcc00
-/* 803707D0 38633000 */ addi r3, r3, 0x3000
-/* 803707D4 80030024 */ lwz r0, 0x24(r3)
-/* 803707D8 54000038 */ rlwinm r0, r0, 0, 0, 0x1c
-/* 803707DC 5403E8FE */ srwi r3, r0, 3
-lbl_803707e0:
-/* 803707E0 4E800020 */ blr
-.size func_803707b4, . - func_803707b4
-
diff --git a/asm/Dolphin/os/OSResetSW.s b/asm/Dolphin/os/OSResetSW.s
deleted file mode 100644
index 33dd3ce..0000000
--- a/asm/Dolphin/os/OSResetSW.s
+++ /dev/null
@@ -1,258 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_803707e4
-.type func_803707e4, @function
-func_803707e4:
-/* 803707E4 7C0802A6 */ mflr r0
-/* 803707E8 90010004 */ stw r0, 4(r1)
-/* 803707EC 9421FFD8 */ stwu r1, -0x28(r1)
-/* 803707F0 93E10024 */ stw r31, 0x24(r1)
-/* 803707F4 93C10020 */ stw r30, 0x20(r1)
-/* 803707F8 93A1001C */ stw r29, 0x1c(r1)
-/* 803707FC 48001FE9 */ bl func_803727e4
-/* 80370800 3CA08000 */ lis r5, 0x8000
-/* 80370804 908DCA94 */ stw r4, lbl_805c68b4@sda21(0)
-/* 80370808 800500F8 */ lwz r0, 0xf8(r5)
-/* 8037080C 3C80431C */ lis r4, 0x431c
-/* 80370810 3884DE83 */ addi r4, r4, -0x217d
-/* 80370814 906DCA90 */ stw r3, lbl_805c68b0@sda21(0)
-/* 80370818 5400F0BE */ srwi r0, r0, 2
-/* 8037081C 7C040016 */ mulhwu r0, r4, r0
-/* 80370820 54008BFE */ srwi r0, r0, 0xf
-/* 80370824 1C000064 */ mulli r0, r0, 0x64
-/* 80370828 541DE8FE */ srwi r29, r0, 3
-/* 8037082C 3BC00000 */ li r30, 0x0
-/* 80370830 3FE0CC00 */ lis r31, 0xcc00
-lbl_80370834:
-/* 80370834 48001FB1 */ bl func_803727e4
-/* 80370838 80CDCA94 */ lwz r6, lbl_805c68b4@sda21(0)
-/* 8037083C 6FC58000 */ xoris r5, r30, 0x8000
-/* 80370840 800DCA90 */ lwz r0, lbl_805c68b0@sda21(0)
-/* 80370844 7C862010 */ subfc r4, r6, r4
-/* 80370848 7C001910 */ subfe r0, r0, r3
-/* 8037084C 6C038000 */ xoris r3, r0, 0x8000
-/* 80370850 7C1D2010 */ subfc r0, r29, r4
-/* 80370854 7CA51910 */ subfe r5, r5, r3
-/* 80370858 7CA31910 */ subfe r5, r3, r3
-/* 8037085C 7CA500D1 */ neg. r5, r5
-/* 80370860 41820010 */ beq- lbl_80370870
-/* 80370864 801F3000 */ lwz r0, 0x3000(r31)
-/* 80370868 540003DF */ rlwinm. r0, r0, 0, 0xf, 0xf
-/* 8037086C 4182FFC8 */ beq+ lbl_80370834
-lbl_80370870:
-/* 80370870 3C60CC00 */ lis r3, 0xcc00
-/* 80370874 80033000 */ lwz r0, 0x3000(r3)
-/* 80370878 540003DF */ rlwinm. r0, r0, 0, 0xf, 0xf
-/* 8037087C 40820034 */ bne- lbl_803708b0
-/* 80370880 38000001 */ li r0, 0x1
-/* 80370884 900DCA7C */ stw r0, lbl_805c689c@sda21(0)
-/* 80370888 38600200 */ li r3, 0x200
-/* 8037088C 900DCA80 */ stw r0, lbl_805c68a0@sda21(0)
-/* 80370890 4BFFE60D */ bl func_8036ee9c
-/* 80370894 818DCA78 */ lwz r12, lbl_805c6898@sda21(0)
-/* 80370898 280C0000 */ cmplwi r12, 0
-/* 8037089C 41820014 */ beq- lbl_803708b0
-/* 803708A0 38000000 */ li r0, 0x0
-/* 803708A4 7D8803A6 */ mtlr r12
-/* 803708A8 900DCA78 */ stw r0, lbl_805c6898@sda21(0)
-/* 803708AC 4E800021 */ blrl
-lbl_803708b0:
-/* 803708B0 38000002 */ li r0, 0x2
-/* 803708B4 3C60CC00 */ lis r3, 0xcc00
-/* 803708B8 90033000 */ stw r0, 0x3000(r3)
-/* 803708BC 8001002C */ lwz r0, 0x2c(r1)
-/* 803708C0 83E10024 */ lwz r31, 0x24(r1)
-/* 803708C4 83C10020 */ lwz r30, 0x20(r1)
-/* 803708C8 83A1001C */ lwz r29, 0x1c(r1)
-/* 803708CC 38210028 */ addi r1, r1, 0x28
-/* 803708D0 7C0803A6 */ mtlr r0
-/* 803708D4 4E800020 */ blr
-.size func_803707e4, . - func_803707e4
-
-
-.global func_803708d8
-.type func_803708d8, @function
-func_803708d8:
-/* 803708D8 7C0802A6 */ mflr r0
-/* 803708DC 90010004 */ stw r0, 4(r1)
-/* 803708E0 9421FFE8 */ stwu r1, -0x18(r1)
-/* 803708E4 93E10014 */ stw r31, 0x14(r1)
-/* 803708E8 93C10010 */ stw r30, 0x10(r1)
-/* 803708EC 93A1000C */ stw r29, 0xc(r1)
-/* 803708F0 4BFFE1E5 */ bl func_8036ead4
-/* 803708F4 7C7E1B78 */ mr r30, r3
-/* 803708F8 48001EED */ bl func_803727e4
-/* 803708FC 3CA0CC00 */ lis r5, 0xcc00
-/* 80370900 80053000 */ lwz r0, 0x3000(r5)
-/* 80370904 540003DF */ rlwinm. r0, r0, 0, 0xf, 0xf
-/* 80370908 408200DC */ bne- lbl_803709e4
-/* 8037090C 800DCA7C */ lwz r0, lbl_805c689c@sda21(0)
-/* 80370910 2C000000 */ cmpwi r0, 0x0
-/* 80370914 40820040 */ bne- lbl_80370954
-/* 80370918 800DCA88 */ lwz r0, lbl_805c68a8@sda21(0)
-/* 8037091C 38C00000 */ li r6, 0x0
-/* 80370920 80ADCA8C */ lwz r5, lbl_805c68ac@sda21(0)
-/* 80370924 38E00001 */ li r7, 0x1
-/* 80370928 7C003278 */ xor r0, r0, r6
-/* 8037092C 7CA53278 */ xor r5, r5, r6
-/* 80370930 90EDCA7C */ stw r7, lbl_805c689c@sda21(0)
-/* 80370934 7CA00379 */ or. r0, r5, r0
-/* 80370938 41820008 */ beq- lbl_80370940
-/* 8037093C 48000008 */ b lbl_80370944
-lbl_80370940:
-/* 80370940 7CC73378 */ mr r7, r6
-lbl_80370944:
-/* 80370944 908DCA94 */ stw r4, lbl_805c68b4@sda21(0)
-/* 80370948 7CFD3B78 */ mr r29, r7
-/* 8037094C 906DCA90 */ stw r3, lbl_805c68b0@sda21(0)
-/* 80370950 48000148 */ b lbl_80370a98
-lbl_80370954:
-/* 80370954 800DCA88 */ lwz r0, lbl_805c68a8@sda21(0)
-/* 80370958 39200000 */ li r9, 0x0
-/* 8037095C 80ADCA8C */ lwz r5, lbl_805c68ac@sda21(0)
-/* 80370960 39400001 */ li r10, 0x1
-/* 80370964 7C004A78 */ xor r0, r0, r9
-/* 80370968 7CA54A78 */ xor r5, r5, r9
-/* 8037096C 7CA00379 */ or. r0, r5, r0
-/* 80370970 40820058 */ bne- lbl_803709c8
-/* 80370974 3CC08000 */ lis r6, 0x8000
-/* 80370978 80ADCA94 */ lwz r5, lbl_805c68b4@sda21(0)
-/* 8037097C 80E600F8 */ lwz r7, 0xf8(r6)
-/* 80370980 3CC0431C */ lis r6, 0x431c
-/* 80370984 3906DE83 */ addi r8, r6, -0x217d
-/* 80370988 800DCA90 */ lwz r0, lbl_805c68b0@sda21(0)
-/* 8037098C 54E6F0BE */ srwi r6, r7, 2
-/* 80370990 7CC83016 */ mulhwu r6, r8, r6
-/* 80370994 54C68BFE */ srwi r6, r6, 0xf
-/* 80370998 1CC60064 */ mulli r6, r6, 0x64
-/* 8037099C 7CE52010 */ subfc r7, r5, r4
-/* 803709A0 7C001910 */ subfe r0, r0, r3
-/* 803709A4 54C8E8FE */ srwi r8, r6, 3
-/* 803709A8 6C058000 */ xoris r5, r0, 0x8000
-/* 803709AC 6D268000 */ xoris r6, r9, 0x8000
-/* 803709B0 7C074010 */ subfc r0, r7, r8
-/* 803709B4 7CA53110 */ subfe r5, r5, r6
-/* 803709B8 7CA63110 */ subfe r5, r6, r6
-/* 803709BC 7CA500D1 */ neg. r5, r5
-/* 803709C0 40820008 */ bne- lbl_803709c8
-/* 803709C4 7D2A4B78 */ mr r10, r9
-lbl_803709c8:
-/* 803709C8 2C0A0000 */ cmpwi r10, 0x0
-/* 803709CC 4182000C */ beq- lbl_803709d8
-/* 803709D0 38000001 */ li r0, 0x1
-/* 803709D4 48000008 */ b lbl_803709dc
-lbl_803709d8:
-/* 803709D8 38000000 */ li r0, 0x0
-lbl_803709dc:
-/* 803709DC 7C1D0378 */ mr r29, r0
-/* 803709E0 480000B8 */ b lbl_80370a98
-lbl_803709e4:
-/* 803709E4 800DCA7C */ lwz r0, lbl_805c689c@sda21(0)
-/* 803709E8 2C000000 */ cmpwi r0, 0x0
-/* 803709EC 41820034 */ beq- lbl_80370a20
-/* 803709F0 80ADCA80 */ lwz r5, lbl_805c68a0@sda21(0)
-/* 803709F4 38000000 */ li r0, 0x0
-/* 803709F8 900DCA7C */ stw r0, lbl_805c689c@sda21(0)
-/* 803709FC 2C050000 */ cmpwi r5, 0x0
-/* 80370A00 3BA50000 */ addi r29, r5, 0x0
-/* 80370A04 41820010 */ beq- lbl_80370a14
-/* 80370A08 908DCA8C */ stw r4, lbl_805c68ac@sda21(0)
-/* 80370A0C 906DCA88 */ stw r3, lbl_805c68a8@sda21(0)
-/* 80370A10 48000088 */ b lbl_80370a98
-lbl_80370a14:
-/* 80370A14 900DCA8C */ stw r0, lbl_805c68ac@sda21(0)
-/* 80370A18 900DCA88 */ stw r0, lbl_805c68a8@sda21(0)
-/* 80370A1C 4800007C */ b lbl_80370a98
-lbl_80370a20:
-/* 80370A20 80CDCA88 */ lwz r6, lbl_805c68a8@sda21(0)
-/* 80370A24 39000000 */ li r8, 0x0
-/* 80370A28 80EDCA8C */ lwz r7, lbl_805c68ac@sda21(0)
-/* 80370A2C 7CC04278 */ xor r0, r6, r8
-/* 80370A30 7CE54278 */ xor r5, r7, r8
-/* 80370A34 7CA00379 */ or. r0, r5, r0
-/* 80370A38 41820050 */ beq- lbl_80370a88
-/* 80370A3C 3CA08000 */ lis r5, 0x8000
-/* 80370A40 800500F8 */ lwz r0, 0xf8(r5)
-/* 80370A44 3CA01062 */ lis r5, 0x1062
-/* 80370A48 38A54DD3 */ addi r5, r5, 0x4dd3
-/* 80370A4C 5400F0BE */ srwi r0, r0, 2
-/* 80370A50 7C050016 */ mulhwu r0, r5, r0
-/* 80370A54 5400D1BE */ srwi r0, r0, 6
-/* 80370A58 1C000028 */ mulli r0, r0, 0x28
-/* 80370A5C 7CE72010 */ subfc r7, r7, r4
-/* 80370A60 7CA61910 */ subfe r5, r6, r3
-/* 80370A64 6CA68000 */ xoris r6, r5, 0x8000
-/* 80370A68 6D058000 */ xoris r5, r8, 0x8000
-/* 80370A6C 7C003810 */ subfc r0, r0, r7
-/* 80370A70 7CA53110 */ subfe r5, r5, r6
-/* 80370A74 7CA63110 */ subfe r5, r6, r6
-/* 80370A78 7CA500D1 */ neg. r5, r5
-/* 80370A7C 4182000C */ beq- lbl_80370a88
-/* 80370A80 3BA00001 */ li r29, 0x1
-/* 80370A84 48000014 */ b lbl_80370a98
-lbl_80370a88:
-/* 80370A88 38000000 */ li r0, 0x0
-/* 80370A8C 900DCA8C */ stw r0, lbl_805c68ac@sda21(0)
-/* 80370A90 3BA00000 */ li r29, 0x0
-/* 80370A94 900DCA88 */ stw r0, lbl_805c68a8@sda21(0)
-lbl_80370a98:
-/* 80370A98 3CA08000 */ lis r5, 0x8000
-/* 80370A9C 93ADCA80 */ stw r29, lbl_805c68a0@sda21(0)
-/* 80370AA0 880530E3 */ lbz r0, 0x30e3(r5)
-/* 80370AA4 540006BF */ clrlwi. r0, r0, 0x1a
-/* 80370AA8 418200A0 */ beq- lbl_80370b48
-/* 80370AAC 1D40003C */ mulli r10, r0, 0x3c
-/* 80370AB0 800500F8 */ lwz r0, 0xf8(r5)
-/* 80370AB4 812DCA24 */ lwz r9, lbl_805c6844@sda21(0)
-/* 80370AB8 810DCA20 */ lwz r8, lbl_805c6840@sda21(0)
-/* 80370ABC 5406F0BE */ srwi r6, r0, 2
-/* 80370AC0 7D40FE70 */ srawi r0, r10, 0x1f
-/* 80370AC4 7CE031D6 */ mullw r7, r0, r6
-/* 80370AC8 7C0A3016 */ mulhwu r0, r10, r6
-/* 80370ACC 7CAA31D6 */ mullw r5, r10, r6
-/* 80370AD0 7D292814 */ addc r9, r9, r5
-/* 80370AD4 3BE00000 */ li r31, 0x0
-/* 80370AD8 7CE70214 */ add r7, r7, r0
-/* 80370ADC 7C0AF9D6 */ mullw r0, r10, r31
-/* 80370AE0 7C070214 */ add r0, r7, r0
-/* 80370AE4 7D080114 */ adde r8, r8, r0
-/* 80370AE8 6D078000 */ xoris r7, r8, 0x8000
-/* 80370AEC 6C658000 */ xoris r5, r3, 0x8000
-/* 80370AF0 7C044810 */ subfc r0, r4, r9
-/* 80370AF4 7CA53910 */ subfe r5, r5, r7
-/* 80370AF8 7CA73910 */ subfe r5, r7, r7
-/* 80370AFC 7CA500D1 */ neg. r5, r5
-/* 80370B00 41820048 */ beq- lbl_80370b48
-/* 80370B04 7C892010 */ subfc r4, r9, r4
-/* 80370B08 7C681910 */ subfe r3, r8, r3
-/* 80370B0C 38A00000 */ li r5, 0x0
-/* 80370B10 48022AA1 */ bl func_803935b0
-/* 80370B14 38A00000 */ li r5, 0x0
-/* 80370B18 38C00002 */ li r6, 0x2
-/* 80370B1C 48022A95 */ bl func_803935b0
-/* 80370B20 38000001 */ li r0, 0x1
-/* 80370B24 7C840038 */ and r4, r4, r0
-/* 80370B28 7C60F838 */ and r0, r3, r31
-/* 80370B2C 7C83FA78 */ xor r3, r4, r31
-/* 80370B30 7C00FA78 */ xor r0, r0, r31
-/* 80370B34 7C600379 */ or. r0, r3, r0
-/* 80370B38 4082000C */ bne- lbl_80370b44
-/* 80370B3C 3BA00001 */ li r29, 0x1
-/* 80370B40 48000008 */ b lbl_80370b48
-lbl_80370b44:
-/* 80370B44 3BA00000 */ li r29, 0x0
-lbl_80370b48:
-/* 80370B48 7FC3F378 */ mr r3, r30
-/* 80370B4C 4BFFDFB1 */ bl func_8036eafc
-/* 80370B50 7FA3EB78 */ mr r3, r29
-/* 80370B54 8001001C */ lwz r0, 0x1c(r1)
-/* 80370B58 83E10014 */ lwz r31, 0x14(r1)
-/* 80370B5C 83C10010 */ lwz r30, 0x10(r1)
-/* 80370B60 83A1000C */ lwz r29, 0xc(r1)
-/* 80370B64 38210018 */ addi r1, r1, 0x18
-/* 80370B68 7C0803A6 */ mtlr r0
-/* 80370B6C 4E800020 */ blr
-.size func_803708d8, . - func_803708d8
-
diff --git a/asm/Dolphin/os/OSRtc.s b/asm/Dolphin/os/OSRtc.s
deleted file mode 100644
index f355f2d..0000000
--- a/asm/Dolphin/os/OSRtc.s
+++ /dev/null
@@ -1,785 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_80370b70
-.type func_80370b70, @function
-func_80370b70:
-/* 80370B70 7C0802A6 */ mflr r0
-/* 80370B74 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80370B78 90010004 */ stw r0, 4(r1)
-/* 80370B7C 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80370B80 93E10014 */ stw r31, 0x14(r1)
-/* 80370B84 3BE3ECA0 */ addi r31, r3, lbl_8053eca0@l
-/* 80370B88 93C10010 */ stw r30, 0x10(r1)
-/* 80370B8C 3BDF0040 */ addi r30, r31, 0x40
-/* 80370B90 809F0040 */ lwz r4, 0x40(r31)
-/* 80370B94 7C7F2214 */ add r3, r31, r4
-/* 80370B98 20A40040 */ subfic r5, r4, 0x40
-/* 80370B9C 48000035 */ bl func_80370bd0
-/* 80370BA0 907F004C */ stw r3, 0x4c(r31)
-/* 80370BA4 801F004C */ lwz r0, 0x4c(r31)
-/* 80370BA8 2C000000 */ cmpwi r0, 0x0
-/* 80370BAC 4182000C */ beq- lbl_80370bb8
-/* 80370BB0 38000040 */ li r0, 0x40
-/* 80370BB4 901E0000 */ stw r0, 0(r30)
-lbl_80370bb8:
-/* 80370BB8 8001001C */ lwz r0, 0x1c(r1)
-/* 80370BBC 83E10014 */ lwz r31, 0x14(r1)
-/* 80370BC0 83C10010 */ lwz r30, 0x10(r1)
-/* 80370BC4 38210018 */ addi r1, r1, 0x18
-/* 80370BC8 7C0803A6 */ mtlr r0
-/* 80370BCC 4E800020 */ blr
-.size func_80370b70, . - func_80370b70
-
-
-.global func_80370bd0
-.type func_80370bd0, @function
-func_80370bd0:
-/* 80370BD0 7C0802A6 */ mflr r0
-/* 80370BD4 3CC08037 */ lis r6, func_80370b70@ha
-/* 80370BD8 90010004 */ stw r0, 4(r1)
-/* 80370BDC 38060B70 */ addi r0, r6, func_80370b70@l
-/* 80370BE0 9421FFD8 */ stwu r1, -0x28(r1)
-/* 80370BE4 93E10024 */ stw r31, 0x24(r1)
-/* 80370BE8 3BE40000 */ addi r31, r4, 0x0
-/* 80370BEC 38800001 */ li r4, 0x1
-/* 80370BF0 93C10020 */ stw r30, 0x20(r1)
-/* 80370BF4 3BC50000 */ addi r30, r5, 0x0
-/* 80370BF8 7C050378 */ mr r5, r0
-/* 80370BFC 93A1001C */ stw r29, 0x1c(r1)
-/* 80370C00 3BA30000 */ addi r29, r3, 0x0
-/* 80370C04 38600000 */ li r3, 0x0
-/* 80370C08 480BBB75 */ bl func_8042c77c
-/* 80370C0C 2C030000 */ cmpwi r3, 0x0
-/* 80370C10 4082000C */ bne- lbl_80370c1c
-/* 80370C14 38600000 */ li r3, 0x0
-/* 80370C18 480000B4 */ b lbl_80370ccc
-lbl_80370c1c:
-/* 80370C1C 38600000 */ li r3, 0x0
-/* 80370C20 38800001 */ li r4, 0x1
-/* 80370C24 38A00003 */ li r5, 0x3
-/* 80370C28 480BB455 */ bl func_8042c07c
-/* 80370C2C 2C030000 */ cmpwi r3, 0x0
-/* 80370C30 40820014 */ bne- lbl_80370c44
-/* 80370C34 38600000 */ li r3, 0x0
-/* 80370C38 480BBC39 */ bl func_8042c870
-/* 80370C3C 38600000 */ li r3, 0x0
-/* 80370C40 4800008C */ b lbl_80370ccc
-lbl_80370c44:
-/* 80370C44 57FF3032 */ slwi r31, r31, 6
-/* 80370C48 381F0100 */ addi r0, r31, 0x100
-/* 80370C4C 6400A000 */ oris r0, r0, 0xa000
-/* 80370C50 90010014 */ stw r0, 0x14(r1)
-/* 80370C54 38810014 */ addi r4, r1, 0x14
-/* 80370C58 38600000 */ li r3, 0x0
-/* 80370C5C 38A00004 */ li r5, 0x4
-/* 80370C60 38C00001 */ li r6, 0x1
-/* 80370C64 38E00000 */ li r7, 0x0
-/* 80370C68 480BA8C1 */ bl func_8042b528
-/* 80370C6C 7C600034 */ cntlzw r0, r3
-/* 80370C70 541FD97E */ srwi r31, r0, 5
-/* 80370C74 38600000 */ li r3, 0x0
-/* 80370C78 480BAC99 */ bl func_8042b910
-/* 80370C7C 7C600034 */ cntlzw r0, r3
-/* 80370C80 5400D97E */ srwi r0, r0, 5
-/* 80370C84 389D0000 */ addi r4, r29, 0x0
-/* 80370C88 38BE0000 */ addi r5, r30, 0x0
-/* 80370C8C 7FFF0378 */ or r31, r31, r0
-/* 80370C90 38600000 */ li r3, 0x0
-/* 80370C94 38C00001 */ li r6, 0x1
-/* 80370C98 480BAAED */ bl func_8042b784
-/* 80370C9C 7C600034 */ cntlzw r0, r3
-/* 80370CA0 5400D97E */ srwi r0, r0, 5
-/* 80370CA4 7FFF0378 */ or r31, r31, r0
-/* 80370CA8 38600000 */ li r3, 0x0
-/* 80370CAC 480BB4FD */ bl func_8042c1a8
-/* 80370CB0 7C600034 */ cntlzw r0, r3
-/* 80370CB4 5400D97E */ srwi r0, r0, 5
-/* 80370CB8 7FFF0378 */ or r31, r31, r0
-/* 80370CBC 38600000 */ li r3, 0x0
-/* 80370CC0 480BBBB1 */ bl func_8042c870
-/* 80370CC4 7FE00034 */ cntlzw r0, r31
-/* 80370CC8 5403D97E */ srwi r3, r0, 5
-lbl_80370ccc:
-/* 80370CCC 8001002C */ lwz r0, 0x2c(r1)
-/* 80370CD0 83E10024 */ lwz r31, 0x24(r1)
-/* 80370CD4 83C10020 */ lwz r30, 0x20(r1)
-/* 80370CD8 83A1001C */ lwz r29, 0x1c(r1)
-/* 80370CDC 38210028 */ addi r1, r1, 0x28
-/* 80370CE0 7C0803A6 */ mtlr r0
-/* 80370CE4 4E800020 */ blr
-.size func_80370bd0, . - func_80370bd0
-
-
-.global func_80370ce8
-.type func_80370ce8, @function
-func_80370ce8:
-/* 80370CE8 7C0802A6 */ mflr r0
-/* 80370CEC 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80370CF0 90010004 */ stw r0, 4(r1)
-/* 80370CF4 38800040 */ li r4, 0x40
-/* 80370CF8 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80370CFC 93E10014 */ stw r31, 0x14(r1)
-/* 80370D00 3BE00000 */ li r31, 0x0
-/* 80370D04 93C10010 */ stw r30, 0x10(r1)
-/* 80370D08 3BC3ECA0 */ addi r30, r3, lbl_8053eca0@l
-/* 80370D0C 387E0000 */ addi r3, r30, 0x0
-/* 80370D10 93FE0044 */ stw r31, 0x44(r30)
-/* 80370D14 93FE0048 */ stw r31, 0x48(r30)
-/* 80370D18 4BFFCBC9 */ bl func_8036d8e0
-/* 80370D1C 38600000 */ li r3, 0x0
-/* 80370D20 38800001 */ li r4, 0x1
-/* 80370D24 38A00000 */ li r5, 0x0
-/* 80370D28 480BBA55 */ bl func_8042c77c
-/* 80370D2C 2C030000 */ cmpwi r3, 0x0
-/* 80370D30 40820008 */ bne- lbl_80370d38
-/* 80370D34 480000C4 */ b lbl_80370df8
-lbl_80370d38:
-/* 80370D38 38600000 */ li r3, 0x0
-/* 80370D3C 38800001 */ li r4, 0x1
-/* 80370D40 38A00003 */ li r5, 0x3
-/* 80370D44 480BB339 */ bl func_8042c07c
-/* 80370D48 2C030000 */ cmpwi r3, 0x0
-/* 80370D4C 40820010 */ bne- lbl_80370d5c
-/* 80370D50 38600000 */ li r3, 0x0
-/* 80370D54 480BBB1D */ bl func_8042c870
-/* 80370D58 480000A0 */ b lbl_80370df8
-lbl_80370d5c:
-/* 80370D5C 3C602000 */ lis r3, 0x2000
-/* 80370D60 38030100 */ addi r0, r3, 0x100
-/* 80370D64 90010008 */ stw r0, 8(r1)
-/* 80370D68 38810008 */ addi r4, r1, 0x8
-/* 80370D6C 38600000 */ li r3, 0x0
-/* 80370D70 38A00004 */ li r5, 0x4
-/* 80370D74 38C00001 */ li r6, 0x1
-/* 80370D78 38E00000 */ li r7, 0x0
-/* 80370D7C 480BA7AD */ bl func_8042b528
-/* 80370D80 7C600034 */ cntlzw r0, r3
-/* 80370D84 541FD97E */ srwi r31, r0, 5
-/* 80370D88 38600000 */ li r3, 0x0
-/* 80370D8C 480BAB85 */ bl func_8042b910
-/* 80370D90 7C600034 */ cntlzw r0, r3
-/* 80370D94 5400D97E */ srwi r0, r0, 5
-/* 80370D98 389E0000 */ addi r4, r30, 0x0
-/* 80370D9C 7FFF0378 */ or r31, r31, r0
-/* 80370DA0 38600000 */ li r3, 0x0
-/* 80370DA4 38A00040 */ li r5, 0x40
-/* 80370DA8 38C00000 */ li r6, 0x0
-/* 80370DAC 38E00000 */ li r7, 0x0
-/* 80370DB0 480BAA75 */ bl func_8042b824
-/* 80370DB4 7C600034 */ cntlzw r0, r3
-/* 80370DB8 5400D97E */ srwi r0, r0, 5
-/* 80370DBC 7FFF0378 */ or r31, r31, r0
-/* 80370DC0 38600000 */ li r3, 0x0
-/* 80370DC4 480BAB4D */ bl func_8042b910
-/* 80370DC8 7C600034 */ cntlzw r0, r3
-/* 80370DCC 5400D97E */ srwi r0, r0, 5
-/* 80370DD0 7FFF0378 */ or r31, r31, r0
-/* 80370DD4 38600000 */ li r3, 0x0
-/* 80370DD8 480BB3D1 */ bl func_8042c1a8
-/* 80370DDC 7C600034 */ cntlzw r0, r3
-/* 80370DE0 5400D97E */ srwi r0, r0, 5
-/* 80370DE4 7FFF0378 */ or r31, r31, r0
-/* 80370DE8 38600000 */ li r3, 0x0
-/* 80370DEC 480BBA85 */ bl func_8042c870
-/* 80370DF0 7FE00034 */ cntlzw r0, r31
-/* 80370DF4 541FD97E */ srwi r31, r0, 5
-lbl_80370df8:
-/* 80370DF8 93FE004C */ stw r31, 0x4c(r30)
-/* 80370DFC 38000040 */ li r0, 0x40
-/* 80370E00 901E0040 */ stw r0, 0x40(r30)
-/* 80370E04 8001001C */ lwz r0, 0x1c(r1)
-/* 80370E08 83E10014 */ lwz r31, 0x14(r1)
-/* 80370E0C 83C10010 */ lwz r30, 0x10(r1)
-/* 80370E10 38210018 */ addi r1, r1, 0x18
-/* 80370E14 7C0803A6 */ mtlr r0
-/* 80370E18 4E800020 */ blr
-.size func_80370ce8, . - func_80370ce8
-
-
-.global func_80370e1c
-.type func_80370e1c, @function
-func_80370e1c:
-/* 80370E1C 7C0802A6 */ mflr r0
-/* 80370E20 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80370E24 90010004 */ stw r0, 4(r1)
-/* 80370E28 9421FFF0 */ stwu r1, -0x10(r1)
-/* 80370E2C 93E1000C */ stw r31, 0xc(r1)
-/* 80370E30 3BE3ECA0 */ addi r31, r3, lbl_8053eca0@l
-/* 80370E34 4BFFDCA1 */ bl func_8036ead4
-/* 80370E38 801F0048 */ lwz r0, 0x48(r31)
-/* 80370E3C 389F0048 */ addi r4, r31, 0x48
-/* 80370E40 2C000000 */ cmpwi r0, 0x0
-/* 80370E44 41820010 */ beq- lbl_80370e54
-/* 80370E48 4BFFDCB5 */ bl func_8036eafc
-/* 80370E4C 3BE00000 */ li r31, 0x0
-/* 80370E50 48000010 */ b lbl_80370e60
-lbl_80370e54:
-/* 80370E54 907F0044 */ stw r3, 0x44(r31)
-/* 80370E58 38000001 */ li r0, 0x1
-/* 80370E5C 90040000 */ stw r0, 0(r4)
-lbl_80370e60:
-/* 80370E60 7FE3FB78 */ mr r3, r31
-/* 80370E64 80010014 */ lwz r0, 0x14(r1)
-/* 80370E68 83E1000C */ lwz r31, 0xc(r1)
-/* 80370E6C 38210010 */ addi r1, r1, 0x10
-/* 80370E70 7C0803A6 */ mtlr r0
-/* 80370E74 4E800020 */ blr
-.size func_80370e1c, . - func_80370e1c
-
-
-.global func_80370e78
-.type func_80370e78, @function
-func_80370e78:
-/* 80370E78 7C0802A6 */ mflr r0
-/* 80370E7C 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80370E80 90010004 */ stw r0, 4(r1)
-/* 80370E84 9421FFF0 */ stwu r1, -0x10(r1)
-/* 80370E88 93E1000C */ stw r31, 0xc(r1)
-/* 80370E8C 3BE3ECA0 */ addi r31, r3, lbl_8053eca0@l
-/* 80370E90 4BFFDC45 */ bl func_8036ead4
-/* 80370E94 801F0048 */ lwz r0, 0x48(r31)
-/* 80370E98 389F0048 */ addi r4, r31, 0x48
-/* 80370E9C 2C000000 */ cmpwi r0, 0x0
-/* 80370EA0 41820010 */ beq- lbl_80370eb0
-/* 80370EA4 4BFFDC59 */ bl func_8036eafc
-/* 80370EA8 38600000 */ li r3, 0x0
-/* 80370EAC 48000014 */ b lbl_80370ec0
-lbl_80370eb0:
-/* 80370EB0 907F0044 */ stw r3, 0x44(r31)
-/* 80370EB4 38000001 */ li r0, 0x1
-/* 80370EB8 387F0014 */ addi r3, r31, 0x14
-/* 80370EBC 90040000 */ stw r0, 0(r4)
-lbl_80370ec0:
-/* 80370EC0 80010014 */ lwz r0, 0x14(r1)
-/* 80370EC4 83E1000C */ lwz r31, 0xc(r1)
-/* 80370EC8 38210010 */ addi r1, r1, 0x10
-/* 80370ECC 7C0803A6 */ mtlr r0
-/* 80370ED0 4E800020 */ blr
-.size func_80370e78, . - func_80370e78
-
-
-.global func_80370ed4
-.type func_80370ed4, @function
-func_80370ed4:
-/* 80370ED4 7C0802A6 */ mflr r0
-/* 80370ED8 2C030000 */ cmpwi r3, 0x0
-/* 80370EDC 90010004 */ stw r0, 4(r1)
-/* 80370EE0 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80370EE4 9421FFD0 */ stwu r1, -0x30(r1)
-/* 80370EE8 BF61001C */ stmw r27, 0x1c(r1)
-/* 80370EEC 3BE3ECA0 */ addi r31, r3, lbl_8053eca0@l
-/* 80370EF0 418202C4 */ beq- lbl_803711b4
-/* 80370EF4 28040000 */ cmplwi r4, 0
-/* 80370EF8 408201B0 */ bne- lbl_803710a8
-/* 80370EFC 887F0013 */ lbz r3, 0x13(r31)
-/* 80370F00 546007BE */ clrlwi r0, r3, 0x1e
-/* 80370F04 28000002 */ cmplwi r0, 2
-/* 80370F08 4081000C */ ble- lbl_80370f14
-/* 80370F0C 5460003A */ rlwinm r0, r3, 0, 0, 0x1d
-/* 80370F10 981F0013 */ stb r0, 0x13(r31)
-lbl_80370f14:
-/* 80370F14 38000000 */ li r0, 0x0
-/* 80370F18 B01F0002 */ sth r0, 2(r31)
-/* 80370F1C 38BF0014 */ addi r5, r31, 0x14
-/* 80370F20 38DF000C */ addi r6, r31, 0xc
-/* 80370F24 38650001 */ addi r3, r5, 0x1
-/* 80370F28 B01F0000 */ sth r0, 0(r31)
-/* 80370F2C 7C661850 */ subf r3, r6, r3
-/* 80370F30 7C062840 */ cmplw r6, r5
-/* 80370F34 5463F87E */ srwi r3, r3, 1
-/* 80370F38 40800170 */ bge- lbl_803710a8
-/* 80370F3C 5460E8FF */ rlwinm. r0, r3, 0x1d, 3, 0x1f
-/* 80370F40 7C0903A6 */ mtctr r0
-/* 80370F44 41820134 */ beq- lbl_80371078
-lbl_80370f48:
-/* 80370F48 A0BF0000 */ lhz r5, 0(r31)
-/* 80370F4C A0060000 */ lhz r0, 0(r6)
-/* 80370F50 7C050214 */ add r0, r5, r0
-/* 80370F54 B01F0000 */ sth r0, 0(r31)
-/* 80370F58 A0060000 */ lhz r0, 0(r6)
-/* 80370F5C A0BF0002 */ lhz r5, 2(r31)
-/* 80370F60 7C0000F8 */ nor r0, r0, r0
-/* 80370F64 7C050214 */ add r0, r5, r0
-/* 80370F68 B01F0002 */ sth r0, 2(r31)
-/* 80370F6C A0BF0000 */ lhz r5, 0(r31)
-/* 80370F70 A0060002 */ lhz r0, 2(r6)
-/* 80370F74 7C050214 */ add r0, r5, r0
-/* 80370F78 B01F0000 */ sth r0, 0(r31)
-/* 80370F7C A0060002 */ lhz r0, 2(r6)
-/* 80370F80 A0BF0002 */ lhz r5, 2(r31)
-/* 80370F84 7C0000F8 */ nor r0, r0, r0
-/* 80370F88 7C050214 */ add r0, r5, r0
-/* 80370F8C B01F0002 */ sth r0, 2(r31)
-/* 80370F90 A0BF0000 */ lhz r5, 0(r31)
-/* 80370F94 A0060004 */ lhz r0, 4(r6)
-/* 80370F98 7C050214 */ add r0, r5, r0
-/* 80370F9C B01F0000 */ sth r0, 0(r31)
-/* 80370FA0 A0060004 */ lhz r0, 4(r6)
-/* 80370FA4 A0BF0002 */ lhz r5, 2(r31)
-/* 80370FA8 7C0000F8 */ nor r0, r0, r0
-/* 80370FAC 7C050214 */ add r0, r5, r0
-/* 80370FB0 B01F0002 */ sth r0, 2(r31)
-/* 80370FB4 A0BF0000 */ lhz r5, 0(r31)
-/* 80370FB8 A0060006 */ lhz r0, 6(r6)
-/* 80370FBC 7C050214 */ add r0, r5, r0
-/* 80370FC0 B01F0000 */ sth r0, 0(r31)
-/* 80370FC4 A0060006 */ lhz r0, 6(r6)
-/* 80370FC8 A0BF0002 */ lhz r5, 2(r31)
-/* 80370FCC 7C0000F8 */ nor r0, r0, r0
-/* 80370FD0 7C050214 */ add r0, r5, r0
-/* 80370FD4 B01F0002 */ sth r0, 2(r31)
-/* 80370FD8 A0BF0000 */ lhz r5, 0(r31)
-/* 80370FDC A0060008 */ lhz r0, 8(r6)
-/* 80370FE0 7C050214 */ add r0, r5, r0
-/* 80370FE4 B01F0000 */ sth r0, 0(r31)
-/* 80370FE8 A0060008 */ lhz r0, 8(r6)
-/* 80370FEC A0BF0002 */ lhz r5, 2(r31)
-/* 80370FF0 7C0000F8 */ nor r0, r0, r0
-/* 80370FF4 7C050214 */ add r0, r5, r0
-/* 80370FF8 B01F0002 */ sth r0, 2(r31)
-/* 80370FFC A0BF0000 */ lhz r5, 0(r31)
-/* 80371000 A006000A */ lhz r0, 0xa(r6)
-/* 80371004 7C050214 */ add r0, r5, r0
-/* 80371008 B01F0000 */ sth r0, 0(r31)
-/* 8037100C A006000A */ lhz r0, 0xa(r6)
-/* 80371010 A0BF0002 */ lhz r5, 2(r31)
-/* 80371014 7C0000F8 */ nor r0, r0, r0
-/* 80371018 7C050214 */ add r0, r5, r0
-/* 8037101C B01F0002 */ sth r0, 2(r31)
-/* 80371020 A0BF0000 */ lhz r5, 0(r31)
-/* 80371024 A006000C */ lhz r0, 0xc(r6)
-/* 80371028 7C050214 */ add r0, r5, r0
-/* 8037102C B01F0000 */ sth r0, 0(r31)
-/* 80371030 A006000C */ lhz r0, 0xc(r6)
-/* 80371034 A0BF0002 */ lhz r5, 2(r31)
-/* 80371038 7C0000F8 */ nor r0, r0, r0
-/* 8037103C 7C050214 */ add r0, r5, r0
-/* 80371040 B01F0002 */ sth r0, 2(r31)
-/* 80371044 A0BF0000 */ lhz r5, 0(r31)
-/* 80371048 A006000E */ lhz r0, 0xe(r6)
-/* 8037104C 7C050214 */ add r0, r5, r0
-/* 80371050 B01F0000 */ sth r0, 0(r31)
-/* 80371054 A006000E */ lhz r0, 0xe(r6)
-/* 80371058 38C60010 */ addi r6, r6, 0x10
-/* 8037105C A0BF0002 */ lhz r5, 2(r31)
-/* 80371060 7C0000F8 */ nor r0, r0, r0
-/* 80371064 7C050214 */ add r0, r5, r0
-/* 80371068 B01F0002 */ sth r0, 2(r31)
-/* 8037106C 4200FEDC */ bdnz lbl_80370f48
-/* 80371070 70630007 */ andi. r3, r3, 7
-/* 80371074 41820034 */ beq- lbl_803710a8
-lbl_80371078:
-/* 80371078 7C6903A6 */ mtctr r3
-lbl_8037107c:
-/* 8037107C A0BF0000 */ lhz r5, 0(r31)
-/* 80371080 A0060000 */ lhz r0, 0(r6)
-/* 80371084 7C050214 */ add r0, r5, r0
-/* 80371088 B01F0000 */ sth r0, 0(r31)
-/* 8037108C A0060000 */ lhz r0, 0(r6)
-/* 80371090 38C60002 */ addi r6, r6, 0x2
-/* 80371094 A0BF0002 */ lhz r5, 2(r31)
-/* 80371098 7C0000F8 */ nor r0, r0, r0
-/* 8037109C 7C050214 */ add r0, r5, r0
-/* 803710A0 B01F0002 */ sth r0, 2(r31)
-/* 803710A4 4200FFD8 */ bdnz lbl_8037107c
-lbl_803710a8:
-/* 803710A8 3BDF0040 */ addi r30, r31, 0x40
-/* 803710AC 801F0040 */ lwz r0, 0x40(r31)
-/* 803710B0 7C040040 */ cmplw r4, r0
-/* 803710B4 40800008 */ bge- lbl_803710bc
-/* 803710B8 909E0000 */ stw r4, 0(r30)
-lbl_803710bc:
-/* 803710BC 83BE0000 */ lwz r29, 0(r30)
-/* 803710C0 3C608037 */ lis r3, func_80370b70@ha
-/* 803710C4 38A30B70 */ addi r5, r3, func_80370b70@l
-/* 803710C8 237D0040 */ subfic r27, r29, 0x40
-/* 803710CC 7F9FEA14 */ add r28, r31, r29
-/* 803710D0 38600000 */ li r3, 0x0
-/* 803710D4 38800001 */ li r4, 0x1
-/* 803710D8 480BB6A5 */ bl func_8042c77c
-/* 803710DC 2C030000 */ cmpwi r3, 0x0
-/* 803710E0 4082000C */ bne- lbl_803710ec
-/* 803710E4 38000000 */ li r0, 0x0
-/* 803710E8 480000B4 */ b lbl_8037119c
-lbl_803710ec:
-/* 803710EC 38600000 */ li r3, 0x0
-/* 803710F0 38800001 */ li r4, 0x1
-/* 803710F4 38A00003 */ li r5, 0x3
-/* 803710F8 480BAF85 */ bl func_8042c07c
-/* 803710FC 2C030000 */ cmpwi r3, 0x0
-/* 80371100 40820014 */ bne- lbl_80371114
-/* 80371104 38600000 */ li r3, 0x0
-/* 80371108 480BB769 */ bl func_8042c870
-/* 8037110C 38000000 */ li r0, 0x0
-/* 80371110 4800008C */ b lbl_8037119c
-lbl_80371114:
-/* 80371114 57A33032 */ slwi r3, r29, 6
-/* 80371118 38030100 */ addi r0, r3, 0x100
-/* 8037111C 6400A000 */ oris r0, r0, 0xa000
-/* 80371120 90010010 */ stw r0, 0x10(r1)
-/* 80371124 38810010 */ addi r4, r1, 0x10
-/* 80371128 38600000 */ li r3, 0x0
-/* 8037112C 38A00004 */ li r5, 0x4
-/* 80371130 38C00001 */ li r6, 0x1
-/* 80371134 38E00000 */ li r7, 0x0
-/* 80371138 480BA3F1 */ bl func_8042b528
-/* 8037113C 7C600034 */ cntlzw r0, r3
-/* 80371140 541DD97E */ srwi r29, r0, 5
-/* 80371144 38600000 */ li r3, 0x0
-/* 80371148 480BA7C9 */ bl func_8042b910
-/* 8037114C 7C600034 */ cntlzw r0, r3
-/* 80371150 5400D97E */ srwi r0, r0, 5
-/* 80371154 389C0000 */ addi r4, r28, 0x0
-/* 80371158 38BB0000 */ addi r5, r27, 0x0
-/* 8037115C 7FBD0378 */ or r29, r29, r0
-/* 80371160 38600000 */ li r3, 0x0
-/* 80371164 38C00001 */ li r6, 0x1
-/* 80371168 480BA61D */ bl func_8042b784
-/* 8037116C 7C600034 */ cntlzw r0, r3
-/* 80371170 5400D97E */ srwi r0, r0, 5
-/* 80371174 7FBD0378 */ or r29, r29, r0
-/* 80371178 38600000 */ li r3, 0x0
-/* 8037117C 480BB02D */ bl func_8042c1a8
-/* 80371180 7C600034 */ cntlzw r0, r3
-/* 80371184 5400D97E */ srwi r0, r0, 5
-/* 80371188 7FBD0378 */ or r29, r29, r0
-/* 8037118C 38600000 */ li r3, 0x0
-/* 80371190 480BB6E1 */ bl func_8042c870
-/* 80371194 7FA00034 */ cntlzw r0, r29
-/* 80371198 5400D97E */ srwi r0, r0, 5
-lbl_8037119c:
-/* 8037119C 901F004C */ stw r0, 0x4c(r31)
-/* 803711A0 801F004C */ lwz r0, 0x4c(r31)
-/* 803711A4 2C000000 */ cmpwi r0, 0x0
-/* 803711A8 4182000C */ beq- lbl_803711b4
-/* 803711AC 38000040 */ li r0, 0x40
-/* 803711B0 901E0000 */ stw r0, 0(r30)
-lbl_803711b4:
-/* 803711B4 38000000 */ li r0, 0x0
-/* 803711B8 901F0048 */ stw r0, 0x48(r31)
-/* 803711BC 807F0044 */ lwz r3, 0x44(r31)
-/* 803711C0 4BFFD93D */ bl func_8036eafc
-/* 803711C4 807F004C */ lwz r3, 0x4c(r31)
-/* 803711C8 BB61001C */ lmw r27, 0x1c(r1)
-/* 803711CC 80010034 */ lwz r0, 0x34(r1)
-/* 803711D0 38210030 */ addi r1, r1, 0x30
-/* 803711D4 7C0803A6 */ mtlr r0
-/* 803711D8 4E800020 */ blr
-.size func_80370ed4, . - func_80370ed4
-
-
-.global func_803711dc
-.type func_803711dc, @function
-func_803711dc:
-/* 803711DC 7C0802A6 */ mflr r0
-/* 803711E0 38800000 */ li r4, 0x0
-/* 803711E4 90010004 */ stw r0, 4(r1)
-/* 803711E8 9421FFF8 */ stwu r1, -8(r1)
-/* 803711EC 4BFFFCE9 */ bl func_80370ed4
-/* 803711F0 8001000C */ lwz r0, 0xc(r1)
-/* 803711F4 38210008 */ addi r1, r1, 0x8
-/* 803711F8 7C0803A6 */ mtlr r0
-/* 803711FC 4E800020 */ blr
-.size func_803711dc, . - func_803711dc
-
-
-.global func_80371200
-.type func_80371200, @function
-func_80371200:
-/* 80371200 7C0802A6 */ mflr r0
-/* 80371204 38800014 */ li r4, 0x14
-/* 80371208 90010004 */ stw r0, 4(r1)
-/* 8037120C 9421FFF8 */ stwu r1, -8(r1)
-/* 80371210 4BFFFCC5 */ bl func_80370ed4
-/* 80371214 8001000C */ lwz r0, 0xc(r1)
-/* 80371218 38210008 */ addi r1, r1, 0x8
-/* 8037121C 7C0803A6 */ mtlr r0
-/* 80371220 4E800020 */ blr
-.size func_80371200, . - func_80371200
-
-
-.global func_80371224
-.type func_80371224, @function
-func_80371224:
-/* 80371224 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80371228 3863ECA0 */ addi r3, r3, lbl_8053eca0@l
-/* 8037122C 8063004C */ lwz r3, 0x4c(r3)
-/* 80371230 4E800020 */ blr
-.size func_80371224, . - func_80371224
-
-
-.global func_80371234
-.type func_80371234, @function
-func_80371234:
-/* 80371234 7C0802A6 */ mflr r0
-/* 80371238 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 8037123C 90010004 */ stw r0, 4(r1)
-/* 80371240 9421FFE0 */ stwu r1, -0x20(r1)
-/* 80371244 93E1001C */ stw r31, 0x1c(r1)
-/* 80371248 3BE3ECA0 */ addi r31, r3, lbl_8053eca0@l
-/* 8037124C 4BFFD889 */ bl func_8036ead4
-/* 80371250 801F0048 */ lwz r0, 0x48(r31)
-/* 80371254 389F0048 */ addi r4, r31, 0x48
-/* 80371258 2C000000 */ cmpwi r0, 0x0
-/* 8037125C 41820010 */ beq- lbl_8037126c
-/* 80371260 4BFFD89D */ bl func_8036eafc
-/* 80371264 3BE00000 */ li r31, 0x0
-/* 80371268 48000010 */ b lbl_80371278
-lbl_8037126c:
-/* 8037126C 907F0044 */ stw r3, 0x44(r31)
-/* 80371270 38000001 */ li r0, 0x1
-/* 80371274 90040000 */ stw r0, 0(r4)
-lbl_80371278:
-/* 80371278 881F0013 */ lbz r0, 0x13(r31)
-/* 8037127C 5400077B */ rlwinm. r0, r0, 0, 0x1d, 0x1d
-/* 80371280 4182000C */ beq- lbl_8037128c
-/* 80371284 3BE00001 */ li r31, 0x1
-/* 80371288 48000008 */ b lbl_80371290
-lbl_8037128c:
-/* 8037128C 3BE00000 */ li r31, 0x0
-lbl_80371290:
-/* 80371290 38600000 */ li r3, 0x0
-/* 80371294 38800000 */ li r4, 0x0
-/* 80371298 4BFFFC3D */ bl func_80370ed4
-/* 8037129C 7FE3FB78 */ mr r3, r31
-/* 803712A0 80010024 */ lwz r0, 0x24(r1)
-/* 803712A4 83E1001C */ lwz r31, 0x1c(r1)
-/* 803712A8 38210020 */ addi r1, r1, 0x20
-/* 803712AC 7C0803A6 */ mtlr r0
-/* 803712B0 4E800020 */ blr
-.size func_80371234, . - func_80371234
-
-
-.global func_803712b4
-.type func_803712b4, @function
-func_803712b4:
-/* 803712B4 7C0802A6 */ mflr r0
-/* 803712B8 3C808054 */ lis r4, lbl_8053eca0@ha
-/* 803712BC 90010004 */ stw r0, 4(r1)
-/* 803712C0 9421FFE0 */ stwu r1, -0x20(r1)
-/* 803712C4 93E1001C */ stw r31, 0x1c(r1)
-/* 803712C8 3BE4ECA0 */ addi r31, r4, lbl_8053eca0@l
-/* 803712CC 93C10018 */ stw r30, 0x18(r1)
-/* 803712D0 547E177A */ rlwinm r30, r3, 2, 0x1d, 0x1d
-/* 803712D4 4BFFD801 */ bl func_8036ead4
-/* 803712D8 801F0048 */ lwz r0, 0x48(r31)
-/* 803712DC 389F0048 */ addi r4, r31, 0x48
-/* 803712E0 2C000000 */ cmpwi r0, 0x0
-/* 803712E4 41820010 */ beq- lbl_803712f4
-/* 803712E8 4BFFD815 */ bl func_8036eafc
-/* 803712EC 3BE00000 */ li r31, 0x0
-/* 803712F0 48000010 */ b lbl_80371300
-lbl_803712f4:
-/* 803712F4 907F0044 */ stw r3, 0x44(r31)
-/* 803712F8 38000001 */ li r0, 0x1
-/* 803712FC 90040000 */ stw r0, 0(r4)
-lbl_80371300:
-/* 80371300 887F0013 */ lbz r3, 0x13(r31)
-/* 80371304 5460077A */ rlwinm r0, r3, 0, 0x1d, 0x1d
-/* 80371308 7C1E0040 */ cmplw r30, r0
-/* 8037130C 40820014 */ bne- lbl_80371320
-/* 80371310 38600000 */ li r3, 0x0
-/* 80371314 38800000 */ li r4, 0x0
-/* 80371318 4BFFFBBD */ bl func_80370ed4
-/* 8037131C 48000024 */ b lbl_80371340
-lbl_80371320:
-/* 80371320 546007B8 */ rlwinm r0, r3, 0, 0x1e, 0x1c
-/* 80371324 981F0013 */ stb r0, 0x13(r31)
-/* 80371328 38600001 */ li r3, 0x1
-/* 8037132C 38800000 */ li r4, 0x0
-/* 80371330 881F0013 */ lbz r0, 0x13(r31)
-/* 80371334 7C00F378 */ or r0, r0, r30
-/* 80371338 981F0013 */ stb r0, 0x13(r31)
-/* 8037133C 4BFFFB99 */ bl func_80370ed4
-lbl_80371340:
-/* 80371340 80010024 */ lwz r0, 0x24(r1)
-/* 80371344 83E1001C */ lwz r31, 0x1c(r1)
-/* 80371348 83C10018 */ lwz r30, 0x18(r1)
-/* 8037134C 38210020 */ addi r1, r1, 0x20
-/* 80371350 7C0803A6 */ mtlr r0
-/* 80371354 4E800020 */ blr
-.size func_803712b4, . - func_803712b4
-
-
-.global func_80371358
-.type func_80371358, @function
-func_80371358:
-/* 80371358 7C0802A6 */ mflr r0
-/* 8037135C 3C608054 */ lis r3, lbl_8053eca0@ha
-/* 80371360 90010004 */ stw r0, 4(r1)
-/* 80371364 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80371368 93E10014 */ stw r31, 0x14(r1)
-/* 8037136C 3BE3ECA0 */ addi r31, r3, lbl_8053eca0@l
-/* 80371370 4BFFD765 */ bl func_8036ead4
-/* 80371374 801F0048 */ lwz r0, 0x48(r31)
-/* 80371378 389F0048 */ addi r4, r31, 0x48
-/* 8037137C 2C000000 */ cmpwi r0, 0x0
-/* 80371380 41820010 */ beq- lbl_80371390
-/* 80371384 4BFFD779 */ bl func_8036eafc
-/* 80371388 3BE00000 */ li r31, 0x0
-/* 8037138C 48000010 */ b lbl_8037139c
-lbl_80371390:
-/* 80371390 907F0044 */ stw r3, 0x44(r31)
-/* 80371394 38000001 */ li r0, 0x1
-/* 80371398 90040000 */ stw r0, 0(r4)
-lbl_8037139c:
-/* 8037139C 881F0013 */ lbz r0, 0x13(r31)
-/* 803713A0 38600000 */ li r3, 0x0
-/* 803713A4 38800000 */ li r4, 0x0
-/* 803713A8 541FCFFE */ rlwinm r31, r0, 0x19, 0x1f, 0x1f
-/* 803713AC 4BFFFB29 */ bl func_80370ed4
-/* 803713B0 7FE3FB78 */ mr r3, r31
-/* 803713B4 8001001C */ lwz r0, 0x1c(r1)
-/* 803713B8 83E10014 */ lwz r31, 0x14(r1)
-/* 803713BC 38210018 */ addi r1, r1, 0x18
-/* 803713C0 7C0803A6 */ mtlr r0
-/* 803713C4 4E800020 */ blr
-.size func_80371358, . - func_80371358
-
-
-.global func_803713c8
-.type func_803713c8, @function
-func_803713c8:
-/* 803713C8 7C0802A6 */ mflr r0
-/* 803713CC 3C808054 */ lis r4, lbl_8053eca0@ha
-/* 803713D0 90010004 */ stw r0, 4(r1)
-/* 803713D4 9421FFE0 */ stwu r1, -0x20(r1)
-/* 803713D8 93E1001C */ stw r31, 0x1c(r1)
-/* 803713DC 3BE4ECA0 */ addi r31, r4, lbl_8053eca0@l
-/* 803713E0 93C10018 */ stw r30, 0x18(r1)
-/* 803713E4 547E3E30 */ rlwinm r30, r3, 7, 0x18, 0x18
-/* 803713E8 4BFFD6ED */ bl func_8036ead4
-/* 803713EC 801F0048 */ lwz r0, 0x48(r31)
-/* 803713F0 389F0048 */ addi r4, r31, 0x48
-/* 803713F4 2C000000 */ cmpwi r0, 0x0
-/* 803713F8 41820010 */ beq- lbl_80371408
-/* 803713FC 4BFFD701 */ bl func_8036eafc
-/* 80371400 3BE00000 */ li r31, 0x0
-/* 80371404 48000010 */ b lbl_80371414
-lbl_80371408:
-/* 80371408 907F0044 */ stw r3, 0x44(r31)
-/* 8037140C 38000001 */ li r0, 0x1
-/* 80371410 90040000 */ stw r0, 0(r4)
-lbl_80371414:
-/* 80371414 887F0013 */ lbz r3, 0x13(r31)
-/* 80371418 54600630 */ rlwinm r0, r3, 0, 0x18, 0x18
-/* 8037141C 7C1E0040 */ cmplw r30, r0
-/* 80371420 40820014 */ bne- lbl_80371434
-/* 80371424 38600000 */ li r3, 0x0
-/* 80371428 38800000 */ li r4, 0x0
-/* 8037142C 4BFFFAA9 */ bl func_80370ed4
-/* 80371430 48000024 */ b lbl_80371454
-lbl_80371434:
-/* 80371434 5460066E */ rlwinm r0, r3, 0, 0x19, 0x17
-/* 80371438 981F0013 */ stb r0, 0x13(r31)
-/* 8037143C 38600001 */ li r3, 0x1
-/* 80371440 38800000 */ li r4, 0x0
-/* 80371444 881F0013 */ lbz r0, 0x13(r31)
-/* 80371448 7C00F378 */ or r0, r0, r30
-/* 8037144C 981F0013 */ stb r0, 0x13(r31)
-/* 80371450 4BFFFA85 */ bl func_80370ed4
-lbl_80371454:
-/* 80371454 80010024 */ lwz r0, 0x24(r1)
-/* 80371458 83E1001C */ lwz r31, 0x1c(r1)
-/* 8037145C 83C10018 */ lwz r30, 0x18(r1)
-/* 80371460 38210020 */ addi r1, r1, 0x20
-/* 80371464 7C0803A6 */ mtlr r0
-/* 80371468 4E800020 */ blr
-.size func_803713c8, . - func_803713c8
-
-
-.global func_8037146c
-.type func_8037146c, @function
-func_8037146c:
-/* 8037146C 7C0802A6 */ mflr r0
-/* 80371470 3C808054 */ lis r4, lbl_8053eca0@ha
-/* 80371474 90010004 */ stw r0, 4(r1)
-/* 80371478 9421FFE0 */ stwu r1, -0x20(r1)
-/* 8037147C 93E1001C */ stw r31, 0x1c(r1)
-/* 80371480 3BE4ECA0 */ addi r31, r4, lbl_8053eca0@l
-/* 80371484 93C10018 */ stw r30, 0x18(r1)
-/* 80371488 3BC30000 */ addi r30, r3, 0x0
-/* 8037148C 4BFFD649 */ bl func_8036ead4
-/* 80371490 801F0048 */ lwz r0, 0x48(r31)
-/* 80371494 389F0048 */ addi r4, r31, 0x48
-/* 80371498 2C000000 */ cmpwi r0, 0x0
-/* 8037149C 41820010 */ beq- lbl_803714ac
-/* 803714A0 4BFFD65D */ bl func_8036eafc
-/* 803714A4 38600000 */ li r3, 0x0
-/* 803714A8 48000014 */ b lbl_803714bc
-lbl_803714ac:
-/* 803714AC 907F0044 */ stw r3, 0x44(r31)
-/* 803714B0 38000001 */ li r0, 0x1
-/* 803714B4 387F0014 */ addi r3, r31, 0x14
-/* 803714B8 90040000 */ stw r0, 0(r4)
-lbl_803714bc:
-/* 803714BC 57C0083C */ slwi r0, r30, 1
-/* 803714C0 7C630214 */ add r3, r3, r0
-/* 803714C4 A3E3001C */ lhz r31, 0x1c(r3)
-/* 803714C8 38600000 */ li r3, 0x0
-/* 803714CC 38800014 */ li r4, 0x14
-/* 803714D0 4BFFFA05 */ bl func_80370ed4
-/* 803714D4 7FE3FB78 */ mr r3, r31
-/* 803714D8 80010024 */ lwz r0, 0x24(r1)
-/* 803714DC 83E1001C */ lwz r31, 0x1c(r1)
-/* 803714E0 83C10018 */ lwz r30, 0x18(r1)
-/* 803714E4 38210020 */ addi r1, r1, 0x20
-/* 803714E8 7C0803A6 */ mtlr r0
-/* 803714EC 4E800020 */ blr
-.size func_8037146c, . - func_8037146c
-
-
-.global func_803714f0
-.type func_803714f0, @function
-func_803714f0:
-/* 803714F0 7C0802A6 */ mflr r0
-/* 803714F4 3CA08054 */ lis r5, lbl_8053eca0@ha
-/* 803714F8 90010004 */ stw r0, 4(r1)
-/* 803714FC 9421FFD8 */ stwu r1, -0x28(r1)
-/* 80371500 93E10024 */ stw r31, 0x24(r1)
-/* 80371504 3BE5ECA0 */ addi r31, r5, lbl_8053eca0@l
-/* 80371508 93C10020 */ stw r30, 0x20(r1)
-/* 8037150C 3BC40000 */ addi r30, r4, 0x0
-/* 80371510 93A1001C */ stw r29, 0x1c(r1)
-/* 80371514 3BA30000 */ addi r29, r3, 0x0
-/* 80371518 4BFFD5BD */ bl func_8036ead4
-/* 8037151C 801F0048 */ lwz r0, 0x48(r31)
-/* 80371520 389F0048 */ addi r4, r31, 0x48
-/* 80371524 2C000000 */ cmpwi r0, 0x0
-/* 80371528 41820010 */ beq- lbl_80371538
-/* 8037152C 4BFFD5D1 */ bl func_8036eafc
-/* 80371530 38600000 */ li r3, 0x0
-/* 80371534 48000014 */ b lbl_80371548
-lbl_80371538:
-/* 80371538 907F0044 */ stw r3, 0x44(r31)
-/* 8037153C 38000001 */ li r0, 0x1
-/* 80371540 387F0014 */ addi r3, r31, 0x14
-/* 80371544 90040000 */ stw r0, 0(r4)
-lbl_80371548:
-/* 80371548 57A0083C */ slwi r0, r29, 1
-/* 8037154C 7C830214 */ add r4, r3, r0
-/* 80371550 A464001C */ lhzu r3, 0x1c(r4)
-/* 80371554 57C0043E */ clrlwi r0, r30, 0x10
-/* 80371558 7C030040 */ cmplw r3, r0
-/* 8037155C 41820018 */ beq- lbl_80371574
-/* 80371560 B3C40000 */ sth r30, 0(r4)
-/* 80371564 38600001 */ li r3, 0x1
-/* 80371568 38800014 */ li r4, 0x14
-/* 8037156C 4BFFF969 */ bl func_80370ed4
-/* 80371570 48000010 */ b lbl_80371580
-lbl_80371574:
-/* 80371574 38600000 */ li r3, 0x0
-/* 80371578 38800014 */ li r4, 0x14
-/* 8037157C 4BFFF959 */ bl func_80370ed4
-lbl_80371580:
-/* 80371580 8001002C */ lwz r0, 0x2c(r1)
-/* 80371584 83E10024 */ lwz r31, 0x24(r1)
-/* 80371588 83C10020 */ lwz r30, 0x20(r1)
-/* 8037158C 83A1001C */ lwz r29, 0x1c(r1)
-/* 80371590 38210028 */ addi r1, r1, 0x28
-/* 80371594 7C0803A6 */ mtlr r0
-/* 80371598 4E800020 */ blr
-.size func_803714f0, . - func_803714f0
-
diff --git a/asm/Dolphin/os/OSSync.s b/asm/Dolphin/os/OSSync.s
deleted file mode 100644
index f284b42..0000000
--- a/asm/Dolphin/os/OSSync.s
+++ /dev/null
@@ -1,54 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_8037159c
-.type func_8037159c, @function
-func_8037159c:
-/* 8037159C 7D30FAA6 */ mfspr r9, 0x3f0
-/* 803715A0 612A0008 */ ori r10, r9, 8
-/* 803715A4 7D50FBA6 */ mtspr 0x3f0, r10
-/* 803715A8 4C00012C */ isync
-/* 803715AC 7C0004AC */ sync 0
-/* 803715B0 7D30FBA6 */ mtspr 0x3f0, r9
-/* 803715B4 4C000064 */ rfi
-.size func_8037159c, . - func_8037159c
-
-
-.global func_803715b8
-.type func_803715b8, @function
-func_803715b8:
-/* 803715B8 60000000 */ nop
-.size func_803715b8, . - func_803715b8
-
-
-.global func_803715bc
-.type func_803715bc, @function
-func_803715bc:
-/* 803715BC 7C0802A6 */ mflr r0
-/* 803715C0 90010004 */ stw r0, 4(r1)
-/* 803715C4 9421FFF0 */ stwu r1, -0x10(r1)
-/* 803715C8 93E1000C */ stw r31, 0xc(r1)
-/* 803715CC 3CA08000 */ lis r5, 0x8000
-/* 803715D0 3C808037 */ lis r4, func_8037159c@ha
-/* 803715D4 3C608037 */ lis r3, func_803715b8@ha
-/* 803715D8 3BE50C00 */ addi r31, r5, 0xc00
-/* 803715DC 380315B8 */ addi r0, r3, func_803715b8@l
-/* 803715E0 3884159C */ addi r4, r4, func_8037159c@l
-/* 803715E4 7FE3FB78 */ mr r3, r31
-/* 803715E8 7CA40050 */ subf r5, r4, r0
-/* 803715EC 4BC9CE31 */ bl func_8000e41c
-/* 803715F0 7FE3FB78 */ mr r3, r31
-/* 803715F4 38800100 */ li r4, 0x100
-/* 803715F8 4BFFC381 */ bl func_8036d978
-/* 803715FC 7C0004AC */ sync 0
-/* 80371600 7FE3FB78 */ mr r3, r31
-/* 80371604 38800100 */ li r4, 0x100
-/* 80371608 4BFFC3D1 */ bl func_8036d9d8
-/* 8037160C 80010014 */ lwz r0, 0x14(r1)
-/* 80371610 83E1000C */ lwz r31, 0xc(r1)
-/* 80371614 38210010 */ addi r1, r1, 0x10
-/* 80371618 7C0803A6 */ mtlr r0
-/* 8037161C 4E800020 */ blr
-.size func_803715bc, . - func_803715bc
-
diff --git a/asm/Dolphin/os/OSThread.s b/asm/Dolphin/os/OSThread.s
deleted file mode 100644
index 2880583..0000000
--- a/asm/Dolphin/os/OSThread.s
+++ /dev/null
@@ -1,1413 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_80371620
-.type func_80371620, @function
-func_80371620:
-/* 80371620 7C0802A6 */ mflr r0
-/* 80371624 3C608054 */ lis r3, lbl_8053ecf8@ha
-/* 80371628 90010004 */ stw r0, 4(r1)
-/* 8037162C 38000002 */ li r0, 0x2
-/* 80371630 38800010 */ li r4, 0x10
-/* 80371634 9421FFE0 */ stwu r1, -0x20(r1)
-/* 80371638 BF410008 */ stmw r26, 8(r1)
-/* 8037163C 3B83ECF8 */ addi r28, r3, lbl_8053ecf8@l
-/* 80371640 3BFC0410 */ addi r31, r28, 0x410
-/* 80371644 3BA00000 */ li r29, 0x0
-/* 80371648 387F02E8 */ addi r3, r31, 0x2e8
-/* 8037164C B01C06D8 */ sth r0, 0x6d8(r28)
-/* 80371650 38000001 */ li r0, 0x1
-/* 80371654 B01C06DA */ sth r0, 0x6da(r28)
-/* 80371658 3800FFFF */ li r0, -0x1
-/* 8037165C 909C06E4 */ stw r4, 0x6e4(r28)
-/* 80371660 909C06E0 */ stw r4, 0x6e0(r28)
-/* 80371664 93BC06DC */ stw r29, 0x6dc(r28)
-/* 80371668 901C06E8 */ stw r0, 0x6e8(r28)
-/* 8037166C 93BC0700 */ stw r29, 0x700(r28)
-/* 80371670 480000D9 */ bl func_80371748
-/* 80371674 93BC0708 */ stw r29, 0x708(r28)
-/* 80371678 3FC08000 */ lis r30, 0x8000
-/* 8037167C 387F0000 */ addi r3, r31, 0x0
-/* 80371680 93BC0704 */ stw r29, 0x704(r28)
-/* 80371684 93FE00D8 */ stw r31, 0xd8(r30)
-/* 80371688 4BFFCBD9 */ bl func_8036e260
-/* 8037168C 7FE3FB78 */ mr r3, r31
-/* 80371690 4BFFCA09 */ bl func_8036e098
-/* 80371694 3C60805E */ lis r3, 0x805e
-/* 80371698 380309C8 */ addi r0, r3, 0x9c8
-/* 8037169C 3C60805D */ lis r3, 0x805d
-/* 803716A0 901C0714 */ stw r0, 0x714(r28)
-/* 803716A4 380309C4 */ addi r0, r3, 0x9c4
-/* 803716A8 387C0718 */ addi r3, r28, 0x718
-/* 803716AC 901C0718 */ stw r0, 0x718(r28)
-/* 803716B0 3C80DEAE */ lis r4, 0xdeae
-/* 803716B4 3B400000 */ li r26, 0x0
-/* 803716B8 80630000 */ lwz r3, 0(r3)
-/* 803716BC 3884BABE */ addi r4, r4, -0x4542
-/* 803716C0 57401838 */ slwi r0, r26, 3
-/* 803716C4 90830000 */ stw r4, 0(r3)
-/* 803716C8 7F7C0214 */ add r27, r28, r0
-/* 803716CC 93ADCA98 */ stw r29, lbl_805c68b8@sda21(0)
-/* 803716D0 93FE00E4 */ stw r31, 0xe4(r30)
-/* 803716D4 93ADCA9C */ stw r29, lbl_805c68bc@sda21(0)
-lbl_803716d8:
-/* 803716D8 7F63DB78 */ mr r3, r27
-/* 803716DC 4800006D */ bl func_80371748
-/* 803716E0 3B5A0001 */ addi r26, r26, 0x1
-/* 803716E4 2C1A001F */ cmpwi r26, 0x1f
-/* 803716E8 3B7B0008 */ addi r27, r27, 0x8
-/* 803716EC 4081FFEC */ ble+ lbl_803716d8
-/* 803716F0 3FC08000 */ lis r30, 0x8000
-/* 803716F4 387E00DC */ addi r3, r30, 0xdc
-/* 803716F8 48000051 */ bl func_80371748
-/* 803716FC 389E00DC */ addi r4, r30, 0xdc
-/* 80371700 84640004 */ lwzu r3, 4(r4)
-/* 80371704 28030000 */ cmplwi r3, 0
-/* 80371708 4082000C */ bne- lbl_80371714
-/* 8037170C 93FE00DC */ stw r31, 0xdc(r30)
-/* 80371710 48000008 */ b lbl_80371718
-lbl_80371714:
-/* 80371714 93E302FC */ stw r31, 0x2fc(r3)
-lbl_80371718:
-/* 80371718 907F0300 */ stw r3, 0x300(r31)
-/* 8037171C 3BC00000 */ li r30, 0x0
-/* 80371720 387C0720 */ addi r3, r28, 0x720
-/* 80371724 93DF02FC */ stw r30, 0x2fc(r31)
-/* 80371728 93E40000 */ stw r31, 0(r4)
-/* 8037172C 4BFFCB35 */ bl func_8036e260
-/* 80371730 93CDCAA0 */ stw r30, lbl_805c68c0@sda21(0)
-/* 80371734 BB410008 */ lmw r26, 8(r1)
-/* 80371738 80010024 */ lwz r0, 0x24(r1)
-/* 8037173C 38210020 */ addi r1, r1, 0x20
-/* 80371740 7C0803A6 */ mtlr r0
-/* 80371744 4E800020 */ blr
-.size func_80371620, . - func_80371620
-
-
-.global func_80371748
-.type func_80371748, @function
-func_80371748:
-/* 80371748 38000000 */ li r0, 0x0
-/* 8037174C 90030004 */ stw r0, 4(r3)
-/* 80371750 90030000 */ stw r0, 0(r3)
-/* 80371754 4E800020 */ blr
-.size func_80371748, . - func_80371748
-
-
-.global func_80371758
-.type func_80371758, @function
-func_80371758:
-/* 80371758 3C608000 */ lis r3, 0x8000
-/* 8037175C 806300E4 */ lwz r3, 0xe4(r3)
-/* 80371760 4E800020 */ blr
-.size func_80371758, . - func_80371758
-
-
-.global func_80371764
-.type func_80371764, @function
-func_80371764:
-/* 80371764 800302CC */ lwz r0, 0x2cc(r3)
-/* 80371768 2C000000 */ cmpwi r0, 0x0
-/* 8037176C 4081000C */ ble- lbl_80371778
-/* 80371770 38600001 */ li r3, 0x1
-/* 80371774 4E800020 */ blr
-lbl_80371778:
-/* 80371778 38600000 */ li r3, 0x0
-/* 8037177C 4E800020 */ blr
-.size func_80371764, . - func_80371764
-
-
-.global func_80371780
-.type func_80371780, @function
-func_80371780:
-/* 80371780 A06302C8 */ lhz r3, 0x2c8(r3)
-/* 80371784 38000001 */ li r0, 0x1
-/* 80371788 28030008 */ cmplwi r3, 8
-/* 8037178C 41820010 */ beq- lbl_8037179c
-/* 80371790 28030000 */ cmplwi r3, 0
-/* 80371794 41820008 */ beq- lbl_8037179c
-/* 80371798 38000000 */ li r0, 0x0
-lbl_8037179c:
-/* 8037179C 2C000000 */ cmpwi r0, 0x0
-/* 803717A0 4182000C */ beq- lbl_803717ac
-/* 803717A4 38600001 */ li r3, 0x1
-/* 803717A8 4E800020 */ blr
-lbl_803717ac:
-/* 803717AC 38600000 */ li r3, 0x0
-/* 803717B0 4E800020 */ blr
-.size func_80371780, . - func_80371780
-
-
-.global func_803717b4
-.type func_803717b4, @function
-func_803717b4:
-/* 803717B4 7C0802A6 */ mflr r0
-/* 803717B8 90010004 */ stw r0, 4(r1)
-/* 803717BC 9421FFF0 */ stwu r1, -0x10(r1)
-/* 803717C0 93E1000C */ stw r31, 0xc(r1)
-/* 803717C4 4BFFD311 */ bl func_8036ead4
-/* 803717C8 808DCAA0 */ lwz r4, lbl_805c68c0@sda21(0)
-/* 803717CC 38040001 */ addi r0, r4, 0x1
-/* 803717D0 900DCAA0 */ stw r0, lbl_805c68c0@sda21(0)
-/* 803717D4 7C9F2378 */ mr r31, r4
-/* 803717D8 4BFFD325 */ bl func_8036eafc
-/* 803717DC 7FE3FB78 */ mr r3, r31
-/* 803717E0 80010014 */ lwz r0, 0x14(r1)
-/* 803717E4 83E1000C */ lwz r31, 0xc(r1)
-/* 803717E8 38210010 */ addi r1, r1, 0x10
-/* 803717EC 7C0803A6 */ mtlr r0
-/* 803717F0 4E800020 */ blr
-.size func_803717b4, . - func_803717b4
-
-
-.global func_803717f4
-.type func_803717f4, @function
-func_803717f4:
-/* 803717F4 7C0802A6 */ mflr r0
-/* 803717F8 90010004 */ stw r0, 4(r1)
-/* 803717FC 9421FFF0 */ stwu r1, -0x10(r1)
-/* 80371800 93E1000C */ stw r31, 0xc(r1)
-/* 80371804 4BFFD2D1 */ bl func_8036ead4
-/* 80371808 808DCAA0 */ lwz r4, lbl_805c68c0@sda21(0)
-/* 8037180C 3804FFFF */ addi r0, r4, -0x1
-/* 80371810 900DCAA0 */ stw r0, lbl_805c68c0@sda21(0)
-/* 80371814 7C9F2378 */ mr r31, r4
-/* 80371818 4BFFD2E5 */ bl func_8036eafc
-/* 8037181C 7FE3FB78 */ mr r3, r31
-/* 80371820 80010014 */ lwz r0, 0x14(r1)
-/* 80371824 83E1000C */ lwz r31, 0xc(r1)
-/* 80371828 38210010 */ addi r1, r1, 0x10
-/* 8037182C 7C0803A6 */ mtlr r0
-/* 80371830 4E800020 */ blr
-.size func_803717f4, . - func_803717f4
-
-
-.global func_80371834
-.type func_80371834, @function
-func_80371834:
-/* 80371834 808302E0 */ lwz r4, 0x2e0(r3)
-/* 80371838 80A302DC */ lwz r5, 0x2dc(r3)
-/* 8037183C 28040000 */ cmplwi r4, 0
-/* 80371840 80C302E4 */ lwz r6, 0x2e4(r3)
-/* 80371844 4082000C */ bne- lbl_80371850
-/* 80371848 90C50004 */ stw r6, 4(r5)
-/* 8037184C 48000008 */ b lbl_80371854
-lbl_80371850:
-/* 80371850 90C402E4 */ stw r6, 0x2e4(r4)
-lbl_80371854:
-/* 80371854 28060000 */ cmplwi r6, 0
-/* 80371858 4082000C */ bne- lbl_80371864
-/* 8037185C 90850000 */ stw r4, 0(r5)
-/* 80371860 48000008 */ b lbl_80371868
-lbl_80371864:
-/* 80371864 908602E0 */ stw r4, 0x2e0(r6)
-lbl_80371868:
-/* 80371868 80050000 */ lwz r0, 0(r5)
-/* 8037186C 28000000 */ cmplwi r0, 0
-/* 80371870 40820020 */ bne- lbl_80371890
-/* 80371874 800302D0 */ lwz r0, 0x2d0(r3)
-/* 80371878 38800001 */ li r4, 0x1
-/* 8037187C 80ADCA98 */ lwz r5, lbl_805c68b8@sda21(0)
-/* 80371880 2000001F */ subfic r0, r0, 0x1f
-/* 80371884 7C800030 */ slw r0, r4, r0
-/* 80371888 7CA00078 */ andc r0, r5, r0
-/* 8037188C 900DCA98 */ stw r0, lbl_805c68b8@sda21(0)
-lbl_80371890:
-/* 80371890 38000000 */ li r0, 0x0
-/* 80371894 900302DC */ stw r0, 0x2dc(r3)
-/* 80371898 4E800020 */ blr
-.size func_80371834, . - func_80371834
-
-
-.global func_8037189c
-.type func_8037189c, @function
-func_8037189c:
-/* 8037189C 808302D4 */ lwz r4, 0x2d4(r3)
-/* 803718A0 80A302F4 */ lwz r5, 0x2f4(r3)
-/* 803718A4 48000024 */ b lbl_803718c8
-lbl_803718a8:
-/* 803718A8 80650000 */ lwz r3, 0(r5)
-/* 803718AC 28030000 */ cmplwi r3, 0
-/* 803718B0 41820014 */ beq- lbl_803718c4
-/* 803718B4 800302D0 */ lwz r0, 0x2d0(r3)
-/* 803718B8 7C002000 */ cmpw r0, r4
-/* 803718BC 40800008 */ bge- lbl_803718c4
-/* 803718C0 7C040378 */ mr r4, r0
-lbl_803718c4:
-/* 803718C4 80A50010 */ lwz r5, 0x10(r5)
-lbl_803718c8:
-/* 803718C8 28050000 */ cmplwi r5, 0
-/* 803718CC 4082FFDC */ bne+ lbl_803718a8
-/* 803718D0 7C832378 */ mr r3, r4
-/* 803718D4 4E800020 */ blr
-.size func_8037189c, . - func_8037189c
-
-
-.global func_803718d8
-.type func_803718d8, @function
-func_803718d8:
-/* 803718D8 7C0802A6 */ mflr r0
-/* 803718DC 90010004 */ stw r0, 4(r1)
-/* 803718E0 9421FFE8 */ stwu r1, -0x18(r1)
-/* 803718E4 93E10014 */ stw r31, 0x14(r1)
-/* 803718E8 7C7F1B78 */ mr r31, r3
-/* 803718EC 93C10010 */ stw r30, 0x10(r1)
-/* 803718F0 3BC40000 */ addi r30, r4, 0x0
-/* 803718F4 A00302C8 */ lhz r0, 0x2c8(r3)
-/* 803718F8 2C000003 */ cmpwi r0, 0x3
-/* 803718FC 41820180 */ beq- lbl_80371a7c
-/* 80371900 40800014 */ bge- lbl_80371914
-/* 80371904 2C000001 */ cmpwi r0, 0x1
-/* 80371908 41820018 */ beq- lbl_80371920
-/* 8037190C 40800164 */ bge- lbl_80371a70
-/* 80371910 4800016C */ b lbl_80371a7c
-lbl_80371914:
-/* 80371914 2C000005 */ cmpwi r0, 0x5
-/* 80371918 40800164 */ bge- lbl_80371a7c
-/* 8037191C 4800007C */ b lbl_80371998
-lbl_80371920:
-/* 80371920 7FE3FB78 */ mr r3, r31
-/* 80371924 4BFFFF11 */ bl func_80371834
-/* 80371928 93DF02D0 */ stw r30, 0x2d0(r31)
-/* 8037192C 3C608054 */ lis r3, lbl_8053ecf8@ha
-/* 80371930 3803ECF8 */ addi r0, r3, lbl_8053ecf8@l
-/* 80371934 807F02D0 */ lwz r3, 0x2d0(r31)
-/* 80371938 54631838 */ slwi r3, r3, 3
-/* 8037193C 7C001A14 */ add r0, r0, r3
-/* 80371940 901F02DC */ stw r0, 0x2dc(r31)
-/* 80371944 809F02DC */ lwz r4, 0x2dc(r31)
-/* 80371948 80640004 */ lwz r3, 4(r4)
-/* 8037194C 28030000 */ cmplwi r3, 0
-/* 80371950 4082000C */ bne- lbl_8037195c
-/* 80371954 93E40000 */ stw r31, 0(r4)
-/* 80371958 48000008 */ b lbl_80371960
-lbl_8037195c:
-/* 8037195C 93E302E0 */ stw r31, 0x2e0(r3)
-lbl_80371960:
-/* 80371960 907F02E4 */ stw r3, 0x2e4(r31)
-/* 80371964 38000000 */ li r0, 0x0
-/* 80371968 38600001 */ li r3, 0x1
-/* 8037196C 901F02E0 */ stw r0, 0x2e0(r31)
-/* 80371970 809F02DC */ lwz r4, 0x2dc(r31)
-/* 80371974 93E40004 */ stw r31, 4(r4)
-/* 80371978 801F02D0 */ lwz r0, 0x2d0(r31)
-/* 8037197C 808DCA98 */ lwz r4, lbl_805c68b8@sda21(0)
-/* 80371980 2000001F */ subfic r0, r0, 0x1f
-/* 80371984 7C600030 */ slw r0, r3, r0
-/* 80371988 7C800378 */ or r0, r4, r0
-/* 8037198C 900DCA98 */ stw r0, lbl_805c68b8@sda21(0)
-/* 80371990 906DCA9C */ stw r3, lbl_805c68bc@sda21(0)
-/* 80371994 480000E8 */ b lbl_80371a7c
-lbl_80371998:
-/* 80371998 809F02E0 */ lwz r4, 0x2e0(r31)
-/* 8037199C 80BF02E4 */ lwz r5, 0x2e4(r31)
-/* 803719A0 28040000 */ cmplwi r4, 0
-/* 803719A4 40820010 */ bne- lbl_803719b4
-/* 803719A8 807F02DC */ lwz r3, 0x2dc(r31)
-/* 803719AC 90A30004 */ stw r5, 4(r3)
-/* 803719B0 48000008 */ b lbl_803719b8
-lbl_803719b4:
-/* 803719B4 90A402E4 */ stw r5, 0x2e4(r4)
-lbl_803719b8:
-/* 803719B8 28050000 */ cmplwi r5, 0
-/* 803719BC 40820010 */ bne- lbl_803719cc
-/* 803719C0 807F02DC */ lwz r3, 0x2dc(r31)
-/* 803719C4 90830000 */ stw r4, 0(r3)
-/* 803719C8 48000008 */ b lbl_803719d0
-lbl_803719cc:
-/* 803719CC 908502E0 */ stw r4, 0x2e0(r5)
-lbl_803719d0:
-/* 803719D0 93DF02D0 */ stw r30, 0x2d0(r31)
-/* 803719D4 809F02DC */ lwz r4, 0x2dc(r31)
-/* 803719D8 80A40000 */ lwz r5, 0(r4)
-/* 803719DC 48000008 */ b lbl_803719e4
-lbl_803719e0:
-/* 803719E0 80A502E0 */ lwz r5, 0x2e0(r5)
-lbl_803719e4:
-/* 803719E4 28050000 */ cmplwi r5, 0
-/* 803719E8 41820014 */ beq- lbl_803719fc
-/* 803719EC 806502D0 */ lwz r3, 0x2d0(r5)
-/* 803719F0 801F02D0 */ lwz r0, 0x2d0(r31)
-/* 803719F4 7C030000 */ cmpw r3, r0
-/* 803719F8 4081FFE8 */ ble+ lbl_803719e0
-lbl_803719fc:
-/* 803719FC 28050000 */ cmplwi r5, 0
-/* 80371A00 40820034 */ bne- lbl_80371a34
-/* 80371A04 80640004 */ lwz r3, 4(r4)
-/* 80371A08 28030000 */ cmplwi r3, 0
-/* 80371A0C 4082000C */ bne- lbl_80371a18
-/* 80371A10 93E40000 */ stw r31, 0(r4)
-/* 80371A14 48000008 */ b lbl_80371a1c
-lbl_80371a18:
-/* 80371A18 93E302E0 */ stw r31, 0x2e0(r3)
-lbl_80371a1c:
-/* 80371A1C 907F02E4 */ stw r3, 0x2e4(r31)
-/* 80371A20 38000000 */ li r0, 0x0
-/* 80371A24 901F02E0 */ stw r0, 0x2e0(r31)
-/* 80371A28 807F02DC */ lwz r3, 0x2dc(r31)
-/* 80371A2C 93E30004 */ stw r31, 4(r3)
-/* 80371A30 4800002C */ b lbl_80371a5c
-lbl_80371a34:
-/* 80371A34 90BF02E0 */ stw r5, 0x2e0(r31)
-/* 80371A38 806502E4 */ lwz r3, 0x2e4(r5)
-/* 80371A3C 93E502E4 */ stw r31, 0x2e4(r5)
-/* 80371A40 28030000 */ cmplwi r3, 0
-/* 80371A44 907F02E4 */ stw r3, 0x2e4(r31)
-/* 80371A48 40820010 */ bne- lbl_80371a58
-/* 80371A4C 807F02DC */ lwz r3, 0x2dc(r31)
-/* 80371A50 93E30000 */ stw r31, 0(r3)
-/* 80371A54 48000008 */ b lbl_80371a5c
-lbl_80371a58:
-/* 80371A58 93E302E0 */ stw r31, 0x2e0(r3)
-lbl_80371a5c:
-/* 80371A5C 807F02F0 */ lwz r3, 0x2f0(r31)
-/* 80371A60 28030000 */ cmplwi r3, 0
-/* 80371A64 41820018 */ beq- lbl_80371a7c
-/* 80371A68 80630008 */ lwz r3, 8(r3)
-/* 80371A6C 48000014 */ b lbl_80371a80
-lbl_80371a70:
-/* 80371A70 38000001 */ li r0, 0x1
-/* 80371A74 900DCA9C */ stw r0, lbl_805c68bc@sda21(0)
-/* 80371A78 93DF02D0 */ stw r30, 0x2d0(r31)
-lbl_80371a7c:
-/* 80371A7C 38600000 */ li r3, 0x0
-lbl_80371a80:
-/* 80371A80 8001001C */ lwz r0, 0x1c(r1)
-/* 80371A84 83E10014 */ lwz r31, 0x14(r1)
-/* 80371A88 83C10010 */ lwz r30, 0x10(r1)
-/* 80371A8C 38210018 */ addi r1, r1, 0x18
-/* 80371A90 7C0803A6 */ mtlr r0
-/* 80371A94 4E800020 */ blr
-.size func_803718d8, . - func_803718d8
-
-
-.global func_80371a98
-.type func_80371a98, @function
-func_80371a98:
-/* 80371A98 7C0802A6 */ mflr r0
-/* 80371A9C 90010004 */ stw r0, 4(r1)
-/* 80371AA0 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80371AA4 93E10014 */ stw r31, 0x14(r1)
-/* 80371AA8 7C9F2378 */ mr r31, r4
-lbl_80371aac:
-/* 80371AAC 800302CC */ lwz r0, 0x2cc(r3)
-/* 80371AB0 2C000000 */ cmpwi r0, 0x0
-/* 80371AB4 41810020 */ bgt- lbl_80371ad4
-/* 80371AB8 800302D0 */ lwz r0, 0x2d0(r3)
-/* 80371ABC 7C00F800 */ cmpw r0, r31
-/* 80371AC0 40810014 */ ble- lbl_80371ad4
-/* 80371AC4 7FE4FB78 */ mr r4, r31
-/* 80371AC8 4BFFFE11 */ bl func_803718d8
-/* 80371ACC 28030000 */ cmplwi r3, 0
-/* 80371AD0 4082FFDC */ bne+ lbl_80371aac
-lbl_80371ad4:
-/* 80371AD4 8001001C */ lwz r0, 0x1c(r1)
-/* 80371AD8 83E10014 */ lwz r31, 0x14(r1)
-/* 80371ADC 38210018 */ addi r1, r1, 0x18
-/* 80371AE0 7C0803A6 */ mtlr r0
-/* 80371AE4 4E800020 */ blr
-.size func_80371a98, . - func_80371a98
-
-
-.global func_80371ae8
-.type func_80371ae8, @function
-func_80371ae8:
-/* 80371AE8 7C0802A6 */ mflr r0
-/* 80371AEC 3C808054 */ lis r4, lbl_8053ecf8@ha
-/* 80371AF0 90010004 */ stw r0, 4(r1)
-/* 80371AF4 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80371AF8 93E10014 */ stw r31, 0x14(r1)
-/* 80371AFC 3BE4ECF8 */ addi r31, r4, lbl_8053ecf8@l
-/* 80371B00 93C10010 */ stw r30, 0x10(r1)
-/* 80371B04 3BC30000 */ addi r30, r3, 0x0
-/* 80371B08 800DCAA0 */ lwz r0, lbl_805c68c0@sda21(0)
-/* 80371B0C 2C000000 */ cmpwi r0, 0x0
-/* 80371B10 4081000C */ ble- lbl_80371b1c
-/* 80371B14 38600000 */ li r3, 0x0
-/* 80371B18 480001B8 */ b lbl_80371cd0
-lbl_80371b1c:
-/* 80371B1C 4BFFC5D9 */ bl func_8036e0f4
-/* 80371B20 3C808000 */ lis r4, 0x8000
-/* 80371B24 80C400E4 */ lwz r6, 0xe4(r4)
-/* 80371B28 7C033040 */ cmplw r3, r6
-/* 80371B2C 38660000 */ addi r3, r6, 0x0
-/* 80371B30 4182000C */ beq- lbl_80371b3c
-/* 80371B34 38600000 */ li r3, 0x0
-/* 80371B38 48000198 */ b lbl_80371cd0
-lbl_80371b3c:
-/* 80371B3C 28060000 */ cmplwi r6, 0
-/* 80371B40 418200BC */ beq- lbl_80371bfc
-/* 80371B44 A00602C8 */ lhz r0, 0x2c8(r6)
-/* 80371B48 28000002 */ cmplwi r0, 2
-/* 80371B4C 40820090 */ bne- lbl_80371bdc
-/* 80371B50 2C1E0000 */ cmpwi r30, 0x0
-/* 80371B54 40820020 */ bne- lbl_80371b74
-/* 80371B58 808DCA98 */ lwz r4, lbl_805c68b8@sda21(0)
-/* 80371B5C 800602D0 */ lwz r0, 0x2d0(r6)
-/* 80371B60 7C840034 */ cntlzw r4, r4
-/* 80371B64 7C002000 */ cmpw r0, r4
-/* 80371B68 4181000C */ bgt- lbl_80371b74
-/* 80371B6C 38600000 */ li r3, 0x0
-/* 80371B70 48000160 */ b lbl_80371cd0
-lbl_80371b74:
-/* 80371B74 38000001 */ li r0, 0x1
-/* 80371B78 B00602C8 */ sth r0, 0x2c8(r6)
-/* 80371B7C 800602D0 */ lwz r0, 0x2d0(r6)
-/* 80371B80 54001838 */ slwi r0, r0, 3
-/* 80371B84 7C1F0214 */ add r0, r31, r0
-/* 80371B88 900602DC */ stw r0, 0x2dc(r6)
-/* 80371B8C 80A602DC */ lwz r5, 0x2dc(r6)
-/* 80371B90 80850004 */ lwz r4, 4(r5)
-/* 80371B94 28040000 */ cmplwi r4, 0
-/* 80371B98 4082000C */ bne- lbl_80371ba4
-/* 80371B9C 90C50000 */ stw r6, 0(r5)
-/* 80371BA0 48000008 */ b lbl_80371ba8
-lbl_80371ba4:
-/* 80371BA4 90C402E0 */ stw r6, 0x2e0(r4)
-lbl_80371ba8:
-/* 80371BA8 908602E4 */ stw r4, 0x2e4(r6)
-/* 80371BAC 38000000 */ li r0, 0x0
-/* 80371BB0 38800001 */ li r4, 0x1
-/* 80371BB4 900602E0 */ stw r0, 0x2e0(r6)
-/* 80371BB8 80A602DC */ lwz r5, 0x2dc(r6)
-/* 80371BBC 90C50004 */ stw r6, 4(r5)
-/* 80371BC0 800602D0 */ lwz r0, 0x2d0(r6)
-/* 80371BC4 80ADCA98 */ lwz r5, lbl_805c68b8@sda21(0)
-/* 80371BC8 2000001F */ subfic r0, r0, 0x1f
-/* 80371BCC 7C800030 */ slw r0, r4, r0
-/* 80371BD0 7CA00378 */ or r0, r5, r0
-/* 80371BD4 900DCA98 */ stw r0, lbl_805c68b8@sda21(0)
-/* 80371BD8 908DCA9C */ stw r4, lbl_805c68bc@sda21(0)
-lbl_80371bdc:
-/* 80371BDC A00601A2 */ lhz r0, 0x1a2(r6)
-/* 80371BE0 540007BD */ rlwinm. r0, r0, 0, 0x1e, 0x1e
-/* 80371BE4 40820018 */ bne- lbl_80371bfc
-/* 80371BE8 4BFFC519 */ bl func_8036e100
-/* 80371BEC 28030000 */ cmplwi r3, 0
-/* 80371BF0 4182000C */ beq- lbl_80371bfc
-/* 80371BF4 38600000 */ li r3, 0x0
-/* 80371BF8 480000D8 */ b lbl_80371cd0
-lbl_80371bfc:
-/* 80371BFC 800DCA98 */ lwz r0, lbl_805c68b8@sda21(0)
-/* 80371C00 38800000 */ li r4, 0x0
-/* 80371C04 3C608000 */ lis r3, 0x8000
-/* 80371C08 28000000 */ cmplwi r0, 0
-/* 80371C0C 908300E4 */ stw r4, 0xe4(r3)
-/* 80371C10 40820034 */ bne- lbl_80371c44
-/* 80371C14 387F0720 */ addi r3, r31, 0x720
-/* 80371C18 4BFFC481 */ bl func_8036e098
-lbl_80371c1c:
-/* 80371C1C 4BFFCECD */ bl func_8036eae8
-lbl_80371c20:
-/* 80371C20 800DCA98 */ lwz r0, lbl_805c68b8@sda21(0)
-/* 80371C24 28000000 */ cmplwi r0, 0
-/* 80371C28 4182FFF8 */ beq+ lbl_80371c20
-/* 80371C2C 4BFFCEA9 */ bl func_8036ead4
-/* 80371C30 800DCA98 */ lwz r0, lbl_805c68b8@sda21(0)
-/* 80371C34 28000000 */ cmplwi r0, 0
-/* 80371C38 4182FFE4 */ beq+ lbl_80371c1c
-/* 80371C3C 387F0720 */ addi r3, r31, 0x720
-/* 80371C40 4BFFC621 */ bl func_8036e260
-lbl_80371c44:
-/* 80371C44 38600000 */ li r3, 0x0
-/* 80371C48 906DCA9C */ stw r3, lbl_805c68bc@sda21(0)
-/* 80371C4C 800DCA98 */ lwz r0, lbl_805c68b8@sda21(0)
-/* 80371C50 7C070034 */ cntlzw r7, r0
-/* 80371C54 54E01838 */ slwi r0, r7, 3
-/* 80371C58 7C9F0214 */ add r4, r31, r0
-/* 80371C5C 80A40000 */ lwz r5, 0(r4)
-/* 80371C60 80C502E0 */ lwz r6, 0x2e0(r5)
-/* 80371C64 3BE50000 */ addi r31, r5, 0x0
-/* 80371C68 28060000 */ cmplwi r6, 0
-/* 80371C6C 4082000C */ bne- lbl_80371c78
-/* 80371C70 90640004 */ stw r3, 4(r4)
-/* 80371C74 48000008 */ b lbl_80371c7c
-lbl_80371c78:
-/* 80371C78 906602E4 */ stw r3, 0x2e4(r6)
-lbl_80371c7c:
-/* 80371C7C 90C40000 */ stw r6, 0(r4)
-/* 80371C80 80040000 */ lwz r0, 0(r4)
-/* 80371C84 28000000 */ cmplwi r0, 0
-/* 80371C88 4082001C */ bne- lbl_80371ca4
-/* 80371C8C 2007001F */ subfic r0, r7, 0x1f
-/* 80371C90 808DCA98 */ lwz r4, lbl_805c68b8@sda21(0)
-/* 80371C94 38600001 */ li r3, 0x1
-/* 80371C98 7C600030 */ slw r0, r3, r0
-/* 80371C9C 7C800078 */ andc r0, r4, r0
-/* 80371CA0 900DCA98 */ stw r0, lbl_805c68b8@sda21(0)
-lbl_80371ca4:
-/* 80371CA4 38000000 */ li r0, 0x0
-/* 80371CA8 901F02DC */ stw r0, 0x2dc(r31)
-/* 80371CAC 38000002 */ li r0, 0x2
-/* 80371CB0 3C808000 */ lis r4, 0x8000
-/* 80371CB4 B01F02C8 */ sth r0, 0x2c8(r31)
-/* 80371CB8 7FE3FB78 */ mr r3, r31
-/* 80371CBC 93E400E4 */ stw r31, 0xe4(r4)
-/* 80371CC0 4BFFC3D9 */ bl func_8036e098
-/* 80371CC4 7FE3FB78 */ mr r3, r31
-/* 80371CC8 4BFFC4B9 */ bl func_8036e180
-/* 80371CCC 7FE3FB78 */ mr r3, r31
-lbl_80371cd0:
-/* 80371CD0 8001001C */ lwz r0, 0x1c(r1)
-/* 80371CD4 83E10014 */ lwz r31, 0x14(r1)
-/* 80371CD8 83C10010 */ lwz r30, 0x10(r1)
-/* 80371CDC 38210018 */ addi r1, r1, 0x18
-/* 80371CE0 7C0803A6 */ mtlr r0
-/* 80371CE4 4E800020 */ blr
-.size func_80371ae8, . - func_80371ae8
-
-
-.global func_80371ce8
-.type func_80371ce8, @function
-func_80371ce8:
-/* 80371CE8 7C0802A6 */ mflr r0
-/* 80371CEC 90010004 */ stw r0, 4(r1)
-/* 80371CF0 9421FFF8 */ stwu r1, -8(r1)
-/* 80371CF4 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 80371CF8 2C000000 */ cmpwi r0, 0x0
-/* 80371CFC 4182000C */ beq- lbl_80371d08
-/* 80371D00 38600000 */ li r3, 0x0
-/* 80371D04 4BFFFDE5 */ bl func_80371ae8
-lbl_80371d08:
-/* 80371D08 8001000C */ lwz r0, 0xc(r1)
-/* 80371D0C 38210008 */ addi r1, r1, 0x8
-/* 80371D10 7C0803A6 */ mtlr r0
-/* 80371D14 4E800020 */ blr
-.size func_80371ce8, . - func_80371ce8
-
-
-.global func_80371d18
-.type func_80371d18, @function
-func_80371d18:
-/* 80371D18 7C0802A6 */ mflr r0
-/* 80371D1C 90010004 */ stw r0, 4(r1)
-/* 80371D20 9421FFF0 */ stwu r1, -0x10(r1)
-/* 80371D24 93E1000C */ stw r31, 0xc(r1)
-/* 80371D28 4BFFCDAD */ bl func_8036ead4
-/* 80371D2C 3BE30000 */ addi r31, r3, 0x0
-/* 80371D30 38600001 */ li r3, 0x1
-/* 80371D34 4BFFFDB5 */ bl func_80371ae8
-/* 80371D38 7FE3FB78 */ mr r3, r31
-/* 80371D3C 4BFFCDC1 */ bl func_8036eafc
-/* 80371D40 80010014 */ lwz r0, 0x14(r1)
-/* 80371D44 83E1000C */ lwz r31, 0xc(r1)
-/* 80371D48 38210010 */ addi r1, r1, 0x10
-/* 80371D4C 7C0803A6 */ mtlr r0
-/* 80371D50 4E800020 */ blr
-.size func_80371d18, . - func_80371d18
-
-
-.global func_80371d54
-.type func_80371d54, @function
-func_80371d54:
-/* 80371D54 7C0802A6 */ mflr r0
-/* 80371D58 2C080000 */ cmpwi r8, 0x0
-/* 80371D5C 90010004 */ stw r0, 4(r1)
-/* 80371D60 9421FFC8 */ stwu r1, -0x38(r1)
-/* 80371D64 93E10034 */ stw r31, 0x34(r1)
-/* 80371D68 3BE30000 */ addi r31, r3, 0x0
-/* 80371D6C 93C10030 */ stw r30, 0x30(r1)
-/* 80371D70 3BC70000 */ addi r30, r7, 0x0
-/* 80371D74 93A1002C */ stw r29, 0x2c(r1)
-/* 80371D78 3BA60000 */ addi r29, r6, 0x0
-/* 80371D7C 93810028 */ stw r28, 0x28(r1)
-/* 80371D80 3B850000 */ addi r28, r5, 0x0
-/* 80371D84 4180000C */ blt- lbl_80371d90
-/* 80371D88 2C08001F */ cmpwi r8, 0x1f
-/* 80371D8C 4081000C */ ble- lbl_80371d98
-lbl_80371d90:
-/* 80371D90 38600000 */ li r3, 0x0
-/* 80371D94 480000C0 */ b lbl_80371e54
-lbl_80371d98:
-/* 80371D98 38E00001 */ li r7, 0x1
-/* 80371D9C B0FF02C8 */ sth r7, 0x2c8(r31)
-/* 80371DA0 552007FE */ clrlwi r0, r9, 0x1f
-/* 80371DA4 57A90038 */ rlwinm r9, r29, 0, 0, 0x1c
-/* 80371DA8 B01F02CA */ sth r0, 0x2ca(r31)
-/* 80371DAC 38C0FFFF */ li r6, -0x1
-/* 80371DB0 38000000 */ li r0, 0x0
-/* 80371DB4 911F02D4 */ stw r8, 0x2d4(r31)
-/* 80371DB8 387F0000 */ addi r3, r31, 0x0
-/* 80371DBC 38A9FFF8 */ addi r5, r9, -0x8
-/* 80371DC0 911F02D0 */ stw r8, 0x2d0(r31)
-/* 80371DC4 90FF02CC */ stw r7, 0x2cc(r31)
-/* 80371DC8 90DF02D8 */ stw r6, 0x2d8(r31)
-/* 80371DCC 901F02F0 */ stw r0, 0x2f0(r31)
-/* 80371DD0 901F02EC */ stw r0, 0x2ec(r31)
-/* 80371DD4 901F02E8 */ stw r0, 0x2e8(r31)
-/* 80371DD8 901F02F8 */ stw r0, 0x2f8(r31)
-/* 80371DDC 901F02F4 */ stw r0, 0x2f4(r31)
-/* 80371DE0 9009FFF8 */ stw r0, -8(r9)
-/* 80371DE4 9009FFFC */ stw r0, -4(r9)
-/* 80371DE8 4BFFC49D */ bl func_8036e284
-/* 80371DEC 3C608037 */ lis r3, func_80371e74@ha
-/* 80371DF0 38031E74 */ addi r0, r3, func_80371e74@l
-/* 80371DF4 901F0084 */ stw r0, 0x84(r31)
-/* 80371DF8 3C60DEAE */ lis r3, 0xdeae
-/* 80371DFC 7C9EE850 */ subf r4, r30, r29
-/* 80371E00 939F000C */ stw r28, 0xc(r31)
-/* 80371E04 3803BABE */ addi r0, r3, -0x4542
-/* 80371E08 93BF0304 */ stw r29, 0x304(r31)
-/* 80371E0C 909F0308 */ stw r4, 0x308(r31)
-/* 80371E10 807F0308 */ lwz r3, 0x308(r31)
-/* 80371E14 90030000 */ stw r0, 0(r3)
-/* 80371E18 4BFFCCBD */ bl func_8036ead4
-/* 80371E1C 3C808000 */ lis r4, 0x8000
-/* 80371E20 38A400DC */ addi r5, r4, 0xdc
-/* 80371E24 84C50004 */ lwzu r6, 4(r5)
-/* 80371E28 28060000 */ cmplwi r6, 0
-/* 80371E2C 4082000C */ bne- lbl_80371e38
-/* 80371E30 93E400DC */ stw r31, 0xdc(r4)
-/* 80371E34 48000008 */ b lbl_80371e3c
-lbl_80371e38:
-/* 80371E38 93E602FC */ stw r31, 0x2fc(r6)
-lbl_80371e3c:
-/* 80371E3C 90DF0300 */ stw r6, 0x300(r31)
-/* 80371E40 38000000 */ li r0, 0x0
-/* 80371E44 901F02FC */ stw r0, 0x2fc(r31)
-/* 80371E48 93E50000 */ stw r31, 0(r5)
-/* 80371E4C 4BFFCCB1 */ bl func_8036eafc
-/* 80371E50 38600001 */ li r3, 0x1
-lbl_80371e54:
-/* 80371E54 8001003C */ lwz r0, 0x3c(r1)
-/* 80371E58 83E10034 */ lwz r31, 0x34(r1)
-/* 80371E5C 83C10030 */ lwz r30, 0x30(r1)
-/* 80371E60 83A1002C */ lwz r29, 0x2c(r1)
-/* 80371E64 83810028 */ lwz r28, 0x28(r1)
-/* 80371E68 38210038 */ addi r1, r1, 0x38
-/* 80371E6C 7C0803A6 */ mtlr r0
-/* 80371E70 4E800020 */ blr
-.size func_80371d54, . - func_80371d54
-
-
-.global func_80371e74
-.type func_80371e74, @function
-func_80371e74:
-/* 80371E74 7C0802A6 */ mflr r0
-/* 80371E78 90010004 */ stw r0, 4(r1)
-/* 80371E7C 9421FFE0 */ stwu r1, -0x20(r1)
-/* 80371E80 93E1001C */ stw r31, 0x1c(r1)
-/* 80371E84 93C10018 */ stw r30, 0x18(r1)
-/* 80371E88 93A10014 */ stw r29, 0x14(r1)
-/* 80371E8C 93810010 */ stw r28, 0x10(r1)
-/* 80371E90 7C7C1B78 */ mr r28, r3
-/* 80371E94 4BFFCC41 */ bl func_8036ead4
-/* 80371E98 3FE08000 */ lis r31, 0x8000
-/* 80371E9C 83DF00E4 */ lwz r30, 0xe4(r31)
-/* 80371EA0 3BA30000 */ addi r29, r3, 0x0
-/* 80371EA4 387E0000 */ addi r3, r30, 0x0
-/* 80371EA8 4BFFC3B9 */ bl func_8036e260
-/* 80371EAC A01E02CA */ lhz r0, 0x2ca(r30)
-/* 80371EB0 540007FF */ clrlwi. r0, r0, 0x1f
-/* 80371EB4 41820044 */ beq- lbl_80371ef8
-/* 80371EB8 809E02FC */ lwz r4, 0x2fc(r30)
-/* 80371EBC 80BE0300 */ lwz r5, 0x300(r30)
-/* 80371EC0 28040000 */ cmplwi r4, 0
-/* 80371EC4 4082000C */ bne- lbl_80371ed0
-/* 80371EC8 90BF00E0 */ stw r5, 0xe0(r31)
-/* 80371ECC 48000008 */ b lbl_80371ed4
-lbl_80371ed0:
-/* 80371ED0 90A40300 */ stw r5, 0x300(r4)
-lbl_80371ed4:
-/* 80371ED4 28050000 */ cmplwi r5, 0
-/* 80371ED8 40820010 */ bne- lbl_80371ee8
-/* 80371EDC 3C608000 */ lis r3, 0x8000
-/* 80371EE0 908300DC */ stw r4, 0xdc(r3)
-/* 80371EE4 48000008 */ b lbl_80371eec
-lbl_80371ee8:
-/* 80371EE8 908502FC */ stw r4, 0x2fc(r5)
-lbl_80371eec:
-/* 80371EEC 38000000 */ li r0, 0x0
-/* 80371EF0 B01E02C8 */ sth r0, 0x2c8(r30)
-/* 80371EF4 48000010 */ b lbl_80371f04
-lbl_80371ef8:
-/* 80371EF8 38000008 */ li r0, 0x8
-/* 80371EFC B01E02C8 */ sth r0, 0x2c8(r30)
-/* 80371F00 939E02D8 */ stw r28, 0x2d8(r30)
-lbl_80371f04:
-/* 80371F04 7FC3F378 */ mr r3, r30
-/* 80371F08 4BFFE27D */ bl func_80370184
-/* 80371F0C 387E02E8 */ addi r3, r30, 0x2e8
-/* 80371F10 480006E9 */ bl func_803725f8
-/* 80371F14 38000001 */ li r0, 0x1
-/* 80371F18 900DCA9C */ stw r0, lbl_805c68bc@sda21(0)
-/* 80371F1C 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 80371F20 2C000000 */ cmpwi r0, 0x0
-/* 80371F24 4182000C */ beq- lbl_80371f30
-/* 80371F28 38600000 */ li r3, 0x0
-/* 80371F2C 4BFFFBBD */ bl func_80371ae8
-lbl_80371f30:
-/* 80371F30 7FA3EB78 */ mr r3, r29
-/* 80371F34 4BFFCBC9 */ bl func_8036eafc
-/* 80371F38 80010024 */ lwz r0, 0x24(r1)
-/* 80371F3C 83E1001C */ lwz r31, 0x1c(r1)
-/* 80371F40 83C10018 */ lwz r30, 0x18(r1)
-/* 80371F44 83A10014 */ lwz r29, 0x14(r1)
-/* 80371F48 83810010 */ lwz r28, 0x10(r1)
-/* 80371F4C 38210020 */ addi r1, r1, 0x20
-/* 80371F50 7C0803A6 */ mtlr r0
-/* 80371F54 4E800020 */ blr
-.size func_80371e74, . - func_80371e74
-
-
-.global func_80371f58
-.type func_80371f58, @function
-func_80371f58:
-/* 80371F58 7C0802A6 */ mflr r0
-/* 80371F5C 90010004 */ stw r0, 4(r1)
-/* 80371F60 9421FFE0 */ stwu r1, -0x20(r1)
-/* 80371F64 93E1001C */ stw r31, 0x1c(r1)
-/* 80371F68 93C10018 */ stw r30, 0x18(r1)
-/* 80371F6C 7C7E1B78 */ mr r30, r3
-/* 80371F70 93A10014 */ stw r29, 0x14(r1)
-/* 80371F74 4BFFCB61 */ bl func_8036ead4
-/* 80371F78 A01E02C8 */ lhz r0, 0x2c8(r30)
-/* 80371F7C 3BE30000 */ addi r31, r3, 0x0
-/* 80371F80 2C000003 */ cmpwi r0, 0x3
-/* 80371F84 418200DC */ beq- lbl_80372060
-/* 80371F88 40800014 */ bge- lbl_80371f9c
-/* 80371F8C 2C000001 */ cmpwi r0, 0x1
-/* 80371F90 41820018 */ beq- lbl_80371fa8
-/* 80371F94 4080002C */ bge- lbl_80371fc0
-/* 80371F98 480000C8 */ b lbl_80372060
-lbl_80371f9c:
-/* 80371F9C 2C000005 */ cmpwi r0, 0x5
-/* 80371FA0 408000C0 */ bge- lbl_80372060
-/* 80371FA4 48000028 */ b lbl_80371fcc
-lbl_80371fa8:
-/* 80371FA8 801E02CC */ lwz r0, 0x2cc(r30)
-/* 80371FAC 2C000000 */ cmpwi r0, 0x0
-/* 80371FB0 418100BC */ bgt- lbl_8037206c
-/* 80371FB4 7FC3F378 */ mr r3, r30
-/* 80371FB8 4BFFF87D */ bl func_80371834
-/* 80371FBC 480000B0 */ b lbl_8037206c
-lbl_80371fc0:
-/* 80371FC0 38000001 */ li r0, 0x1
-/* 80371FC4 900DCA9C */ stw r0, lbl_805c68bc@sda21(0)
-/* 80371FC8 480000A4 */ b lbl_8037206c
-lbl_80371fcc:
-/* 80371FCC 809E02E0 */ lwz r4, 0x2e0(r30)
-/* 80371FD0 80BE02E4 */ lwz r5, 0x2e4(r30)
-/* 80371FD4 28040000 */ cmplwi r4, 0
-/* 80371FD8 40820010 */ bne- lbl_80371fe8
-/* 80371FDC 807E02DC */ lwz r3, 0x2dc(r30)
-/* 80371FE0 90A30004 */ stw r5, 4(r3)
-/* 80371FE4 48000008 */ b lbl_80371fec
-lbl_80371fe8:
-/* 80371FE8 90A402E4 */ stw r5, 0x2e4(r4)
-lbl_80371fec:
-/* 80371FEC 28050000 */ cmplwi r5, 0
-/* 80371FF0 40820010 */ bne- lbl_80372000
-/* 80371FF4 807E02DC */ lwz r3, 0x2dc(r30)
-/* 80371FF8 90830000 */ stw r4, 0(r3)
-/* 80371FFC 48000008 */ b lbl_80372004
-lbl_80372000:
-/* 80372000 908502E0 */ stw r4, 0x2e0(r5)
-lbl_80372004:
-/* 80372004 38000000 */ li r0, 0x0
-/* 80372008 901E02DC */ stw r0, 0x2dc(r30)
-/* 8037200C 801E02CC */ lwz r0, 0x2cc(r30)
-/* 80372010 2C000000 */ cmpwi r0, 0x0
-/* 80372014 41810058 */ bgt- lbl_8037206c
-/* 80372018 807E02F0 */ lwz r3, 0x2f0(r30)
-/* 8037201C 28030000 */ cmplwi r3, 0
-/* 80372020 4182004C */ beq- lbl_8037206c
-/* 80372024 83A30008 */ lwz r29, 8(r3)
-lbl_80372028:
-/* 80372028 801D02CC */ lwz r0, 0x2cc(r29)
-/* 8037202C 2C000000 */ cmpwi r0, 0x0
-/* 80372030 4181003C */ bgt- lbl_8037206c
-/* 80372034 7FA3EB78 */ mr r3, r29
-/* 80372038 4BFFF865 */ bl func_8037189c
-/* 8037203C 801D02D0 */ lwz r0, 0x2d0(r29)
-/* 80372040 38830000 */ addi r4, r3, 0x0
-/* 80372044 7C002000 */ cmpw r0, r4
-/* 80372048 41820024 */ beq- lbl_8037206c
-/* 8037204C 7FA3EB78 */ mr r3, r29
-/* 80372050 4BFFF889 */ bl func_803718d8
-/* 80372054 7C7D1B79 */ or. r29, r3, r3
-/* 80372058 4082FFD0 */ bne+ lbl_80372028
-/* 8037205C 48000010 */ b lbl_8037206c
-lbl_80372060:
-/* 80372060 7FE3FB78 */ mr r3, r31
-/* 80372064 4BFFCA99 */ bl func_8036eafc
-/* 80372068 48000090 */ b lbl_803720f8
-lbl_8037206c:
-/* 8037206C 7FC3F378 */ mr r3, r30
-/* 80372070 4BFFC1F1 */ bl func_8036e260
-/* 80372074 A01E02CA */ lhz r0, 0x2ca(r30)
-/* 80372078 540007FF */ clrlwi. r0, r0, 0x1f
-/* 8037207C 41820048 */ beq- lbl_803720c4
-/* 80372080 809E02FC */ lwz r4, 0x2fc(r30)
-/* 80372084 80BE0300 */ lwz r5, 0x300(r30)
-/* 80372088 28040000 */ cmplwi r4, 0
-/* 8037208C 40820010 */ bne- lbl_8037209c
-/* 80372090 3C608000 */ lis r3, 0x8000
-/* 80372094 90A300E0 */ stw r5, 0xe0(r3)
-/* 80372098 48000008 */ b lbl_803720a0
-lbl_8037209c:
-/* 8037209C 90A40300 */ stw r5, 0x300(r4)
-lbl_803720a0:
-/* 803720A0 28050000 */ cmplwi r5, 0
-/* 803720A4 40820010 */ bne- lbl_803720b4
-/* 803720A8 3C608000 */ lis r3, 0x8000
-/* 803720AC 908300DC */ stw r4, 0xdc(r3)
-/* 803720B0 48000008 */ b lbl_803720b8
-lbl_803720b4:
-/* 803720B4 908502FC */ stw r4, 0x2fc(r5)
-lbl_803720b8:
-/* 803720B8 38000000 */ li r0, 0x0
-/* 803720BC B01E02C8 */ sth r0, 0x2c8(r30)
-/* 803720C0 4800000C */ b lbl_803720cc
-lbl_803720c4:
-/* 803720C4 38000008 */ li r0, 0x8
-/* 803720C8 B01E02C8 */ sth r0, 0x2c8(r30)
-lbl_803720cc:
-/* 803720CC 7FC3F378 */ mr r3, r30
-/* 803720D0 4BFFE0B5 */ bl func_80370184
-/* 803720D4 387E02E8 */ addi r3, r30, 0x2e8
-/* 803720D8 48000521 */ bl func_803725f8
-/* 803720DC 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 803720E0 2C000000 */ cmpwi r0, 0x0
-/* 803720E4 4182000C */ beq- lbl_803720f0
-/* 803720E8 38600000 */ li r3, 0x0
-/* 803720EC 4BFFF9FD */ bl func_80371ae8
-lbl_803720f0:
-/* 803720F0 7FE3FB78 */ mr r3, r31
-/* 803720F4 4BFFCA09 */ bl func_8036eafc
-lbl_803720f8:
-/* 803720F8 80010024 */ lwz r0, 0x24(r1)
-/* 803720FC 83E1001C */ lwz r31, 0x1c(r1)
-/* 80372100 83C10018 */ lwz r30, 0x18(r1)
-/* 80372104 83A10014 */ lwz r29, 0x14(r1)
-/* 80372108 38210020 */ addi r1, r1, 0x20
-/* 8037210C 7C0803A6 */ mtlr r0
-/* 80372110 4E800020 */ blr
-.size func_80371f58, . - func_80371f58
-
-
-.global func_80372114
-.type func_80372114, @function
-func_80372114:
-/* 80372114 7C0802A6 */ mflr r0
-/* 80372118 90010004 */ stw r0, 4(r1)
-/* 8037211C 9421FFD8 */ stwu r1, -0x28(r1)
-/* 80372120 93E10024 */ stw r31, 0x24(r1)
-/* 80372124 93C10020 */ stw r30, 0x20(r1)
-/* 80372128 93A1001C */ stw r29, 0x1c(r1)
-/* 8037212C 7C7D1B78 */ mr r29, r3
-/* 80372130 4BFFC9A5 */ bl func_8036ead4
-/* 80372134 809D02CC */ lwz r4, 0x2cc(r29)
-/* 80372138 3BE30000 */ addi r31, r3, 0x0
-/* 8037213C 3804FFFF */ addi r0, r4, -0x1
-/* 80372140 901D02CC */ stw r0, 0x2cc(r29)
-/* 80372144 7C9E2378 */ mr r30, r4
-/* 80372148 801D02CC */ lwz r0, 0x2cc(r29)
-/* 8037214C 2C000000 */ cmpwi r0, 0x0
-/* 80372150 40800010 */ bge- lbl_80372160
-/* 80372154 38000000 */ li r0, 0x0
-/* 80372158 901D02CC */ stw r0, 0x2cc(r29)
-/* 8037215C 48000218 */ b lbl_80372374
-lbl_80372160:
-/* 80372160 40820214 */ bne- lbl_80372374
-/* 80372164 A01D02C8 */ lhz r0, 0x2c8(r29)
-/* 80372168 2C000004 */ cmpwi r0, 0x4
-/* 8037216C 418200B8 */ beq- lbl_80372224
-/* 80372170 408001F0 */ bge- lbl_80372360
-/* 80372174 2C000001 */ cmpwi r0, 0x1
-/* 80372178 41820008 */ beq- lbl_80372180
-/* 8037217C 480001E4 */ b lbl_80372360
-lbl_80372180:
-/* 80372180 801D02D4 */ lwz r0, 0x2d4(r29)
-/* 80372184 807D02F4 */ lwz r3, 0x2f4(r29)
-/* 80372188 48000024 */ b lbl_803721ac
-lbl_8037218c:
-/* 8037218C 80830000 */ lwz r4, 0(r3)
-/* 80372190 28040000 */ cmplwi r4, 0
-/* 80372194 41820014 */ beq- lbl_803721a8
-/* 80372198 808402D0 */ lwz r4, 0x2d0(r4)
-/* 8037219C 7C040000 */ cmpw r4, r0
-/* 803721A0 40800008 */ bge- lbl_803721a8
-/* 803721A4 7C802378 */ mr r0, r4
-lbl_803721a8:
-/* 803721A8 80630010 */ lwz r3, 0x10(r3)
-lbl_803721ac:
-/* 803721AC 28030000 */ cmplwi r3, 0
-/* 803721B0 4082FFDC */ bne+ lbl_8037218c
-/* 803721B4 901D02D0 */ stw r0, 0x2d0(r29)
-/* 803721B8 3C608054 */ lis r3, lbl_8053ecf8@ha
-/* 803721BC 3803ECF8 */ addi r0, r3, lbl_8053ecf8@l
-/* 803721C0 807D02D0 */ lwz r3, 0x2d0(r29)
-/* 803721C4 54631838 */ slwi r3, r3, 3
-/* 803721C8 7C001A14 */ add r0, r0, r3
-/* 803721CC 901D02DC */ stw r0, 0x2dc(r29)
-/* 803721D0 809D02DC */ lwz r4, 0x2dc(r29)
-/* 803721D4 80640004 */ lwz r3, 4(r4)
-/* 803721D8 28030000 */ cmplwi r3, 0
-/* 803721DC 4082000C */ bne- lbl_803721e8
-/* 803721E0 93A40000 */ stw r29, 0(r4)
-/* 803721E4 48000008 */ b lbl_803721ec
-lbl_803721e8:
-/* 803721E8 93A302E0 */ stw r29, 0x2e0(r3)
-lbl_803721ec:
-/* 803721EC 907D02E4 */ stw r3, 0x2e4(r29)
-/* 803721F0 38000000 */ li r0, 0x0
-/* 803721F4 38600001 */ li r3, 0x1
-/* 803721F8 901D02E0 */ stw r0, 0x2e0(r29)
-/* 803721FC 809D02DC */ lwz r4, 0x2dc(r29)
-/* 80372200 93A40004 */ stw r29, 4(r4)
-/* 80372204 801D02D0 */ lwz r0, 0x2d0(r29)
-/* 80372208 808DCA98 */ lwz r4, lbl_805c68b8@sda21(0)
-/* 8037220C 2000001F */ subfic r0, r0, 0x1f
-/* 80372210 7C600030 */ slw r0, r3, r0
-/* 80372214 7C800378 */ or r0, r4, r0
-/* 80372218 900DCA98 */ stw r0, lbl_805c68b8@sda21(0)
-/* 8037221C 906DCA9C */ stw r3, lbl_805c68bc@sda21(0)
-/* 80372220 48000140 */ b lbl_80372360
-lbl_80372224:
-/* 80372224 809D02E0 */ lwz r4, 0x2e0(r29)
-/* 80372228 80BD02E4 */ lwz r5, 0x2e4(r29)
-/* 8037222C 28040000 */ cmplwi r4, 0
-/* 80372230 40820010 */ bne- lbl_80372240
-/* 80372234 807D02DC */ lwz r3, 0x2dc(r29)
-/* 80372238 90A30004 */ stw r5, 4(r3)
-/* 8037223C 48000008 */ b lbl_80372244
-lbl_80372240:
-/* 80372240 90A402E4 */ stw r5, 0x2e4(r4)
-lbl_80372244:
-/* 80372244 28050000 */ cmplwi r5, 0
-/* 80372248 40820010 */ bne- lbl_80372258
-/* 8037224C 807D02DC */ lwz r3, 0x2dc(r29)
-/* 80372250 90830000 */ stw r4, 0(r3)
-/* 80372254 48000008 */ b lbl_8037225c
-lbl_80372258:
-/* 80372258 908502E0 */ stw r4, 0x2e0(r5)
-lbl_8037225c:
-/* 8037225C 801D02D4 */ lwz r0, 0x2d4(r29)
-/* 80372260 807D02F4 */ lwz r3, 0x2f4(r29)
-/* 80372264 48000024 */ b lbl_80372288
-lbl_80372268:
-/* 80372268 80830000 */ lwz r4, 0(r3)
-/* 8037226C 28040000 */ cmplwi r4, 0
-/* 80372270 41820014 */ beq- lbl_80372284
-/* 80372274 808402D0 */ lwz r4, 0x2d0(r4)
-/* 80372278 7C040000 */ cmpw r4, r0
-/* 8037227C 40800008 */ bge- lbl_80372284
-/* 80372280 7C802378 */ mr r0, r4
-lbl_80372284:
-/* 80372284 80630010 */ lwz r3, 0x10(r3)
-lbl_80372288:
-/* 80372288 28030000 */ cmplwi r3, 0
-/* 8037228C 4082FFDC */ bne+ lbl_80372268
-/* 80372290 901D02D0 */ stw r0, 0x2d0(r29)
-/* 80372294 809D02DC */ lwz r4, 0x2dc(r29)
-/* 80372298 80A40000 */ lwz r5, 0(r4)
-/* 8037229C 48000008 */ b lbl_803722a4
-lbl_803722a0:
-/* 803722A0 80A502E0 */ lwz r5, 0x2e0(r5)
-lbl_803722a4:
-/* 803722A4 28050000 */ cmplwi r5, 0
-/* 803722A8 41820014 */ beq- lbl_803722bc
-/* 803722AC 806502D0 */ lwz r3, 0x2d0(r5)
-/* 803722B0 801D02D0 */ lwz r0, 0x2d0(r29)
-/* 803722B4 7C030000 */ cmpw r3, r0
-/* 803722B8 4081FFE8 */ ble+ lbl_803722a0
-lbl_803722bc:
-/* 803722BC 28050000 */ cmplwi r5, 0
-/* 803722C0 40820034 */ bne- lbl_803722f4
-/* 803722C4 80640004 */ lwz r3, 4(r4)
-/* 803722C8 28030000 */ cmplwi r3, 0
-/* 803722CC 4082000C */ bne- lbl_803722d8
-/* 803722D0 93A40000 */ stw r29, 0(r4)
-/* 803722D4 48000008 */ b lbl_803722dc
-lbl_803722d8:
-/* 803722D8 93A302E0 */ stw r29, 0x2e0(r3)
-lbl_803722dc:
-/* 803722DC 907D02E4 */ stw r3, 0x2e4(r29)
-/* 803722E0 38000000 */ li r0, 0x0
-/* 803722E4 901D02E0 */ stw r0, 0x2e0(r29)
-/* 803722E8 807D02DC */ lwz r3, 0x2dc(r29)
-/* 803722EC 93A30004 */ stw r29, 4(r3)
-/* 803722F0 4800002C */ b lbl_8037231c
-lbl_803722f4:
-/* 803722F4 90BD02E0 */ stw r5, 0x2e0(r29)
-/* 803722F8 806502E4 */ lwz r3, 0x2e4(r5)
-/* 803722FC 93A502E4 */ stw r29, 0x2e4(r5)
-/* 80372300 28030000 */ cmplwi r3, 0
-/* 80372304 907D02E4 */ stw r3, 0x2e4(r29)
-/* 80372308 40820010 */ bne- lbl_80372318
-/* 8037230C 807D02DC */ lwz r3, 0x2dc(r29)
-/* 80372310 93A30000 */ stw r29, 0(r3)
-/* 80372314 48000008 */ b lbl_8037231c
-lbl_80372318:
-/* 80372318 93A302E0 */ stw r29, 0x2e0(r3)
-lbl_8037231c:
-/* 8037231C 807D02F0 */ lwz r3, 0x2f0(r29)
-/* 80372320 28030000 */ cmplwi r3, 0
-/* 80372324 4182003C */ beq- lbl_80372360
-/* 80372328 83A30008 */ lwz r29, 8(r3)
-lbl_8037232c:
-/* 8037232C 801D02CC */ lwz r0, 0x2cc(r29)
-/* 80372330 2C000000 */ cmpwi r0, 0x0
-/* 80372334 4181002C */ bgt- lbl_80372360
-/* 80372338 7FA3EB78 */ mr r3, r29
-/* 8037233C 4BFFF561 */ bl func_8037189c
-/* 80372340 801D02D0 */ lwz r0, 0x2d0(r29)
-/* 80372344 38830000 */ addi r4, r3, 0x0
-/* 80372348 7C002000 */ cmpw r0, r4
-/* 8037234C 41820014 */ beq- lbl_80372360
-/* 80372350 7FA3EB78 */ mr r3, r29
-/* 80372354 4BFFF585 */ bl func_803718d8
-/* 80372358 7C7D1B79 */ or. r29, r3, r3
-/* 8037235C 4082FFD0 */ bne+ lbl_8037232c
-lbl_80372360:
-/* 80372360 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 80372364 2C000000 */ cmpwi r0, 0x0
-/* 80372368 4182000C */ beq- lbl_80372374
-/* 8037236C 38600000 */ li r3, 0x0
-/* 80372370 4BFFF779 */ bl func_80371ae8
-lbl_80372374:
-/* 80372374 7FE3FB78 */ mr r3, r31
-/* 80372378 4BFFC785 */ bl func_8036eafc
-/* 8037237C 7FC3F378 */ mr r3, r30
-/* 80372380 8001002C */ lwz r0, 0x2c(r1)
-/* 80372384 83E10024 */ lwz r31, 0x24(r1)
-/* 80372388 83C10020 */ lwz r30, 0x20(r1)
-/* 8037238C 83A1001C */ lwz r29, 0x1c(r1)
-/* 80372390 38210028 */ addi r1, r1, 0x28
-/* 80372394 7C0803A6 */ mtlr r0
-/* 80372398 4E800020 */ blr
-.size func_80372114, . - func_80372114
-
-
-.global func_8037239c
-.type func_8037239c, @function
-func_8037239c:
-/* 8037239C 7C0802A6 */ mflr r0
-/* 803723A0 90010004 */ stw r0, 4(r1)
-/* 803723A4 9421FFE0 */ stwu r1, -0x20(r1)
-/* 803723A8 93E1001C */ stw r31, 0x1c(r1)
-/* 803723AC 93C10018 */ stw r30, 0x18(r1)
-/* 803723B0 93A10014 */ stw r29, 0x14(r1)
-/* 803723B4 7C7D1B78 */ mr r29, r3
-/* 803723B8 4BFFC71D */ bl func_8036ead4
-/* 803723BC 809D02CC */ lwz r4, 0x2cc(r29)
-/* 803723C0 3BE30000 */ addi r31, r3, 0x0
-/* 803723C4 38040001 */ addi r0, r4, 0x1
-/* 803723C8 7C9E2379 */ or. r30, r4, r4
-/* 803723CC 901D02CC */ stw r0, 0x2cc(r29)
-/* 803723D0 40820114 */ bne- lbl_803724e4
-/* 803723D4 A01D02C8 */ lhz r0, 0x2c8(r29)
-/* 803723D8 2C000003 */ cmpwi r0, 0x3
-/* 803723DC 418200F4 */ beq- lbl_803724d0
-/* 803723E0 40800014 */ bge- lbl_803723f4
-/* 803723E4 2C000001 */ cmpwi r0, 0x1
-/* 803723E8 41820028 */ beq- lbl_80372410
-/* 803723EC 40800014 */ bge- lbl_80372400
-/* 803723F0 480000E0 */ b lbl_803724d0
-lbl_803723f4:
-/* 803723F4 2C000005 */ cmpwi r0, 0x5
-/* 803723F8 408000D8 */ bge- lbl_803724d0
-/* 803723FC 48000020 */ b lbl_8037241c
-lbl_80372400:
-/* 80372400 38000001 */ li r0, 0x1
-/* 80372404 900DCA9C */ stw r0, lbl_805c68bc@sda21(0)
-/* 80372408 B01D02C8 */ sth r0, 0x2c8(r29)
-/* 8037240C 480000C4 */ b lbl_803724d0
-lbl_80372410:
-/* 80372410 7FA3EB78 */ mr r3, r29
-/* 80372414 4BFFF421 */ bl func_80371834
-/* 80372418 480000B8 */ b lbl_803724d0
-lbl_8037241c:
-/* 8037241C 809D02E0 */ lwz r4, 0x2e0(r29)
-/* 80372420 80BD02E4 */ lwz r5, 0x2e4(r29)
-/* 80372424 28040000 */ cmplwi r4, 0
-/* 80372428 40820010 */ bne- lbl_80372438
-/* 8037242C 807D02DC */ lwz r3, 0x2dc(r29)
-/* 80372430 90A30004 */ stw r5, 4(r3)
-/* 80372434 48000008 */ b lbl_8037243c
-lbl_80372438:
-/* 80372438 90A402E4 */ stw r5, 0x2e4(r4)
-lbl_8037243c:
-/* 8037243C 28050000 */ cmplwi r5, 0
-/* 80372440 40820010 */ bne- lbl_80372450
-/* 80372444 807D02DC */ lwz r3, 0x2dc(r29)
-/* 80372448 90830000 */ stw r4, 0(r3)
-/* 8037244C 48000008 */ b lbl_80372454
-lbl_80372450:
-/* 80372450 908502E0 */ stw r4, 0x2e0(r5)
-lbl_80372454:
-/* 80372454 38000020 */ li r0, 0x20
-/* 80372458 901D02D0 */ stw r0, 0x2d0(r29)
-/* 8037245C 809D02DC */ lwz r4, 0x2dc(r29)
-/* 80372460 80640004 */ lwz r3, 4(r4)
-/* 80372464 28030000 */ cmplwi r3, 0
-/* 80372468 4082000C */ bne- lbl_80372474
-/* 8037246C 93A40000 */ stw r29, 0(r4)
-/* 80372470 48000008 */ b lbl_80372478
-lbl_80372474:
-/* 80372474 93A302E0 */ stw r29, 0x2e0(r3)
-lbl_80372478:
-/* 80372478 907D02E4 */ stw r3, 0x2e4(r29)
-/* 8037247C 38000000 */ li r0, 0x0
-/* 80372480 901D02E0 */ stw r0, 0x2e0(r29)
-/* 80372484 807D02DC */ lwz r3, 0x2dc(r29)
-/* 80372488 93A30004 */ stw r29, 4(r3)
-/* 8037248C 807D02F0 */ lwz r3, 0x2f0(r29)
-/* 80372490 28030000 */ cmplwi r3, 0
-/* 80372494 4182003C */ beq- lbl_803724d0
-/* 80372498 83A30008 */ lwz r29, 8(r3)
-lbl_8037249c:
-/* 8037249C 801D02CC */ lwz r0, 0x2cc(r29)
-/* 803724A0 2C000000 */ cmpwi r0, 0x0
-/* 803724A4 4181002C */ bgt- lbl_803724d0
-/* 803724A8 7FA3EB78 */ mr r3, r29
-/* 803724AC 4BFFF3F1 */ bl func_8037189c
-/* 803724B0 801D02D0 */ lwz r0, 0x2d0(r29)
-/* 803724B4 38830000 */ addi r4, r3, 0x0
-/* 803724B8 7C002000 */ cmpw r0, r4
-/* 803724BC 41820014 */ beq- lbl_803724d0
-/* 803724C0 7FA3EB78 */ mr r3, r29
-/* 803724C4 4BFFF415 */ bl func_803718d8
-/* 803724C8 7C7D1B79 */ or. r29, r3, r3
-/* 803724CC 4082FFD0 */ bne+ lbl_8037249c
-lbl_803724d0:
-/* 803724D0 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 803724D4 2C000000 */ cmpwi r0, 0x0
-/* 803724D8 4182000C */ beq- lbl_803724e4
-/* 803724DC 38600000 */ li r3, 0x0
-/* 803724E0 4BFFF609 */ bl func_80371ae8
-lbl_803724e4:
-/* 803724E4 7FE3FB78 */ mr r3, r31
-/* 803724E8 4BFFC615 */ bl func_8036eafc
-/* 803724EC 7FC3F378 */ mr r3, r30
-/* 803724F0 80010024 */ lwz r0, 0x24(r1)
-/* 803724F4 83E1001C */ lwz r31, 0x1c(r1)
-/* 803724F8 83C10018 */ lwz r30, 0x18(r1)
-/* 803724FC 83A10014 */ lwz r29, 0x14(r1)
-/* 80372500 38210020 */ addi r1, r1, 0x20
-/* 80372504 7C0803A6 */ mtlr r0
-/* 80372508 4E800020 */ blr
-.size func_8037239c, . - func_8037239c
-
-
-.global func_8037250c
-.type func_8037250c, @function
-func_8037250c:
-/* 8037250C 7C0802A6 */ mflr r0
-/* 80372510 90010004 */ stw r0, 4(r1)
-/* 80372514 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80372518 93E10014 */ stw r31, 0x14(r1)
-/* 8037251C 93C10010 */ stw r30, 0x10(r1)
-/* 80372520 7C7E1B78 */ mr r30, r3
-/* 80372524 4BFFC5B1 */ bl func_8036ead4
-/* 80372528 3C808000 */ lis r4, 0x8000
-/* 8037252C 808400E4 */ lwz r4, 0xe4(r4)
-/* 80372530 38000004 */ li r0, 0x4
-/* 80372534 7C7F1B78 */ mr r31, r3
-/* 80372538 B00402C8 */ sth r0, 0x2c8(r4)
-/* 8037253C 93C402DC */ stw r30, 0x2dc(r4)
-/* 80372540 80BE0000 */ lwz r5, 0(r30)
-/* 80372544 48000008 */ b lbl_8037254c
-lbl_80372548:
-/* 80372548 80A502E0 */ lwz r5, 0x2e0(r5)
-lbl_8037254c:
-/* 8037254C 28050000 */ cmplwi r5, 0
-/* 80372550 41820014 */ beq- lbl_80372564
-/* 80372554 806502D0 */ lwz r3, 0x2d0(r5)
-/* 80372558 800402D0 */ lwz r0, 0x2d0(r4)
-/* 8037255C 7C030000 */ cmpw r3, r0
-/* 80372560 4081FFE8 */ ble+ lbl_80372548
-lbl_80372564:
-/* 80372564 28050000 */ cmplwi r5, 0
-/* 80372568 40820030 */ bne- lbl_80372598
-/* 8037256C 807E0004 */ lwz r3, 4(r30)
-/* 80372570 28030000 */ cmplwi r3, 0
-/* 80372574 4082000C */ bne- lbl_80372580
-/* 80372578 909E0000 */ stw r4, 0(r30)
-/* 8037257C 48000008 */ b lbl_80372584
-lbl_80372580:
-/* 80372580 908302E0 */ stw r4, 0x2e0(r3)
-lbl_80372584:
-/* 80372584 906402E4 */ stw r3, 0x2e4(r4)
-/* 80372588 38000000 */ li r0, 0x0
-/* 8037258C 900402E0 */ stw r0, 0x2e0(r4)
-/* 80372590 909E0004 */ stw r4, 4(r30)
-/* 80372594 48000028 */ b lbl_803725bc
-lbl_80372598:
-/* 80372598 90A402E0 */ stw r5, 0x2e0(r4)
-/* 8037259C 806502E4 */ lwz r3, 0x2e4(r5)
-/* 803725A0 908502E4 */ stw r4, 0x2e4(r5)
-/* 803725A4 28030000 */ cmplwi r3, 0
-/* 803725A8 906402E4 */ stw r3, 0x2e4(r4)
-/* 803725AC 4082000C */ bne- lbl_803725b8
-/* 803725B0 909E0000 */ stw r4, 0(r30)
-/* 803725B4 48000008 */ b lbl_803725bc
-lbl_803725b8:
-/* 803725B8 908302E0 */ stw r4, 0x2e0(r3)
-lbl_803725bc:
-/* 803725BC 38000001 */ li r0, 0x1
-/* 803725C0 900DCA9C */ stw r0, lbl_805c68bc@sda21(0)
-/* 803725C4 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 803725C8 2C000000 */ cmpwi r0, 0x0
-/* 803725CC 4182000C */ beq- lbl_803725d8
-/* 803725D0 38600000 */ li r3, 0x0
-/* 803725D4 4BFFF515 */ bl func_80371ae8
-lbl_803725d8:
-/* 803725D8 7FE3FB78 */ mr r3, r31
-/* 803725DC 4BFFC521 */ bl func_8036eafc
-/* 803725E0 8001001C */ lwz r0, 0x1c(r1)
-/* 803725E4 83E10014 */ lwz r31, 0x14(r1)
-/* 803725E8 83C10010 */ lwz r30, 0x10(r1)
-/* 803725EC 38210018 */ addi r1, r1, 0x18
-/* 803725F0 7C0803A6 */ mtlr r0
-/* 803725F4 4E800020 */ blr
-.size func_8037250c, . - func_8037250c
-
-
-.global func_803725f8
-.type func_803725f8, @function
-func_803725f8:
-/* 803725F8 7C0802A6 */ mflr r0
-/* 803725FC 90010004 */ stw r0, 4(r1)
-/* 80372600 9421FFE8 */ stwu r1, -0x18(r1)
-/* 80372604 93E10014 */ stw r31, 0x14(r1)
-/* 80372608 93C10010 */ stw r30, 0x10(r1)
-/* 8037260C 7C7E1B78 */ mr r30, r3
-/* 80372610 4BFFC4C5 */ bl func_8036ead4
-/* 80372614 3C808054 */ lis r4, lbl_8053ecf8@ha
-/* 80372618 3BE30000 */ addi r31, r3, 0x0
-/* 8037261C 38A4ECF8 */ addi r5, r4, lbl_8053ecf8@l
-/* 80372620 4800009C */ b lbl_803726bc
-lbl_80372624:
-/* 80372624 806602E0 */ lwz r3, 0x2e0(r6)
-/* 80372628 28030000 */ cmplwi r3, 0
-/* 8037262C 40820010 */ bne- lbl_8037263c
-/* 80372630 38000000 */ li r0, 0x0
-/* 80372634 901E0004 */ stw r0, 4(r30)
-/* 80372638 4800000C */ b lbl_80372644
-lbl_8037263c:
-/* 8037263C 38000000 */ li r0, 0x0
-/* 80372640 900302E4 */ stw r0, 0x2e4(r3)
-lbl_80372644:
-/* 80372644 907E0000 */ stw r3, 0(r30)
-/* 80372648 38000001 */ li r0, 0x1
-/* 8037264C B00602C8 */ sth r0, 0x2c8(r6)
-/* 80372650 800602CC */ lwz r0, 0x2cc(r6)
-/* 80372654 2C000000 */ cmpwi r0, 0x0
-/* 80372658 41810064 */ bgt- lbl_803726bc
-/* 8037265C 800602D0 */ lwz r0, 0x2d0(r6)
-/* 80372660 54001838 */ slwi r0, r0, 3
-/* 80372664 7C050214 */ add r0, r5, r0
-/* 80372668 900602DC */ stw r0, 0x2dc(r6)
-/* 8037266C 808602DC */ lwz r4, 0x2dc(r6)
-/* 80372670 80640004 */ lwz r3, 4(r4)
-/* 80372674 28030000 */ cmplwi r3, 0
-/* 80372678 4082000C */ bne- lbl_80372684
-/* 8037267C 90C40000 */ stw r6, 0(r4)
-/* 80372680 48000008 */ b lbl_80372688
-lbl_80372684:
-/* 80372684 90C302E0 */ stw r6, 0x2e0(r3)
-lbl_80372688:
-/* 80372688 906602E4 */ stw r3, 0x2e4(r6)
-/* 8037268C 38000000 */ li r0, 0x0
-/* 80372690 38600001 */ li r3, 0x1
-/* 80372694 900602E0 */ stw r0, 0x2e0(r6)
-/* 80372698 808602DC */ lwz r4, 0x2dc(r6)
-/* 8037269C 90C40004 */ stw r6, 4(r4)
-/* 803726A0 800602D0 */ lwz r0, 0x2d0(r6)
-/* 803726A4 808DCA98 */ lwz r4, lbl_805c68b8@sda21(0)
-/* 803726A8 2000001F */ subfic r0, r0, 0x1f
-/* 803726AC 7C600030 */ slw r0, r3, r0
-/* 803726B0 7C800378 */ or r0, r4, r0
-/* 803726B4 900DCA98 */ stw r0, lbl_805c68b8@sda21(0)
-/* 803726B8 906DCA9C */ stw r3, lbl_805c68bc@sda21(0)
-lbl_803726bc:
-/* 803726BC 80DE0000 */ lwz r6, 0(r30)
-/* 803726C0 28060000 */ cmplwi r6, 0
-/* 803726C4 4082FF60 */ bne+ lbl_80372624
-/* 803726C8 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 803726CC 2C000000 */ cmpwi r0, 0x0
-/* 803726D0 4182000C */ beq- lbl_803726dc
-/* 803726D4 38600000 */ li r3, 0x0
-/* 803726D8 4BFFF411 */ bl func_80371ae8
-lbl_803726dc:
-/* 803726DC 7FE3FB78 */ mr r3, r31
-/* 803726E0 4BFFC41D */ bl func_8036eafc
-/* 803726E4 8001001C */ lwz r0, 0x1c(r1)
-/* 803726E8 83E10014 */ lwz r31, 0x14(r1)
-/* 803726EC 83C10010 */ lwz r30, 0x10(r1)
-/* 803726F0 38210018 */ addi r1, r1, 0x18
-/* 803726F4 7C0803A6 */ mtlr r0
-/* 803726F8 4E800020 */ blr
-.size func_803725f8, . - func_803725f8
-
-
-.global func_803726fc
-.type func_803726fc, @function
-func_803726fc:
-/* 803726FC 7C0802A6 */ mflr r0
-/* 80372700 90010004 */ stw r0, 4(r1)
-/* 80372704 9421FFE0 */ stwu r1, -0x20(r1)
-/* 80372708 93E1001C */ stw r31, 0x1c(r1)
-/* 8037270C 7C9F2379 */ or. r31, r4, r4
-/* 80372710 93C10018 */ stw r30, 0x18(r1)
-/* 80372714 93A10014 */ stw r29, 0x14(r1)
-/* 80372718 3BA30000 */ addi r29, r3, 0x0
-/* 8037271C 4180000C */ blt- lbl_80372728
-/* 80372720 2C1F001F */ cmpwi r31, 0x1f
-/* 80372724 4081000C */ ble- lbl_80372730
-lbl_80372728:
-/* 80372728 38600000 */ li r3, 0x0
-/* 8037272C 48000074 */ b lbl_803727a0
-lbl_80372730:
-/* 80372730 4BFFC3A5 */ bl func_8036ead4
-/* 80372734 801D02D4 */ lwz r0, 0x2d4(r29)
-/* 80372738 3BC30000 */ addi r30, r3, 0x0
-/* 8037273C 7C00F800 */ cmpw r0, r31
-/* 80372740 41820054 */ beq- lbl_80372794
-/* 80372744 93FD02D4 */ stw r31, 0x2d4(r29)
-/* 80372748 7FBFEB78 */ mr r31, r29
-lbl_8037274c:
-/* 8037274C 801F02CC */ lwz r0, 0x2cc(r31)
-/* 80372750 2C000000 */ cmpwi r0, 0x0
-/* 80372754 4181002C */ bgt- lbl_80372780
-/* 80372758 7FE3FB78 */ mr r3, r31
-/* 8037275C 4BFFF141 */ bl func_8037189c
-/* 80372760 801F02D0 */ lwz r0, 0x2d0(r31)
-/* 80372764 38830000 */ addi r4, r3, 0x0
-/* 80372768 7C002000 */ cmpw r0, r4
-/* 8037276C 41820014 */ beq- lbl_80372780
-/* 80372770 7FE3FB78 */ mr r3, r31
-/* 80372774 4BFFF165 */ bl func_803718d8
-/* 80372778 7C7F1B79 */ or. r31, r3, r3
-/* 8037277C 4082FFD0 */ bne+ lbl_8037274c
-lbl_80372780:
-/* 80372780 800DCA9C */ lwz r0, lbl_805c68bc@sda21(0)
-/* 80372784 2C000000 */ cmpwi r0, 0x0
-/* 80372788 4182000C */ beq- lbl_80372794
-/* 8037278C 38600000 */ li r3, 0x0
-/* 80372790 4BFFF359 */ bl func_80371ae8
-lbl_80372794:
-/* 80372794 7FC3F378 */ mr r3, r30
-/* 80372798 4BFFC365 */ bl func_8036eafc
-/* 8037279C 38600001 */ li r3, 0x1
-lbl_803727a0:
-/* 803727A0 80010024 */ lwz r0, 0x24(r1)
-/* 803727A4 83E1001C */ lwz r31, 0x1c(r1)
-/* 803727A8 83C10018 */ lwz r30, 0x18(r1)
-/* 803727AC 83A10014 */ lwz r29, 0x14(r1)
-/* 803727B0 38210020 */ addi r1, r1, 0x20
-/* 803727B4 7C0803A6 */ mtlr r0
-/* 803727B8 4E800020 */ blr
-.size func_803726fc, . - func_803726fc
-
-
-.global func_803727bc
-.type func_803727bc, @function
-func_803727bc:
-/* 803727BC 806302D4 */ lwz r3, 0x2d4(r3)
-/* 803727C0 4E800020 */ blr
-.size func_803727bc, . - func_803727bc
-
diff --git a/asm/Dolphin/os/OSTime-data.s b/asm/Dolphin/os/OSTime-data.s
deleted file mode 100644
index dc26c61..0000000
--- a/asm/Dolphin/os/OSTime-data.s
+++ /dev/null
@@ -1,41 +0,0 @@
-.include "macros.inc"
-
-.section .data
-
-.balign 8
-
-.global lbl_804ef5a8
-.type lbl_804ef5a8, @object
-lbl_804ef5a8:
-/* 804EF5A8 00000000 */ .4byte 0x00000000
-/* 804EF5AC 0000001F */ .4byte 0x0000001f
-/* 804EF5B0 0000003B */ .4byte 0x0000003b
-/* 804EF5B4 0000005A */ .4byte 0x0000005a
-/* 804EF5B8 00000078 */ .4byte 0x00000078
-/* 804EF5BC 00000097 */ .4byte 0x00000097
-/* 804EF5C0 000000B5 */ .4byte 0x000000b5
-/* 804EF5C4 000000D4 */ .4byte 0x000000d4
-/* 804EF5C8 000000F3 */ .4byte 0x000000f3
-/* 804EF5CC 00000111 */ .4byte 0x00000111
-/* 804EF5D0 00000130 */ .4byte 0x00000130
-/* 804EF5D4 0000014E */ .4byte 0x0000014e
-.size lbl_804ef5a8, . - lbl_804ef5a8
-
-
-.global lbl_804ef5d8
-.type lbl_804ef5d8, @object
-lbl_804ef5d8:
-/* 804EF5D8 00000000 */ .4byte 0x00000000
-/* 804EF5DC 0000001F */ .4byte 0x0000001f
-/* 804EF5E0 0000003C */ .4byte 0x0000003c
-/* 804EF5E4 0000005B */ .4byte 0x0000005b
-/* 804EF5E8 00000079 */ .4byte 0x00000079
-/* 804EF5EC 00000098 */ .4byte 0x00000098
-/* 804EF5F0 000000B6 */ .4byte 0x000000b6
-/* 804EF5F4 000000D5 */ .4byte 0x000000d5
-/* 804EF5F8 000000F4 */ .4byte 0x000000f4
-/* 804EF5FC 00000112 */ .4byte 0x00000112
-/* 804EF600 00000131 */ .4byte 0x00000131
-/* 804EF604 0000014F */ .4byte 0x0000014f
-.size lbl_804ef5d8, . - lbl_804ef5d8
-
diff --git a/asm/Dolphin/os/OSTime.s b/asm/Dolphin/os/OSTime.s
deleted file mode 100644
index f12669d..0000000
--- a/asm/Dolphin/os/OSTime.s
+++ /dev/null
@@ -1,312 +0,0 @@
-.include "macros.inc"
-
-.section .text
-
-.global func_803727c4
-.type func_803727c4, @function
-func_803727c4:
-/* 803727C4 7C6D42E6 */ mftbu r3
-/* 803727C8 7C8C42E6 */ mftb r4, 0x10c
-/* 803727CC 7CAD42E6 */ mftbu r5
-/* 803727D0 7C032800 */ cmpw r3, r5
-/* 803727D4 4082FFF0 */ bne- func_803727c4
-/* 803727D8 4E800020 */ blr
-.size func_803727c4, . - func_803727c4
-
-
-.global func_803727dc
-.type func_803727dc, @function
-func_803727dc:
-/* 803727DC 7C6C42E6 */ mftb r3, 0x10c
-/* 803727E0 4E800020 */ blr
-.size func_803727dc, . - func_803727dc
-
-
-.global func_803727e4
-.type func_803727e4, @function
-func_803727e4:
-/* 803727E4 7C0802A6 */ mflr r0
-/* 803727E8 90010004 */ stw r0, 4(r1)
-/* 803727EC 9421FFE0 */ stwu r1, -0x20(r1)
-/* 803727F0 93E1001C */ stw r31, 0x1c(r1)
-/* 803727F4 93C10018 */ stw r30, 0x18(r1)
-/* 803727F8 93A10014 */ stw r29, 0x14(r1)
-/* 803727FC 4BFFC2D9 */ bl func_8036ead4
-/* 80372800 7C7F1B78 */ mr r31, r3
-/* 80372804 4BFFFFC1 */ bl func_803727c4
-/* 80372808 3CC08000 */ lis r6, 0x8000
-/* 8037280C 80A630DC */ lwz r5, 0x30dc(r6)
-/* 80372810 800630D8 */ lwz r0, 0x30d8(r6)
-/* 80372814 7FA52014 */ addc r29, r5, r4
-/* 80372818 7FC01914 */ adde r30, r0, r3
-/* 8037281C 7FE3FB78 */ mr r3, r31
-/* 80372820 4BFFC2DD */ bl func_8036eafc
-/* 80372824 7FA4EB78 */ mr r4, r29
-/* 80372828 7FC3F378 */ mr r3, r30
-/* 8037282C 80010024 */ lwz r0, 0x24(r1)
-/* 80372830 83E1001C */ lwz r31, 0x1c(r1)
-/* 80372834 83C10018 */ lwz r30, 0x18(r1)
-/* 80372838 83A10014 */ lwz r29, 0x14(r1)
-/* 8037283C 38210020 */ addi r1, r1, 0x20
-/* 80372840 7C0803A6 */ mtlr r0
-/* 80372844 4E800020 */ blr
-.size func_803727e4, . - func_803727e4
-
-
-.global func_80372848
-.type func_80372848, @function
-func_80372848:
-/* 80372848 3CA09249 */ lis r5, 0x9249
-/* 8037284C 38052493 */ addi r0, r5, 0x2493
-/* 80372850 38E30006 */ addi r7, r3, 0x6
-/* 80372854 7CC03896 */ mulhw r6, r0, r7
-/* 80372858 3CA0B38D */ lis r5, 0xb38d
-/* 8037285C 3805F9B1 */ addi r0, r5, -0x64f
-/* 80372860 7C001896 */ mulhw r0, r0, r3
-/* 80372864 7CA63A14 */ add r5, r6, r7
-/* 80372868 7CA51670 */ srawi r5, r5, 2
-/* 8037286C 54A60FFE */ srwi r6, r5, 0x1f
-/* 80372870 7CA53214 */ add r5, r5, r6
-/* 80372874 7C001A14 */ add r0, r0, r3
-/* 80372878 1CC50007 */ mulli r6, r5, 0x7
-/* 8037287C 7C004670 */ srawi r0, r0, 8
-/* 80372880 54050FFE */ srwi r5, r0, 0x1f
-/* 80372884 7CA02A14 */ add r5, r0, r5
-/* 80372888 7C063850 */ subf r0, r6, r7
-/* 8037288C 1D65016D */ mulli r11, r5, 0x16d
-/* 80372890 90040018 */ stw r0, 0x18(r4)
-/* 80372894 48000004 */ b lbl_80372898
-lbl_80372898:
-/* 80372898 3CC051EC */ lis r6, 0x51ec
-/* 8037289C 3946851F */ addi r10, r6, -0x7ae1
-/* 803728A0 48000004 */ b lbl_803728a4
-lbl_803728a4:
-/* 803728A4 4800000C */ b lbl_803728b0
-lbl_803728a8:
-/* 803728A8 396BFE93 */ addi r11, r11, -0x16d
-/* 803728AC 38A5FFFF */ addi r5, r5, -0x1
-lbl_803728b0:
-/* 803728B0 2C050001 */ cmpwi r5, 0x1
-/* 803728B4 4080000C */ bge- lbl_803728c0
-/* 803728B8 38000000 */ li r0, 0x0
-/* 803728BC 48000038 */ b lbl_803728f4
-lbl_803728c0:
-/* 803728C0 3805FFFF */ addi r0, r5, -0x1
-/* 803728C4 7C0A0096 */ mulhw r0, r10, r0
-/* 803728C8 7C083E70 */ srawi r8, r0, 7
-/* 803728CC 7C062E70 */ srawi r6, r0, 5
-/* 803728D0 38050003 */ addi r0, r5, 0x3
-/* 803728D4 54C70FFE */ srwi r7, r6, 0x1f
-/* 803728D8 7C001670 */ srawi r0, r0, 2
-/* 803728DC 55090FFE */ srwi r9, r8, 0x1f
-/* 803728E0 7CC63A14 */ add r6, r6, r7
-/* 803728E4 7C000194 */ addze r0, r0
-/* 803728E8 7CE84A14 */ add r7, r8, r9
-/* 803728EC 7C060050 */ subf r0, r6, r0
-/* 803728F0 7C070214 */ add r0, r7, r0
-lbl_803728f4:
-/* 803728F4 7C0B0214 */ add r0, r11, r0
-/* 803728F8 7C030000 */ cmpw r3, r0
-/* 803728FC 4180FFAC */ blt+ lbl_803728a8
-/* 80372900 7CA61670 */ srawi r6, r5, 2
-/* 80372904 90A40014 */ stw r5, 0x14(r4)
-/* 80372908 7CC60194 */ addze r6, r6
-/* 8037290C 54C6103A */ slwi r6, r6, 2
-/* 80372910 7CC62810 */ subfc r6, r6, r5
-/* 80372914 7C001850 */ subf r0, r0, r3
-/* 80372918 2C060000 */ cmpwi r6, 0x0
-/* 8037291C 9004001C */ stw r0, 0x1c(r4)
-/* 80372920 38E00001 */ li r7, 0x1
-/* 80372924 39000000 */ li r8, 0x0
-/* 80372928 40820030 */ bne- lbl_80372958
-/* 8037292C 3C6051EC */ lis r3, 0x51ec
-/* 80372930 3863851F */ addi r3, r3, -0x7ae1
-/* 80372934 7C632896 */ mulhw r3, r3, r5
-/* 80372938 7C632E70 */ srawi r3, r3, 5
-/* 8037293C 54660FFE */ srwi r6, r3, 0x1f
-/* 80372940 7C633214 */ add r3, r3, r6
-/* 80372944 1C630064 */ mulli r3, r3, 0x64
-/* 80372948 7C632850 */ subf r3, r3, r5
-/* 8037294C 2C030000 */ cmpwi r3, 0x0
-/* 80372950 41820008 */ beq- lbl_80372958
-/* 80372954 7CE83B78 */ mr r8, r7
-lbl_80372958:
-/* 80372958 2C080000 */ cmpwi r8, 0x0
-/* 8037295C 40820030 */ bne- lbl_8037298c
-/* 80372960 3C6051EC */ lis r3, 0x51ec
-/* 80372964 3863851F */ addi r3, r3, -0x7ae1
-/* 80372968 7C632896 */ mulhw r3, r3, r5
-/* 8037296C 7C633E70 */ srawi r3, r3, 7
-/* 80372970 54660FFE */ srwi r6, r3, 0x1f
-/* 80372974 7C633214 */ add r3, r3, r6
-/* 80372978 1C630190 */ mulli r3, r3, 0x190
-/* 8037297C 7C632850 */ subf r3, r3, r5
-/* 80372980 2C030000 */ cmpwi r3, 0x0
-/* 80372984 41820008 */ beq- lbl_8037298c
-/* 80372988 38E00000 */ li r7, 0x0
-lbl_8037298c:
-/* 8037298C 2C070000 */ cmpwi r7, 0x0
-/* 80372990 41820010 */ beq- lbl_803729a0
-/* 80372994 3C60804F */ lis r3, lbl_804ef5d8@ha
-/* 80372998 38C3F5D8 */ addi r6, r3, lbl_804ef5d8@l
-/* 8037299C 4800000C */ b lbl_803729a8
-lbl_803729a0:
-/* 803729A0 3C60804F */ lis r3, lbl_804ef5a8@ha
-/* 803729A4 38C3F5A8 */ addi r6, r3, lbl_804ef5a8@l
-lbl_803729a8:
-/* 803729A8 38E0000C */ li r7, 0xc
-/* 803729AC 38600030 */ li r3, 0x30
-/* 803729B0 48000004 */ b lbl_803729b4
-lbl_803729b4:
-/* 803729B4 48000004 */ b lbl_803729b8
-lbl_803729b8:
-/* 803729B8 3863FFFC */ addi r3, r3, -0x4
-/* 803729BC 7CA6182E */ lwzx r5, r6, r3
-/* 803729C0 38E7FFFF */ addi r7, r7, -0x1
-/* 803729C4 7C002800 */ cmpw r0, r5
-/* 803729C8 4180FFF0 */ blt+ lbl_803729b8
-/* 803729CC 90E40010 */ stw r7, 0x10(r4)
-/* 803729D0 7C66182E */ lwzx r3, r6, r3
-/* 803729D4 7C630050 */ subf r3, r3, r0
-/* 803729D8 38030001 */ addi r0, r3, 0x1
-/* 803729DC 9004000C */ stw r0, 0xc(r4)
-/* 803729E0 4E800020 */ blr
-.size func_80372848, . - func_80372848
-
-
-.global func_803729e4
-.type func_803729e4, @function
-func_803729e4:
-/* 803729E4 7C0802A6 */ mflr r0
-/* 803729E8 90010004 */ stw r0, 4(r1)
-/* 803729EC 9421FFC8 */ stwu r1, -0x38(r1)
-/* 803729F0 BF21001C */ stmw r25, 0x1c(r1)
-/* 803729F4 7C7D1B78 */ mr r29, r3
-/* 803729F8 7C9E2378 */ mr r30, r4
-/* 803729FC 7CBF2B78 */ mr r31, r5
-/* 80372A00 3F608000 */ lis r27, 0x8000
-/* 80372A04 801B00F8 */ lwz r0, 0xf8(r27)
-/* 80372A08 7FA3EB78 */ mr r3, r29
-/* 80372A0C 7FC4F378 */ mr r4, r30
-/* 80372A10 5406F0BE */ srwi r6, r0, 2
-/* 80372A14 38A00000 */ li r5, 0x0
-/* 80372A18 48020DB5 */ bl func_803937cc
-/* 80372A1C 7C7A1B78 */ mr r26, r3
-/* 80372A20 38A00000 */ li r5, 0x0
-/* 80372A24 7C992378 */ mr r25, r4
-/* 80372A28 6F448000 */ xoris r4, r26, 0x8000
-/* 80372A2C 6CA38000 */ xoris r3, r5, 0x8000
-/* 80372A30 7C05C810 */ subfc r0, r5, r25
-/* 80372A34 7C632110 */ subfe r3, r3, r4
-/* 80372A38 7C642110 */ subfe r3, r4, r4
-/* 80372A3C 7C6300D0 */ neg r3, r3
-/* 80372A40 2C030000 */ cmpwi r3, 0x0
-/* 80372A44 41820014 */ beq- lbl_80372a58
-/* 80372A48 801B00F8 */ lwz r0, 0xf8(r27)
-/* 80372A4C 5400F0BE */ srwi r0, r0, 2
-/* 80372A50 7F390014 */ addc r25, r25, r0
-/* 80372A54 7F5A2914 */ adde r26, r26, r5
-lbl_80372a58:
-/* 80372A58 38800008 */ li r4, 0x8
-/* 80372A5C 7C7A21D6 */ mullw r3, r26, r4
-/* 80372A60 7C192016 */ mulhwu r0, r25, r4
-/* 80372A64 3F608000 */ lis r27, 0x8000
-/* 80372A68 80DB00F8 */ lwz r6, 0xf8(r27)
-/* 80372A6C 3CA0431C */ lis r5, 0x431c
-/* 80372A70 38A5DE83 */ addi r5, r5, -0x217d
-/* 80372A74 54C6F0BE */ srwi r6, r6, 2
-/* 80372A78 7CA53016 */ mulhwu r5, r5, r6
-/* 80372A7C 54A68BFE */ srwi r6, r5, 0xf
-/* 80372A80 3B800000 */ li r28, 0x0
-/* 80372A84 7C630214 */ add r3, r3, r0
-/* 80372A88 7C19E1D6 */ mullw r0, r25, r28
-/* 80372A8C 7C9921D6 */ mullw r4, r25, r4
-/* 80372A90 7C630214 */ add r3, r3, r0
-/* 80372A94 38A00000 */ li r5, 0x0
-/* 80372A98 48020B19 */ bl func_803935b0
-/* 80372A9C 38A00000 */ li r5, 0x0
-/* 80372AA0 38C003E8 */ li r6, 0x3e8
-/* 80372AA4 48020D29 */ bl func_803937cc
-/* 80372AA8 909F0024 */ stw r4, 0x24(r31)
-/* 80372AAC 3C601062 */ lis r3, 0x1062
-/* 80372AB0 38A34DD3 */ addi r5, r3, 0x4dd3
-/* 80372AB4 801B00F8 */ lwz r0, 0xf8(r27)
-/* 80372AB8 7F43D378 */ mr r3, r26
-/* 80372ABC 7F24CB78 */ mr r4, r25
-/* 80372AC0 5400F0BE */ srwi r0, r0, 2
-/* 80372AC4 7C050016 */ mulhwu r0, r5, r0
-/* 80372AC8 5406D1BE */ srwi r6, r0, 6
-/* 80372ACC 38A00000 */ li r5, 0x0
-/* 80372AD0 48020AE1 */ bl func_803935b0
-/* 80372AD4 38A00000 */ li r5, 0x0
-/* 80372AD8 38C003E8 */ li r6, 0x3e8
-/* 80372ADC 48020CF1 */ bl func_803937cc
-/* 80372AE0 909F0020 */ stw r4, 0x20(r31)
-/* 80372AE4 7FD9F010 */ subfc r30, r25, r30
-/* 80372AE8 7FBAE910 */ subfe r29, r26, r29
-/* 80372AEC 801B00F8 */ lwz r0, 0xf8(r27)
-/* 80372AF0 3CA00001 */ lis r5, 1
-/* 80372AF4 3B255180 */ addi r25, r5, 0x5180
-/* 80372AF8 7FA3EB78 */ mr r3, r29
-/* 80372AFC 5406F0BE */ srwi r6, r0, 2
-/* 80372B00 7FC4F378 */ mr r4, r30
-/* 80372B04 38A00000 */ li r5, 0x0
-/* 80372B08 48020AA9 */ bl func_803935b0
-/* 80372B0C 7F26CB78 */ mr r6, r25
-/* 80372B10 38A00000 */ li r5, 0x0
-/* 80372B14 48020A9D */ bl func_803935b0
-/* 80372B18 3CA0000B */ lis r5, 0xb
-/* 80372B1C 801B00F8 */ lwz r0, 0xf8(r27)
-/* 80372B20 38A52575 */ addi r5, r5, 0x2575
-/* 80372B24 7F442814 */ addc r26, r4, r5
-/* 80372B28 5406F0BE */ srwi r6, r0, 2
-/* 80372B2C 7C03E114 */ adde r0, r3, r28
-/* 80372B30 7FA3EB78 */ mr r3, r29
-/* 80372B34 7FC4F378 */ mr r4, r30
-/* 80372B38 38A00000 */ li r5, 0x0
-/* 80372B3C 48020A75 */ bl func_803935b0
-/* 80372B40 7F26CB78 */ mr r6, r25
-/* 80372B44 38A00000 */ li r5, 0x0
-/* 80372B48 48020C85 */ bl func_803937cc
-/* 80372B4C 7C9B2378 */ mr r27, r4
-/* 80372B50 2C1B0000 */ cmpwi r27, 0x0
-/* 80372B54 40800010 */ bge- lbl_80372b64
-/* 80372B58 3F7B0001 */ addis r27, r27, 1
-/* 80372B5C 3B5AFFFF */ addi r26, r26, -0x1
-/* 80372B60 3B7B5180 */ addi r27, r27, 0x5180
-lbl_80372b64:
-/* 80372B64 7F43D378 */ mr r3, r26
-/* 80372B68 7FE4FB78 */ mr r4, r31
-/* 80372B6C 4BFFFCDD */ bl func_80372848
-/* 80372B70 3C608889 */ lis r3, 0x8889
-/* 80372B74 38A38889 */ addi r5, r3, -0x7777
-/* 80372B78 7C05D896 */ mulhw r0, r5, r27
-/* 80372B7C 7C80DA14 */ add r4, r0, r27
-/* 80372B80 7C802E70 */ srawi r0, r4, 5
-/* 80372B84 54030FFE */ srwi r3, r0, 0x1f
-/* 80372B88 7CE01A14 */ add r7, r0, r3
-/* 80372B8C 7C053896 */ mulhw r0, r5, r7
-/* 80372B90 7C003A14 */ add r0, r0, r7
-/* 80372B94 7C052E70 */ srawi r5, r0, 5
-/* 80372B98 7C002E70 */ srawi r0, r0, 5
-/* 80372B9C 54030FFE */ srwi r3, r0, 0x1f
-/* 80372BA0 7C601A14 */ add r3, r0, r3
-/* 80372BA4 7C802E70 */ srawi r0, r4, 5
-/* 80372BA8 54A60FFE */ srwi r6, r5, 0x1f
-/* 80372BAC 1C83003C */ mulli r4, r3, 0x3c
-/* 80372BB0 54030FFE */ srwi r3, r0, 0x1f
-/* 80372BB4 7CA53214 */ add r5, r5, r6
-/* 80372BB8 7C001A14 */ add r0, r0, r3
-/* 80372BBC 90BF0008 */ stw r5, 8(r31)
-/* 80372BC0 1C00003C */ mulli r0, r0, 0x3c
-/* 80372BC4 7C643850 */ subf r3, r4, r7
-/* 80372BC8 907F0004 */ stw r3, 4(r31)
-/* 80372BCC 7C00D850 */ subf r0, r0, r27
-/* 80372BD0 901F0000 */ stw r0, 0(r31)
-/* 80372BD4 BB21001C */ lmw r25, 0x1c(r1)
-/* 80372BD8 8001003C */ lwz r0, 0x3c(r1)
-/* 80372BDC 38210038 */ addi r1, r1, 0x38
-/* 80372BE0 7C0803A6 */ mtlr r0
-/* 80372BE4 4E800020 */ blr
-.size func_803729e4, . - func_803729e4
-
diff --git a/include/asm_types.h b/include/asm_types.h
new file mode 100644
index 0000000..d2870dc
--- /dev/null
+++ b/include/asm_types.h
@@ -0,0 +1,86 @@
+// This file was taken from the Metroid Prime decompilation project.
+// https://github.com/PrimeDecomp/prime/blob/main/include/asm_types.h
+#ifndef _ASM_TYPES
+#define _ASM_TYPES
+
+// Special Purpose Registers (SPRs)
+#define XER 1
+#define LR 8
+#define CTR 9
+#define DSISR 18
+#define DAR 19
+#define DEC 22
+#define SDR1 25
+#define SRR0 26
+#define SRR1 27
+#define SPRG0 272
+#define SPRG1 273
+#define SPRG2 274
+#define SPRG3 275
+#define EAR 282
+#define PVR 287
+#define IBAT0U 528
+#define IBAT0L 529
+#define IBAT1U 530
+#define IBAT1L 531
+#define IBAT2U 532
+#define IBAT2L 533
+#define IBAT3U 534
+#define IBAT3L 535
+#define DBAT0U 536
+#define DBAT0L 537
+#define DBAT1U 538
+#define DBAT1L 539
+#define DBAT2U 540
+#define DBAT2L 541
+#define DBAT3U 542
+#define DBAT3L 543
+#define GQR0 912
+#define GQR1 913
+#define GQR2 914
+#define GQR3 915
+#define GQR4 916
+#define GQR5 917
+#define GQR6 918
+#define GQR7 919
+#define HID2 920
+#define WPAR 921
+#define DMA_U 922
+#define DMA_L 923
+#define UMMCR0 936
+#define UPMC1 937
+#define UPMC2 938
+#define USIA 939
+#define UMMCR1 940
+#define UPMC3 941
+#define UPMC4 942
+#define USDA 943
+#define MMCR0 952
+#define PMC1 953
+#define PMC2 954
+#define SIA 955
+#define MMCR1 956
+#define PMC3 957
+#define PMC4 958
+#define SDA 959
+#define HID0 1008
+#define HID1 1009
+#define IABR 1010
+#define DABR 1013
+#define L2CR 1017
+#define ICTC 1019
+#define THRM1 1020
+#define THRM2 1021
+#define THRM3 1022
+
+// Condition Registers (CRs)
+#define cr0 0
+#define cr1 1
+#define cr2 2
+#define cr3 3
+#define cr4 4
+#define cr5 5
+#define cr6 6
+#define cr7 7
+
+#endif // _ASM_TYPES
diff --git a/include/dolphin/CARDPriv.h b/include/dolphin/CARDPriv.h
new file mode 100644
index 0000000..ca28f6e
--- /dev/null
+++ b/include/dolphin/CARDPriv.h
@@ -0,0 +1,132 @@
+#ifndef _DOLPHIN_CARDPRIV
+#define _DOLPHIN_CARDPRIV
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CARD_FAT_AVAIL 0x0000u
+#define CARD_FAT_CHECKSUM 0x0000u
+#define CARD_FAT_CHECKSUMINV 0x0001u
+#define CARD_FAT_CHECKCODE 0x0002u
+#define CARD_FAT_FREEBLOCKS 0x0003u
+#define CARD_FAT_LASTSLOT 0x0004u
+
+#define CARD_PAGE_SIZE 128u
+#define CARD_SEG_SIZE 512u
+
+#define CARD_NUM_SYSTEM_BLOCK 5
+#define CARD_SYSTEM_BLOCK_SIZE (8 * 1024u)
+
+#define CARD_MAX_MOUNT_STEP (CARD_NUM_SYSTEM_BLOCK + 2)
+
+typedef struct CARDDir {
+ u8 gameName[4];
+ u8 company[2];
+ u8 _padding0;
+ u8 bannerFormat;
+ u8 fileName[CARD_FILENAME_MAX];
+ u32 time; // seconds since 01/01/2000 midnight
+
+ u32 iconAddr; // 0xffffffff if not used
+ u16 iconFormat;
+ u16 iconSpeed;
+
+ u8 permission;
+ u8 copyTimes;
+ u16 startBlock;
+ u16 length;
+ u8 _padding1[2];
+
+ u32 commentAddr; // 0xffffffff if not used
+} CARDDir;
+
+typedef struct CARDDirCheck {
+ u8 padding0[64 - 2 * 4];
+ u16 padding1;
+ s16 checkCode;
+ u16 checkSum;
+ u16 checkSumInv;
+} CARDDirCheck;
+
+typedef struct CARDControl {
+ BOOL attached;
+ s32 result;
+ u16 size;
+ u16 pageSize;
+ s32 sectorSize;
+ u16 cBlock;
+ u16 vendorID;
+ s32 latency;
+ u8 id[12];
+ int mountStep;
+ int formatStep;
+ u32 scramble;
+ DSPTaskInfo task;
+ void* workArea;
+ CARDDir* currentDir;
+ u16* currentFat;
+ OSThreadQueue threadQueue;
+ u8 cmd[9];
+ s32 cmdlen;
+ vu32 mode;
+ int retry;
+ int repeat;
+ u32 addr;
+ void* buffer;
+ s32 xferred;
+ u16 freeNo;
+ u16 startBlock;
+ CARDFileInfo* fileInfo;
+ CARDCallback extCallback;
+ CARDCallback txCallback;
+ CARDCallback exiCallback;
+ CARDCallback apiCallback;
+ CARDCallback xferCallback;
+ CARDCallback eraseCallback;
+ CARDCallback unlockCallback;
+ OSAlarm alarm;
+ u32 cid;
+ const DVDDiskID* diskID;
+} CARDControl;
+
+typedef struct CARDID {
+ u8 serial[32]; // flashID[12] + timebase[8] + counterBias[4] + language[4] + XXX[4]
+ u16 deviceID;
+ u16 size;
+ u16 encode; // character set -- 0: S-JIS, 1: ANSI
+
+ u8 padding[512 - 32 - 5 * 2];
+
+ u16 checkSum;
+ u16 checkSumInv;
+} CARDID;
+
+void __CARDDefaultApiCallback(s32 chan, s32 result);
+
+#define CARDIsValidBlockNo(card, iBlock) \
+ (CARD_NUM_SYSTEM_BLOCK <= (iBlock) && (iBlock) < (card)->cBlock)
+#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE])
+
+CARDDir* __CARDGetDirBlock(CARDControl* card);
+u16* __CARDGetFatBlock(CARDControl* card);
+s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback);
+void __CARDCheckSum(void* ptr, int length, u16* checkSum, u16* checkSumInv);
+u16 __CARDGetFontEncode();
+void __CARDExiHandler(s32 chan, OSContext* context);
+void __CARDExtHandler(s32 chan, OSContext* context);
+void __CARDUnlockedHandler(s32 chan, OSContext* context);
+s32 __CARDAccess(CARDControl* card, CARDDir* ent);
+BOOL __CARDIsWritable(CARDDir* ent);
+
+#define TRUNC(n, a) (((u32)(n)) & ~((a)-1))
+#define OFFSET(n, a) (((u32)(n)) & ((a)-1))
+
+extern CARDControl __CARDBlock[2];
+extern DVDDiskID __CARDDiskNone;
+extern u16 __CARDVendorID;
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _DOLPHIN_CARDPRIV
diff --git a/include/dolphin/DVDPriv.h b/include/dolphin/DVDPriv.h
new file mode 100644
index 0000000..654e4fc
--- /dev/null
+++ b/include/dolphin/DVDPriv.h
@@ -0,0 +1,51 @@
+#ifndef _DOLPHIN_DVDPRIV
+#define _DOLPHIN_DVDPRIV
+
+#include <dolphin/dvd.h>
+#include <dolphin/dvd_regs.h>
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DVDDriveInfo {
+ u16 revisionLevel;
+ u16 deviceCode;
+ u32 releaseDate;
+ u8 padding[24];
+} DVDDriveInfo;
+
+typedef struct DVDBB1 {
+ u32 appLoaderLength;
+ void* appLoaderFunc1;
+ void* appLoaderFunc2;
+ void* appLoaderFunc3;
+} DVDBB1;
+
+typedef struct DVDBB2 {
+ u32 bootFilePosition;
+ u32 FSTPosition;
+ u32 FSTLength;
+ u32 FSTMaxLength;
+ void* FSTAddress;
+ u32 userPosition;
+ u32 userLength;
+
+ u32 padding0;
+} DVDBB2;
+
+typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, void (*cb)(u32 intType));
+typedef void (*DVDLowCallback)(u32 intType);
+
+DVDLowCallback DVDLowClearCallback();
+void DVDLowSeek(u32 offset, DVDLowCallback callback);
+
+void __DVDLowSetWAType(u32 type, u32 location);
+DVDCommandBlock* __DVDPopWaitingQueue();
+
+#ifdef __cplusplus
+}
+#endif // _DOLPHIN_DVDPRIV
+
+#endif __DVDPRIV_H__
diff --git a/include/dolphin/GBAPriv.h b/include/dolphin/GBAPriv.h
new file mode 100644
index 0000000..43d23e1
--- /dev/null
+++ b/include/dolphin/GBAPriv.h
@@ -0,0 +1,62 @@
+#ifndef _DOLPHIN_GBAPRIV
+#define _DOLPHIN_GBAPRIV
+
+#include "types.h"
+
+#include <dolphin/gba.h>
+#include <dolphin/os.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*GBATransferCallback)(s32 chan);
+
+typedef struct GBASecParams {
+ u8 data[0x40];
+} GBASecParams;
+
+typedef struct GBA {
+ u8 command;
+ u8 src[4];
+ u8 dst[4];
+ u8 _09;
+ s8 _0a;
+ s8 _0b;
+ s32 _0c;
+ s32 _10;
+ u8* status;
+ u8* buffer;
+ GBACallback callback;
+ s32 result;
+ OSThreadQueue thread_queue;
+ OSTime delay;
+ GBATransferCallback _38;
+ s32 _3c;
+ s32 palette_color;
+ s32 palette_speed;
+ u8* program;
+ s32 program_length;
+ s32 jboot_status;
+ GBACallback jboot_callback;
+ char data2[0x74u - 0x58u];
+ u8* challenge_cipher;
+ char data3[0xf8 - 0x78u];
+ GBASecParams* param;
+ char data4[0x100u - 0xfcu];
+} GBA;
+
+extern GBA __GBA[4];
+extern BOOL __GBAReset;
+
+void __GBAHandler(s32 chan, u32 sr, OSContext* context);
+void __GBASyncCallback(s32 chan, s32 ret);
+s32 __GBASync(s32 chan);
+OSTime __GBASetDelay(s32 chan, OSTime delay);
+s32 __GBATransfer(s32 chan, s32 w1, s32 w2, GBATransferCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GBAPRIV
diff --git a/include/dolphin/OSReset.h b/include/dolphin/OSReset.h
deleted file mode 100644
index e8c8bed..0000000
--- a/include/dolphin/OSReset.h
+++ /dev/null
@@ -1 +0,0 @@
-extern void OSResetSystem(int reset, unsigned int resetCode, int forceMenu);
diff --git a/include/dolphin/OSRtcPriv.h b/include/dolphin/OSRtcPriv.h
new file mode 100644
index 0000000..949c71e
--- /dev/null
+++ b/include/dolphin/OSRtcPriv.h
@@ -0,0 +1,34 @@
+#ifndef _DOLPHIN_OSRTCPRIV
+#define _DOLPHIN_OSRTCPRIV
+
+#include <types.h>
+
+typedef struct OSSram {
+ u16 checkSum;
+ u16 checkSumInv;
+ u32 ead0;
+ u32 ead1;
+ u32 counterBias;
+ s8 displayOffsetH;
+ u8 ntd;
+ u8 language;
+ u8 flags;
+} OSSram;
+
+typedef struct OSSramEx {
+ u8 flashID[2][12];
+ u32 wirelessKeyboardID;
+ u16 wirelessPadID[4];
+ u8 dvdErrorCode;
+ u8 _padding0;
+ u8 flashIDCheckSum[2];
+ u16 gbs;
+ u8 _padding1[2];
+} OSSramEx;
+
+OSSram* __OSLockSram();
+OSSramEx* __OSLockSramEx();
+void OSSetWirelessID(s32 chan, u16 id);
+u16 OSGetWirelessID(s32 chan);
+
+#endif // _DOLPHIN_OSRTCPRIV
diff --git a/include/dolphin/PPCArch.h b/include/dolphin/PPCArch.h
index 9ffbd5c..14eecf2 100644
--- a/include/dolphin/PPCArch.h
+++ b/include/dolphin/PPCArch.h
@@ -1,5 +1,3 @@
-// This file was taken from the Metroid Prime decompilation project.
-// https://github.com/PrimeDecomp/prime/blob/main/include/dolphin/PPCArch.h
#ifndef _DOLPHIN_PPCARCH
#define _DOLPHIN_PPCARCH
diff --git a/include/dolphin/__ppc_eabi_init.h b/include/dolphin/__ppc_eabi_init.h
index 6349ce9..5dcba28 100644
--- a/include/dolphin/__ppc_eabi_init.h
+++ b/include/dolphin/__ppc_eabi_init.h
@@ -1,5 +1,3 @@
-// This file was taken from the Metroid Prime decompilation project.
-// https://github.com/PrimeDecomp/prime/blob/main/include/dolphin/__ppc_eabi_init.h
#ifndef _DOLPHIN__PPC_EABI_INIT
#define _DOLPHIN__PPC_EABI_INIT
diff --git a/include/dolphin/__start.h b/include/dolphin/__start.h
index 1b74138..128828f 100644
--- a/include/dolphin/__start.h
+++ b/include/dolphin/__start.h
@@ -1,52 +1,44 @@
-// This file was taken from the Super Mario Sunshine decompilation project.
-// https://github.com/doldecomp/sms/blob/master/include/dolphin/__start.h
-#include "dolphin/types.h"
+#ifndef _DOLPHIN__START
+#define _DOLPHIN__START
+
#include "dolphin/db.h"
+#include "types.h"
-#define PAD3_BUTTON_ADDR 0x800030E4
-#define OS_RESET_RESTART 0
-#define FALSE 0
-#define TRUE 1
-#define EXCEPTIONMASK_ADDR 0x80000044
-#define BOOTINFO2_ADDR 0x800000F4
+#define PAD3_BUTTON_ADDR 0x800030E4
+#define OS_RESET_RESTART 0
+#define EXCEPTIONMASK_ADDR 0x80000044
+#define BOOTINFO2_ADDR 0x800000F4
#define OS_BI2_DEBUGFLAG_OFFSET 0xC
-#define ARENAHI_ADDR 0x80000034
-#define DEBUGFLAG_ADDR 0x800030E8
-#define DVD_DEVICECODE_ADDR 0x800030E6
+#define ARENAHI_ADDR 0x80000034
+#define DEBUGFLAG_ADDR 0x800030E8
+#define DVD_DEVICECODE_ADDR 0x800030E6
+
+#define MSR_FP 0x2000
extern void InitMetroTRK();
u16 Pad3Button : PAD3_BUTTON_ADDR;
+static u8 Debug_BBA = 0;
extern void memset(void*, int, int);
extern int main(int argc, char* argv[]);
extern void exit(int);
extern void __init_user(void);
-extern void InitMetroTRK_BBA(void);
extern void OSInit(void);
+extern void DBInit(void);
extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu);
-extern void __init_hardware(void);
+extern void __OSCacheInit(void);
+extern void __OSPSInit(void);
__declspec(section ".init") extern void __check_pad3(void);
__declspec(section ".init") extern void __start(void);
__declspec(section ".init") extern void __init_registers(void);
__declspec(section ".init") extern void __init_data(void);
+__declspec(section ".init") extern void __init_hardware(void);
+__declspec(section ".init") extern void __flush_cache(void* address, unsigned int size);
__declspec(section ".init") extern char _stack_addr[];
__declspec(section ".init") extern char _SDA_BASE_[];
__declspec(section ".init") extern char _SDA2_BASE_[];
-typedef struct __rom_copy_info {
- char* rom;
- char* addr;
- unsigned int size;
-} __rom_copy_info;
-
-__declspec(section ".init") extern __rom_copy_info _rom_copy_info[];
-
-typedef struct __bss_init_info {
- char* addr;
- unsigned int size;
-} __bss_init_info;
-
-__declspec(section ".init") extern __bss_init_info _bss_init_info[];
+#endif // _DOLPHIN__START
diff --git a/include/dolphin/ai.h b/include/dolphin/ai.h
new file mode 100644
index 0000000..f226c70
--- /dev/null
+++ b/include/dolphin/ai.h
@@ -0,0 +1,36 @@
+#ifndef _DOLPHIN_AI
+#define _DOLPHIN_AI
+
+#include "types.h"
+
+typedef void (*AISCallback)(u32 count);
+typedef void (*AIDCallback)();
+
+AIDCallback AIRegisterDMACallback(AIDCallback callback);
+void AIInitDMA(u32 start_addr, u32 length);
+BOOL AIGetDMAEnableFlag();
+void AIStartDMA();
+void AIStopDMA();
+u32 AIGetDMABytesLeft();
+u32 AIGetDMAStartAddr();
+u32 AIGetDMALength();
+u32 AIGetDSPSampleRate();
+void AISetDSPSampleRate(u32 rate);
+AISCallback AIRegisterStreamCallback(AISCallback callback);
+u32 AIGetStreamSampleCount();
+void AIResetStreamSampleCount();
+void AISetStreamTrigger(u32 trigger);
+u32 AIGetStreamTrigger();
+void AISetStreamPlayState(u32 state);
+u32 AIGetStreamPlayState();
+void AISetStreamSampleRate(u32 rate);
+u32 AIGetStreamSampleRate();
+void AISetStreamVolLeft(u8 vol);
+void AISetStreamVolRight(u8 vol);
+u8 AIGetStreamVolLeft();
+u8 AIGetStreamVolRight();
+void AIInit(u8* stack);
+BOOL AICheckInit();
+void AIReset();
+
+#endif // _DOLPHIN_AI
diff --git a/include/dolphin/ar.h b/include/dolphin/ar.h
new file mode 100644
index 0000000..db0adaf
--- /dev/null
+++ b/include/dolphin/ar.h
@@ -0,0 +1,45 @@
+#ifndef _DOLPHIN_AR
+#define _DOLPHIN_AR
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AR_STACK_INDEX_ENTRY_SIZE sizeof(u32)
+
+#define ARAM_DIR_MRAM_TO_ARAM 0x00
+#define ARAM_DIR_ARAM_TO_MRAM 0x01
+
+#define AR_CLEAR_INTERNAL_ALL 0x00
+#define AR_CLEAR_INTERNAL_USER 0x01
+#define AR_CLEAR_EXPANSION 0x02
+
+typedef void (*ARCallback)(void);
+
+ARCallback ARRegisterDMACallback(ARCallback callback);
+u32 ARGetDMAStatus(void);
+void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length);
+u32 ARInit(u32* stack_index_addr, u32 num_entries);
+u32 ARGetBaseAddress(void);
+BOOL ARCheckInit(void);
+void ARReset(void);
+u32 ARAlloc(u32 length);
+u32 ARFree(u32* length);
+u32 ARGetSize(void);
+u32 ARGetInternalSize(void);
+void ARSetSize(void);
+void ARClear(u32 flag);
+
+void __ARClearInterrupt(void);
+u16 __ARGetInterruptStatus(void);
+
+#define ARStartDMARead(mmem, aram, len) ARStartDMA(ARAM_DIR_ARAM_TO_MRAM, mmem, aram, len)
+#define ARStartDMAWrite(mmem, aram, len) ARStartDMA(ARAM_DIR_MRAM_TO_ARAM, mmem, aram, len)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_AR
diff --git a/include/dolphin/arq.h b/include/dolphin/arq.h
new file mode 100644
index 0000000..c897454
--- /dev/null
+++ b/include/dolphin/arq.h
@@ -0,0 +1,48 @@
+#ifndef _DOLPHIN_ARQ
+#define _DOLPHIN_ARQ
+
+#include "types.h"
+
+#include "dolphin/ar.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "dolphin/ar.h"
+
+#define ARQ_DMA_ALIGNMENT 32
+#define ARQ_CHUNK_SIZE_DEFAULT 4096
+
+#define ARQ_TYPE_MRAM_TO_ARAM ARAM_DIR_MRAM_TO_ARAM
+#define ARQ_TYPE_ARAM_TO_MRAM ARAM_DIR_ARAM_TO_MRAM
+
+#define ARQ_PRIORITY_LOW 0
+#define ARQ_PRIORITY_HIGH 1
+
+typedef void (*ARQCallback)(u32 pointerToARQRequest);
+
+typedef struct ARQRequest {
+
+ struct ARQRequest* next;
+ u32 owner;
+ u32 type;
+ u32 priority;
+ u32 source;
+ u32 dest;
+ u32 length;
+ ARQCallback callback;
+
+} ARQRequest;
+
+void ARQInit(void);
+void ARQReset(void);
+void ARQPostRequest(ARQRequest* task, u32 owner, u32 type, u32 priority, u32 source, u32 dest,
+ u32 length, ARQCallback callback);
+u32 ARQGetChunkSize(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_ARQ
diff --git a/include/dolphin/card.h b/include/dolphin/card.h
new file mode 100644
index 0000000..7d0602d
--- /dev/null
+++ b/include/dolphin/card.h
@@ -0,0 +1,176 @@
+#ifndef _DOLPHIN_CARD
+#define _DOLPHIN_CARD
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define CARD_ENCODE_ANSI 0u
+#define CARD_ENCODE_SJIS 1u
+
+/* Sizes */
+#define CARD_WORKAREA_SIZE (5 * 8 * 1024)
+#define CARD_READ_SIZE 512
+#define CARD_MAX_FILE 127
+#define CARD_COMMENT_SIZE 64
+#define CARD_FILENAME_MAX 32
+#define CARD_ICON_MAX 8
+#define CARD_ICON_WIDTH 32
+#define CARD_ICON_HEIGHT 32
+#define CARD_BANNER_WIDTH 96
+#define CARD_BANNER_HEIGHT 32
+
+/* Icon animation */
+#define CARD_MODE_NORMAL 0
+#define CARD_MODE_FAST 1
+
+#define CARDGetBannerFormat(stat) (((stat)->bannerFormat) & CARD_STAT_BANNER_MASK)
+#define CARDGetIconAnim(stat) (((stat)->bannerFormat) & CARD_STAT_ANIM_MASK)
+#define CARDGetIconFormat(stat, n) (((stat)->iconFormat >> (2 * (n))) & CARD_STAT_ICON_MASK)
+#define CARDGetIconSpeed(stat, n) (((stat)->iconSpeed >> (2 * (n))) & CARD_STAT_SPEED_MASK)
+#define CARDSetBannerFormat(stat, f) \
+ ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_BANNER_MASK) | (f)))
+#define CARDSetIconAnim(stat, f) \
+ ((stat)->bannerFormat = (u8)(((stat)->bannerFormat & ~CARD_STAT_ANIM_MASK) | (f)))
+#define CARDSetIconFormat(stat, n, f) \
+ ((stat)->iconFormat = \
+ (u16)(((stat)->iconFormat & ~(CARD_STAT_ICON_MASK << (2 * (n)))) | ((f) << (2 * (n)))))
+#define CARDSetIconSpeed(stat, n, f) \
+ ((stat)->iconSpeed = \
+ (u16)(((stat)->iconSpeed & ~(CARD_STAT_SPEED_MASK << (2 * (n)))) | ((f) << (2 * (n)))))
+#define CARDSetIconAddress(stat, addr) ((stat)->iconAddr = (u32)(addr))
+#define CARDSetCommentAddress(stat, addr) ((stat)->commentAddr = (u32)(addr))
+#define CARDGetFileNo(fileInfo) ((fileInfo)->fileNo)
+
+#define CARD_RESULT_UNLOCKED 1
+#define CARD_RESULT_READY 0
+#define CARD_RESULT_BUSY -1
+#define CARD_RESULT_WRONGDEVICE -2
+#define CARD_RESULT_NOCARD -3
+#define CARD_RESULT_NOFILE -4
+#define CARD_RESULT_IOERROR -5
+#define CARD_RESULT_BROKEN -6
+#define CARD_RESULT_EXIST -7
+#define CARD_RESULT_NOENT -8
+#define CARD_RESULT_INSSPACE -9
+#define CARD_RESULT_NOPERM -10
+#define CARD_RESULT_LIMIT -11
+#define CARD_RESULT_NAMETOOLONG -12
+#define CARD_RESULT_ENCODING -13
+#define CARD_RESULT_CANCELED -14
+#define CARD_RESULT_FATAL_ERROR -128
+
+#define CARD_STAT_ICON_NONE 0
+#define CARD_STAT_ICON_C8 1
+#define CARD_STAT_ICON_RGB5A3 2
+#define CARD_STAT_ICON_MASK 3
+
+#define CARD_STAT_BANNER_NONE 0
+#define CARD_STAT_BANNER_C8 1
+#define CARD_STAT_BANNER_RGB5A3 2
+#define CARD_STAT_BANNER_MASK 3
+
+#define CARD_STAT_ANIM_LOOP 0x00
+#define CARD_STAT_ANIM_BOUNCE 0x04
+#define CARD_STAT_ANIM_MASK 0x04
+
+#define CARD_STAT_SPEED_END 0
+#define CARD_STAT_SPEED_FAST 1
+#define CARD_STAT_SPEED_MIDDLE 2
+#define CARD_STAT_SPEED_SLOW 3
+#define CARD_STAT_SPEED_MASK 3
+
+#define CARD_ATTR_PUBLIC 0x04u
+#define CARD_ATTR_NO_COPY 0x08u
+#define CARD_ATTR_NO_MOVE 0x10u
+#define CARD_ATTR_GLOBAL 0x20u
+#define CARD_ATTR_COMPANY 0x40u
+
+typedef struct CARDFileInfo {
+ s32 chan;
+ s32 fileNo;
+
+ s32 offset;
+ s32 length;
+ u16 iBlock;
+ u16 __padding;
+} CARDFileInfo;
+
+typedef struct CARDStat {
+ char fileName[CARD_FILENAME_MAX];
+ u32 length;
+ u32 time; // seconds since 01/01/2000 midnight
+ u8 gameName[4];
+ u8 company[2];
+
+ u8 bannerFormat;
+ u8 __padding;
+ u32 iconAddr; // offset to the banner, bannerTlut, icon, iconTlut data set.
+ u16 iconFormat;
+ u16 iconSpeed;
+ u32 commentAddr; // offset to the pair of 32 byte character strings.
+
+ u32 offsetBanner;
+ u32 offsetBannerTlut;
+ u32 offsetIcon[CARD_ICON_MAX];
+ u32 offsetIconTlut;
+ u32 offsetData;
+} CARDStat;
+
+typedef void (*CARDCallback)(s32 chan, s32 result);
+
+void CARDInit(void);
+BOOL CARDGetFastMode(void);
+BOOL CARDSetFastMode(BOOL enable);
+
+s32 CARDCheck(s32 chan);
+s32 CARDCheckAsync(s32 chan, CARDCallback callback);
+s32 CARDCheckEx(s32 chan, s32* xferBytes);
+s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback);
+s32 CARDCreate(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo);
+s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo,
+ CARDCallback callback);
+s32 CARDDelete(s32 chan, const char* fileName);
+s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback);
+s32 CARDFastDelete(s32 chan, s32 fileNo);
+s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback);
+s32 CARDFastOpen(s32 chan, s32 fileNo, CARDFileInfo* fileInfo);
+s32 CARDFormat(s32 chan);
+s32 CARDFormatAsync(s32 chan, CARDCallback callback);
+s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed);
+s32 CARDGetAttributes(s32 chan, s32 fileNo, u8* attr);
+s32 CARDGetEncoding(s32 chan, u16* encode);
+s32 CARDGetMemSize(s32 chan, u16* size);
+s32 CARDGetResultCode(s32 chan);
+s32 CARDGetSectorSize(s32 chan, u32* size);
+s32 CARDGetSerialNo(s32 chan, u64* serialNo);
+s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat);
+s32 CARDGetXferredBytes(s32 chan);
+s32 CARDMount(s32 chan, void* workArea, CARDCallback detachCallback);
+s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback,
+ CARDCallback attachCallback);
+s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo);
+BOOL CARDProbe(s32 chan);
+s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize);
+s32 CARDRename(s32 chan, const char* oldName, const char* newName);
+s32 CARDRenameAsync(s32 chan, const char* oldName, const char* newName, CARDCallback callback);
+s32 CARDSetAttributesAsync(s32 chan, s32 fileNo, u8 attr, CARDCallback callback);
+s32 CARDSetAttributes(s32 chan, s32 fileNo, u8 attr);
+s32 CARDSetStatus(s32 chan, s32 fileNo, CARDStat* stat);
+s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback);
+s32 CARDUnmount(s32 chan);
+s32 CARDGetCurrentMode(s32 chan, u32* mode);
+s32 CARDCancel(CARDFileInfo* fileInfo);
+s32 CARDClose(CARDFileInfo* fileInfo);
+s32 CARDRead(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset);
+s32 CARDReadAsync(CARDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
+ CARDCallback callback);
+s32 CARDWrite(CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset);
+s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* addr, s32 length, s32 offset,
+ CARDCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _DOLPHIN_CARD
diff --git a/include/dolphin/db.h b/include/dolphin/db.h
new file mode 100644
index 0000000..08851a4
--- /dev/null
+++ b/include/dolphin/db.h
@@ -0,0 +1,31 @@
+#ifndef _DOLPHIN_DB
+#define _DOLPHIN_DB
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_DBINTERFACE_ADDR 0x00000040
+
+typedef struct DBInterface
+{
+ u32 bPresent;
+ u32 exceptionMask;
+ void (*ExceptionDestination) ( void );
+ void *exceptionReturn;
+} DBInterface;
+
+extern DBInterface* __DBInterface;
+
+void DBInit(void);
+void DBInitComm(int* inputFlagPtr, int* mtrCallback);
+static void __DBExceptionDestination(void);
+void DBPrintf(char* format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_DB
diff --git a/include/dolphin/dsp.h b/include/dolphin/dsp.h
new file mode 100644
index 0000000..f74ac9e
--- /dev/null
+++ b/include/dolphin/dsp.h
@@ -0,0 +1,72 @@
+#ifndef _DOLPHIN_DSP
+#define _DOLPHIN_DSP
+
+#include "types.h"
+#include <dolphin/os.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DSP_TASK_FLAG_CLEARALL 0x00000000
+#define DSP_TASK_FLAG_ATTACHED 0x00000001
+#define DSP_TASK_FLAG_CANCEL 0x00000002
+
+#define DSP_TASK_STATE_INIT 0
+#define DSP_TASK_STATE_RUN 1
+#define DSP_TASK_STATE_YIELD 2
+#define DSP_TASK_STATE_DONE 3
+
+typedef void (*DSPCallback)(void* task);
+
+typedef struct DSPTaskInfo DSPTaskInfo;
+
+typedef struct DSPTaskInfo {
+ vu32 state;
+ vu32 priority;
+ vu32 flags;
+ u16* iram_mmem_addr;
+ u32 iram_length;
+ u32 iram_addr;
+
+ u16* dram_mmem_addr;
+ u32 dram_length;
+ u32 dram_addr;
+
+ u16 dsp_init_vector;
+ u16 dsp_resume_vector;
+
+ DSPCallback init_cb;
+ DSPCallback res_cb;
+ DSPCallback done_cb;
+ DSPCallback req_cb;
+
+ struct DSPTaskInfo* next;
+ struct DSPTaskInfo* prev;
+
+ OSTime t_context;
+ OSTime t_task;
+
+} DSPTaskInfo;
+
+void DSPInit();
+void DSPReset();
+void DSPHalt();
+void DSPSendMailToDSP(u32 mail);
+u32 DSPCheckMailToDSP();
+u32 DSPCheckMailFromDSP();
+u32 DSPGetDMAStatus();
+
+DSPTaskInfo* DSPAddTask(DSPTaskInfo* task);
+
+void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next);
+void __DSP_boot_task(DSPTaskInfo* task);
+void __DSP_remove_task(DSPTaskInfo* task);
+void __DSP_add_task(DSPTaskInfo* task);
+void __DSP_debug_printf(const char* fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_DSP
diff --git a/include/dolphin/dsp_regs.h b/include/dolphin/dsp_regs.h
new file mode 100644
index 0000000..eee9376
--- /dev/null
+++ b/include/dolphin/dsp_regs.h
@@ -0,0 +1,9 @@
+#ifndef _DOLPHIN_DSP_REGS
+#define _DOLPHIN_DSP_REGS
+
+#include "types.h"
+
+vu16 __DSPRegs[32] : 0xCC005000;
+vu32 __AIRegs[8] : 0xCC006C00;
+
+#endif // _DOLPHIN_DSP_REGS
diff --git a/include/dolphin/dtk.h b/include/dolphin/dtk.h
new file mode 100644
index 0000000..f266190
--- /dev/null
+++ b/include/dolphin/dtk.h
@@ -0,0 +1,47 @@
+#ifndef _DOLPHIN_DTK
+#define _DOLPHIN_DTK
+
+#include <dolphin/dvd.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef void (*DTKCallback)(u32 eventMask);
+typedef void (*DTKFlushCallback)(void);
+
+typedef struct DTKTrack {
+ struct DTKTrack* prev;
+ struct DTKTrack* next;
+ char* fileName;
+ u32 eventMask;
+ DTKCallback callback;
+ DVDFileInfo dvdFileInfo;
+
+} DTKTrack;
+
+void DTKInit(void);
+void DTKShutdown(void);
+u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback);
+u32 DTKRemoveTrack(DTKTrack* track);
+void DTKFlushTracks(DTKFlushCallback callback);
+void DTKSetSampleRate(u32 samplerate);
+u32 DTKGetSampleRate(void);
+void DTKSetInterruptFrequency(u32 samples);
+u32 DTKGetInterruptFrequency(void);
+void DTKSetRepeatMode(u32 repeat);
+u32 DTKGetRepeatMode(void);
+void DTKSetState(u32 state);
+u32 DTKGetState(void);
+void DTKNextTrack(void);
+void DTKPrevTrack(void);
+u32 DTKGetPosition(void);
+DTKTrack* DTKGetCurrentTrack(void);
+void DTKSetVolume(u8 left, u8 right);
+u16 DTKGetVolume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_DTK
diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h
new file mode 100644
index 0000000..3360a8e
--- /dev/null
+++ b/include/dolphin/dvd.h
@@ -0,0 +1,136 @@
+#ifndef _DOLPHIN_DVD
+#define _DOLPHIN_DVD
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DVD_MIN_TRANSFER_SIZE 32
+
+#define DVD_STATE_FATAL_ERROR -1
+#define DVD_STATE_END 0
+#define DVD_STATE_BUSY 1
+#define DVD_STATE_WAITING 2
+#define DVD_STATE_COVER_CLOSED 3
+#define DVD_STATE_NO_DISK 4
+#define DVD_STATE_COVER_OPEN 5
+#define DVD_STATE_WRONG_DISK 6
+#define DVD_STATE_MOTOR_STOPPED 7
+#define DVD_STATE_PAUSING 8
+#define DVD_STATE_IGNORED 9
+#define DVD_STATE_CANCELED 10
+#define DVD_STATE_RETRY 11
+
+#define DVD_FILEINFO_READY 0
+#define DVD_FILEINFO_BUSY 1
+
+#define DVD_RESULT_GOOD 0
+#define DVD_RESULT_FATAL_ERROR -1
+#define DVD_RESULT_IGNORED -2
+#define DVD_RESULT_CANCELED -3
+
+#define DVD_AIS_SUCCESS 0x0
+
+typedef struct DVDDiskID {
+ char gameName[4];
+ char company[2];
+ u8 diskNumber;
+ u8 gameVersion;
+ u8 streaming;
+ u8 streamingBufSize; // 0 = default
+ u8 padding[22]; // 0's are stored
+} DVDDiskID;
+
+typedef struct DVDCommandBlock DVDCommandBlock;
+
+typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block);
+
+struct DVDCommandBlock {
+ DVDCommandBlock* next;
+ DVDCommandBlock* prev;
+ u32 command;
+ s32 state;
+ u32 offset;
+ u32 length;
+ void* addr;
+ u32 currTransferSize;
+ u32 transferredSize;
+ DVDDiskID* id;
+ DVDCBCallback callback;
+ void* userData;
+};
+
+typedef struct DVDFileInfo DVDFileInfo;
+
+typedef void (*DVDCallback)(s32 result, DVDFileInfo* fileInfo);
+
+struct DVDFileInfo {
+ DVDCommandBlock cb;
+ u32 startAddr;
+ u32 length;
+ DVDCallback callback;
+};
+
+typedef struct {
+ u32 entryNum;
+ u32 location;
+ u32 next;
+} DVDDir;
+
+typedef struct {
+ u32 entryNum;
+ BOOL isDir;
+ char* name;
+} DVDDirEntry;
+
+void DVDInit();
+BOOL DVDClose(DVDFileInfo* f);
+BOOL DVDSetAutoFatalMessaging(BOOL);
+void DVDReset();
+s32 DVDCancel(DVDCommandBlock* block);
+BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo);
+BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo);
+s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block);
+BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback);
+s32 DVDCancel(DVDCommandBlock* block);
+BOOL DVDCancelAllAsync(DVDCBCallback callback);
+s32 DVDCancelAll(void);
+BOOL DVDPrepareStreamAsync(DVDFileInfo* fInfo, u32 length, u32 offset, DVDCallback callback);
+s32 DVDPrepareStream(DVDFileInfo* fInfo, u32 length, u32 offset);
+
+BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback);
+s32 DVDCancelStream(DVDCommandBlock* block);
+
+BOOL DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback);
+s32 DVDStopStreamAtEnd(DVDCommandBlock* block);
+
+BOOL DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback);
+s32 DVDGetStreamErrorStatus(DVDCommandBlock* block);
+
+BOOL DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback);
+s32 DVDGetStreamPlayAddr(DVDCommandBlock* block);
+
+s32 DVDGetDriveStatus();
+
+s32 DVDConvertPathToEntrynum(char* pathPtr);
+
+BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
+ DVDCallback callback, s32 prio);
+BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length,
+ s32 offset, DVDCBCallback callback);
+BOOL DVDCheckDisk(void);
+void __DVDPrepareResetAsync(DVDCBCallback callback);
+BOOL DVDSetAutoInvalidation(BOOL autoInval);
+
+#define DVDReadAsync(fileInfo, addr, length, offset, callback) \
+ DVDReadAsyncPrio((fileInfo), (addr), (length), (offset), (callback), 2)
+#define DVDSeekAsync(fileInfo, offset, callback) \
+ DVDSeekAsyncPrio((fileInfo), (offset), (callback), 2)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_DVD
diff --git a/include/dolphin/dvd_regs.h b/include/dolphin/dvd_regs.h
new file mode 100644
index 0000000..85be468
--- /dev/null
+++ b/include/dolphin/dvd_regs.h
@@ -0,0 +1,6 @@
+#ifndef _DOLPHIN_DVD_REGS
+#define _DOLPHIN_DVD_REGS
+
+vu32 __DIRegs[16] : 0xCC006000;
+
+#endif // _DOLPHIN_DVD_REGS
diff --git a/include/dolphin/gba.h b/include/dolphin/gba.h
new file mode 100644
index 0000000..692f568
--- /dev/null
+++ b/include/dolphin/gba.h
@@ -0,0 +1,65 @@
+#ifndef _DOLPHIN_GBA
+#define _DOLPHIN_GBA
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GBA_CHAN0 0
+#define GBA_CHAN1 1
+#define GBA_CHAN2 2
+#define GBA_CHAN3 3
+#define GBA_MAX_CHAN 4
+
+#define GBA_ALL_KEY_MASK 0x03ff
+#define GBA_A_BUTTON 0x0001
+#define GBA_B_BUTTON 0x0002
+#define GBA_SELECT_BUTTON 0x0004
+#define GBA_START_BUTTON 0x0008
+#define GBA_R_KEY 0x0010
+#define GBA_L_KEY 0x0020
+#define GBA_U_KEY 0x0040
+#define GBA_D_KEY 0x0080
+#define GBA_R_BUTTON 0x0100
+#define GBA_L_BUTTON 0x0200
+
+#define GBA_JSTAT_MASK 0x3a
+#define GBA_JSTAT_FLAGS_SHIFT 4
+#define GBA_JSTAT_FLAGS_MASK 0x30
+#define GBA_JSTAT_PSF1 0x20
+#define GBA_JSTAT_PSF0 0x10
+#define GBA_JSTAT_SEND 0x08
+#define GBA_JSTAT_RECV 0x02
+
+#define GBA_READY 0
+#define GBA_NOT_READY 1
+#define GBA_BUSY 2
+#define GBA_JOYBOOT_UNKNOWN_STATE 3
+#define GBA_JOYBOOT_ERR_INVALID 4
+
+#define GBA_JOYBOOT_PROGRAM_SIZE_MAX 0x40000
+
+#define GBA_JOYBOOT_BOOTPARAM_OFFSET 0xc8
+#define GBA_JOYBOOT_BOOTPARAM_SIZE 0x18
+typedef void (*GBACallback)(s32 chan, s32 ret);
+void GBAInit(void);
+s32 GBAGetStatus(s32 chan, u8* status);
+s32 GBAGetStatusAsync(s32 chan, u8* status, GBACallback callback);
+s32 GBAReset(s32 chan, u8* status);
+s32 GBAResetAsync(s32 chan, u8* status, GBACallback callback);
+s32 GBAGetProcessStatus(s32 chan, u8* percentp);
+s32 GBARead(s32 chan, u8* dst, u8* status);
+s32 GBAReadAsync(s32 chan, u8* dst, u8* status, GBACallback callback);
+s32 GBAWrite(s32 chan, u8* src, u8* status);
+s32 GBAWriteAsync(s32 chan, u8* src, u8* status, GBACallback callback);
+s32 GBAJoyBoot(s32 chan, s32 palette_color, s32 palette_speed, u8* programp, s32 length,
+ u8* status);
+s32 GBAJoyBootAsync(s32 chan, s32 palette_color, s32 palette_speed, u8* programp, s32 length,
+ u8* status, GBACallback callback);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GBA
diff --git a/include/dolphin/gx.h b/include/dolphin/gx.h
new file mode 100644
index 0000000..856842b
--- /dev/null
+++ b/include/dolphin/gx.h
@@ -0,0 +1,26 @@
+#ifndef _DOLPHIN_GX
+#define _DOLPHIN_GX
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/gx/GXStruct.h>
+
+#include <dolphin/gx/GXBump.h>
+#include <dolphin/gx/GXCommandList.h>
+#include <dolphin/gx/GXCull.h>
+#include <dolphin/gx/GXDispList.h>
+#include <dolphin/gx/GXDraw.h>
+#include <dolphin/gx/GXExtra.h>
+#include <dolphin/gx/GXFifo.h>
+#include <dolphin/gx/GXFrameBuffer.h>
+#include <dolphin/gx/GXGeometry.h>
+#include <dolphin/gx/GXGet.h>
+#include <dolphin/gx/GXLighting.h>
+#include <dolphin/gx/GXManage.h>
+#include <dolphin/gx/GXPerf.h>
+#include <dolphin/gx/GXPixel.h>
+#include <dolphin/gx/GXTev.h>
+#include <dolphin/gx/GXTexture.h>
+#include <dolphin/gx/GXTransform.h>
+#include <dolphin/gx/GXVert.h>
+
+#endif // _DOLPHIN_GX
diff --git a/include/dolphin/gx/GXBump.h b/include/dolphin/gx/GXBump.h
new file mode 100644
index 0000000..a936ddc
--- /dev/null
+++ b/include/dolphin/gx/GXBump.h
@@ -0,0 +1,30 @@
+#ifndef _DOLPHIN_GXBUMP
+#define _DOLPHIN_GXBUMP
+
+#include <dolphin/gx/GXEnum.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXSetTevDirect(GXTevStageID tev_stage);
+void GXSetNumIndStages(u8 nIndStages);
+#ifdef TARGET_PC
+void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, const void* offset, s8 scale_exp);
+#else
+void GXSetIndTexMtx(GXIndTexMtxID mtx_sel, f32 offset[2][3], s8 scale_exp);
+#endif
+void GXSetIndTexOrder(GXIndTexStageID ind_stage, GXTexCoordID tex_coord, GXTexMapID tex_map);
+void GXSetTevIndirect(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXIndTexFormat format,
+ GXIndTexBiasSel bias_sel, GXIndTexMtxID matrix_sel, GXIndTexWrap wrap_s,
+ GXIndTexWrap wrap_t, GXBool add_prev, GXBool ind_lod,
+ GXIndTexAlphaSel alpha_sel);
+void GXSetTevIndWarp(GXTevStageID tev_stage, GXIndTexStageID ind_stage, GXBool signed_offsets,
+ GXBool replace_mode, GXIndTexMtxID matrix_sel);
+void GXSetIndTexCoordScale(GXIndTexStageID ind_state, GXIndTexScale scale_s, GXIndTexScale scale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXBUMP
diff --git a/include/dolphin/gx/GXCommandList.h b/include/dolphin/gx/GXCommandList.h
new file mode 100644
index 0000000..cf3a517
--- /dev/null
+++ b/include/dolphin/gx/GXCommandList.h
@@ -0,0 +1,35 @@
+#ifndef _DOLPHIN_GXCOMMANDLIST
+#define _DOLPHIN_GXCOMMANDLIST
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GX_NOP 0x00
+#define GX_DRAW_QUADS 0x80
+#define GX_DRAW_TRIANGLES 0x90
+#define GX_DRAW_TRIANGLE_STRIP 0x98
+#define GX_DRAW_TRIANGLE_FAN 0xA0
+#define GX_DRAW_LINES 0xA8
+#define GX_DRAW_LINE_STRIP 0xB0
+#define GX_DRAW_POINTS 0xB8
+
+#define GX_LOAD_BP_REG 0x61
+#define GX_LOAD_CP_REG 0x08
+#define GX_LOAD_XF_REG 0x10
+#define GX_LOAD_INDX_A 0x20
+#define GX_LOAD_INDX_B 0x28
+#define GX_LOAD_INDX_C 0x30
+#define GX_LOAD_INDX_D 0x38
+
+#define GX_CMD_CALL_DL 0x40
+#define GX_CMD_INVL_VC 0x48
+
+#define GX_OPCODE_MASK 0xF8
+#define GX_VAT_MASK 0x07
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXCOMMANDLIST
diff --git a/include/dolphin/gx/GXCull.h b/include/dolphin/gx/GXCull.h
new file mode 100644
index 0000000..b569930
--- /dev/null
+++ b/include/dolphin/gx/GXCull.h
@@ -0,0 +1,18 @@
+#ifndef _DOLPHIN_GXCULL
+#define _DOLPHIN_GXCULL
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXSetScissor(u32 left, u32 top, u32 wd, u32 ht);
+void GXSetCullMode(GXCullMode mode);
+void GXSetCoPlanar(GXBool enable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXCULL
diff --git a/include/dolphin/gx/GXDispList.h b/include/dolphin/gx/GXDispList.h
new file mode 100644
index 0000000..552eda2
--- /dev/null
+++ b/include/dolphin/gx/GXDispList.h
@@ -0,0 +1,18 @@
+#ifndef _DOLPHIN_GXDISPLIST
+#define _DOLPHIN_GXDISPLIST
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXBeginDisplayList(void* list, u32 size);
+u32 GXEndDisplayList(void);
+void GXCallDisplayList(const void* list, u32 nbytes);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXDISPLIST
diff --git a/include/dolphin/gx/GXDraw.h b/include/dolphin/gx/GXDraw.h
new file mode 100644
index 0000000..3901ebf
--- /dev/null
+++ b/include/dolphin/gx/GXDraw.h
@@ -0,0 +1,16 @@
+#ifndef _DOLPHIN_GXDRAW
+#define _DOLPHIN_GXDRAW
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXDrawSphere(u8 numMajor, u8 numMinor);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXDRAW
diff --git a/include/dolphin/gx/GXEnum.h b/include/dolphin/gx/GXEnum.h
new file mode 100644
index 0000000..206ca80
--- /dev/null
+++ b/include/dolphin/gx/GXEnum.h
@@ -0,0 +1,891 @@
+#ifndef _DOLPHIN_GXENUM
+#define _DOLPHIN_GXENUM
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef TARGET_PC
+#include <stdbool.h>
+
+typedef bool GXBool;
+#else
+typedef u8 GXBool;
+#endif
+
+#define GX_FALSE ((GXBool)0)
+#define GX_TRUE ((GXBool)1)
+
+#define GX_ENABLE ((GXBool)1)
+#define GX_DISABLE ((GXBool)0)
+
+typedef enum _GXProjectionType {
+ GX_PERSPECTIVE,
+ GX_ORTHOGRAPHIC,
+} GXProjectionType;
+
+typedef enum _GXCompare {
+ GX_NEVER,
+ GX_LESS,
+ GX_EQUAL,
+ GX_LEQUAL,
+ GX_GREATER,
+ GX_NEQUAL,
+ GX_GEQUAL,
+ GX_ALWAYS,
+} GXCompare;
+
+typedef enum _GXAlphaOp {
+ GX_AOP_AND,
+ GX_AOP_OR,
+ GX_AOP_XOR,
+ GX_AOP_XNOR,
+ GX_MAX_ALPHAOP,
+} GXAlphaOp;
+
+typedef enum _GXZFmt16 {
+ GX_ZC_LINEAR,
+ GX_ZC_NEAR,
+ GX_ZC_MID,
+ GX_ZC_FAR,
+} GXZFmt16;
+
+typedef enum _GXGamma {
+ GX_GM_1_0,
+ GX_GM_1_7,
+ GX_GM_2_2,
+} GXGamma;
+
+typedef enum _GXPixelFmt {
+ GX_PF_RGB8_Z24,
+ GX_PF_RGBA6_Z24,
+ GX_PF_RGB565_Z16,
+ GX_PF_Z24,
+ GX_PF_Y8,
+ GX_PF_U8,
+ GX_PF_V8,
+ GX_PF_YUV420,
+} GXPixelFmt;
+
+typedef enum _GXPrimitive {
+ GX_QUADS = 0x80,
+ GX_TRIANGLES = 0x90,
+ GX_TRIANGLESTRIP = 0x98,
+ GX_TRIANGLEFAN = 0xA0,
+ GX_LINES = 0xA8,
+ GX_LINESTRIP = 0xB0,
+ GX_POINTS = 0xB8,
+} GXPrimitive;
+
+typedef enum _GXVtxFmt {
+ GX_VTXFMT0,
+ GX_VTXFMT1,
+ GX_VTXFMT2,
+ GX_VTXFMT3,
+ GX_VTXFMT4,
+ GX_VTXFMT5,
+ GX_VTXFMT6,
+ GX_VTXFMT7,
+ GX_MAX_VTXFMT,
+} GXVtxFmt;
+
+typedef enum _GXAttr {
+ GX_VA_PNMTXIDX,
+ GX_VA_TEX0MTXIDX,
+ GX_VA_TEX1MTXIDX,
+ GX_VA_TEX2MTXIDX,
+ GX_VA_TEX3MTXIDX,
+ GX_VA_TEX4MTXIDX,
+ GX_VA_TEX5MTXIDX,
+ GX_VA_TEX6MTXIDX,
+ GX_VA_TEX7MTXIDX,
+ GX_VA_POS,
+ GX_VA_NRM,
+ GX_VA_CLR0,
+ GX_VA_CLR1,
+ GX_VA_TEX0,
+ GX_VA_TEX1,
+ GX_VA_TEX2,
+ GX_VA_TEX3,
+ GX_VA_TEX4,
+ GX_VA_TEX5,
+ GX_VA_TEX6,
+ GX_VA_TEX7,
+ GX_POS_MTX_ARRAY,
+ GX_NRM_MTX_ARRAY,
+ GX_TEX_MTX_ARRAY,
+ GX_LIGHT_ARRAY,
+ GX_VA_NBT,
+ GX_VA_MAX_ATTR,
+ GX_VA_NULL = 0xFF,
+} GXAttr;
+
+#define GX_MAX_VTXDESCLIST_SZ (GX_VA_MAX_ATTR + 1)
+
+typedef enum _GXAttrType {
+ GX_NONE,
+ GX_DIRECT,
+ GX_INDEX8,
+ GX_INDEX16,
+} GXAttrType;
+
+#define _GX_TF_CTF 0x20
+#define _GX_TF_ZTF 0x10
+
+typedef enum _GXTexFmt {
+ GX_TF_I4 = 0x0,
+ GX_TF_I8 = 0x1,
+ GX_TF_IA4 = 0x2,
+ GX_TF_IA8 = 0x3,
+ GX_TF_RGB565 = 0x4,
+ GX_TF_RGB5A3 = 0x5,
+ GX_TF_RGBA8 = 0x6,
+ GX_TF_CMPR = 0xE,
+
+ GX_CTF_R4 = 0x0 | _GX_TF_CTF,
+ GX_CTF_RA4 = 0x2 | _GX_TF_CTF,
+ GX_CTF_RA8 = 0x3 | _GX_TF_CTF,
+ GX_CTF_YUVA8 = 0x6 | _GX_TF_CTF,
+ GX_CTF_A8 = 0x7 | _GX_TF_CTF,
+ GX_CTF_R8 = 0x8 | _GX_TF_CTF,
+ GX_CTF_G8 = 0x9 | _GX_TF_CTF,
+ GX_CTF_B8 = 0xA | _GX_TF_CTF,
+ GX_CTF_RG8 = 0xB | _GX_TF_CTF,
+ GX_CTF_GB8 = 0xC | _GX_TF_CTF,
+
+ GX_TF_Z8 = 0x1 | _GX_TF_ZTF,
+ GX_TF_Z16 = 0x3 | _GX_TF_ZTF,
+ GX_TF_Z24X8 = 0x6 | _GX_TF_ZTF,
+
+ GX_CTF_Z4 = 0x0 | _GX_TF_ZTF | _GX_TF_CTF,
+ GX_CTF_Z8M = 0x9 | _GX_TF_ZTF | _GX_TF_CTF,
+ GX_CTF_Z8L = 0xA | _GX_TF_ZTF | _GX_TF_CTF,
+ GX_CTF_Z16L = 0xC | _GX_TF_ZTF | _GX_TF_CTF,
+
+ GX_TF_A8 = GX_CTF_A8,
+} GXTexFmt;
+
+typedef enum _GXCITexFmt {
+ GX_TF_C4 = 0x8,
+ GX_TF_C8 = 0x9,
+ GX_TF_C14X2 = 0xa,
+} GXCITexFmt;
+
+typedef enum _GXTexWrapMode {
+ GX_CLAMP,
+ GX_REPEAT,
+ GX_MIRROR,
+ GX_MAX_TEXWRAPMODE,
+} GXTexWrapMode;
+
+typedef enum _GXTexFilter {
+ GX_NEAR,
+ GX_LINEAR,
+ GX_NEAR_MIP_NEAR,
+ GX_LIN_MIP_NEAR,
+ GX_NEAR_MIP_LIN,
+ GX_LIN_MIP_LIN,
+} GXTexFilter;
+
+typedef enum _GXAnisotropy {
+ GX_ANISO_1,
+ GX_ANISO_2,
+ GX_ANISO_4,
+ GX_MAX_ANISOTROPY,
+} GXAnisotropy;
+
+typedef enum _GXTexMapID {
+ GX_TEXMAP0,
+ GX_TEXMAP1,
+ GX_TEXMAP2,
+ GX_TEXMAP3,
+ GX_TEXMAP4,
+ GX_TEXMAP5,
+ GX_TEXMAP6,
+ GX_TEXMAP7,
+ GX_MAX_TEXMAP,
+ GX_TEXMAP_NULL = 0xFF,
+ GX_TEX_DISABLE = 0x100,
+} GXTexMapID;
+
+typedef enum _GXTexCoordID {
+ GX_TEXCOORD0,
+ GX_TEXCOORD1,
+ GX_TEXCOORD2,
+ GX_TEXCOORD3,
+ GX_TEXCOORD4,
+ GX_TEXCOORD5,
+ GX_TEXCOORD6,
+ GX_TEXCOORD7,
+ GX_MAX_TEXCOORD,
+ GX_TEXCOORD_NULL = 0xFF,
+} GXTexCoordID;
+
+typedef enum _GXTevStageID {
+ GX_TEVSTAGE0,
+ GX_TEVSTAGE1,
+ GX_TEVSTAGE2,
+ GX_TEVSTAGE3,
+ GX_TEVSTAGE4,
+ GX_TEVSTAGE5,
+ GX_TEVSTAGE6,
+ GX_TEVSTAGE7,
+ GX_TEVSTAGE8,
+ GX_TEVSTAGE9,
+ GX_TEVSTAGE10,
+ GX_TEVSTAGE11,
+ GX_TEVSTAGE12,
+ GX_TEVSTAGE13,
+ GX_TEVSTAGE14,
+ GX_TEVSTAGE15,
+ GX_MAX_TEVSTAGE,
+} GXTevStageID;
+
+typedef enum _GXTevMode {
+ GX_MODULATE,
+ GX_DECAL,
+ GX_BLEND,
+ GX_REPLACE,
+ GX_PASSCLR,
+} GXTevMode;
+
+typedef enum _GXTexMtxType {
+ GX_MTX3x4,
+ GX_MTX2x4,
+} GXTexMtxType;
+
+typedef enum _GXTexGenType {
+ GX_TG_MTX3x4,
+ GX_TG_MTX2x4,
+ GX_TG_BUMP0,
+ GX_TG_BUMP1,
+ GX_TG_BUMP2,
+ GX_TG_BUMP3,
+ GX_TG_BUMP4,
+ GX_TG_BUMP5,
+ GX_TG_BUMP6,
+ GX_TG_BUMP7,
+ GX_TG_SRTG,
+} GXTexGenType;
+
+typedef enum _GXPosNrmMtx {
+ GX_PNMTX0 = 0,
+ GX_PNMTX1 = 3,
+ GX_PNMTX2 = 6,
+ GX_PNMTX3 = 9,
+ GX_PNMTX4 = 12,
+ GX_PNMTX5 = 15,
+ GX_PNMTX6 = 18,
+ GX_PNMTX7 = 21,
+ GX_PNMTX8 = 24,
+ GX_PNMTX9 = 27,
+} GXPosNrmMtx;
+
+typedef enum _GXTexMtx {
+ GX_TEXMTX0 = 30,
+ GX_TEXMTX1 = 33,
+ GX_TEXMTX2 = 36,
+ GX_TEXMTX3 = 39,
+ GX_TEXMTX4 = 42,
+ GX_TEXMTX5 = 45,
+ GX_TEXMTX6 = 48,
+ GX_TEXMTX7 = 51,
+ GX_TEXMTX8 = 54,
+ GX_TEXMTX9 = 57,
+ GX_IDENTITY = 60,
+} GXTexMtx;
+
+typedef enum _GXChannelID {
+ GX_COLOR0,
+ GX_COLOR1,
+ GX_ALPHA0,
+ GX_ALPHA1,
+ GX_COLOR0A0,
+ GX_COLOR1A1,
+ GX_COLOR_ZERO,
+ GX_ALPHA_BUMP,
+ GX_ALPHA_BUMPN,
+ GX_COLOR_NULL = 0xFF,
+} GXChannelID;
+
+typedef enum _GXTexGenSrc {
+ GX_TG_POS,
+ GX_TG_NRM,
+ GX_TG_BINRM,
+ GX_TG_TANGENT,
+ GX_TG_TEX0,
+ GX_TG_TEX1,
+ GX_TG_TEX2,
+ GX_TG_TEX3,
+ GX_TG_TEX4,
+ GX_TG_TEX5,
+ GX_TG_TEX6,
+ GX_TG_TEX7,
+ GX_TG_TEXCOORD0,
+ GX_TG_TEXCOORD1,
+ GX_TG_TEXCOORD2,
+ GX_TG_TEXCOORD3,
+ GX_TG_TEXCOORD4,
+ GX_TG_TEXCOORD5,
+ GX_TG_TEXCOORD6,
+ GX_TG_COLOR0,
+ GX_TG_COLOR1,
+ GX_MAX_TEXGENSRC,
+} GXTexGenSrc;
+
+typedef enum _GXBlendMode {
+ GX_BM_NONE,
+ GX_BM_BLEND,
+ GX_BM_LOGIC,
+ GX_BM_SUBTRACT,
+ GX_MAX_BLENDMODE,
+} GXBlendMode;
+
+typedef enum _GXBlendFactor {
+ GX_BL_ZERO,
+ GX_BL_ONE,
+ GX_BL_SRCCLR,
+ GX_BL_INVSRCCLR,
+ GX_BL_SRCALPHA,
+ GX_BL_INVSRCALPHA,
+ GX_BL_DSTALPHA,
+ GX_BL_INVDSTALPHA,
+ GX_BL_DSTCLR = GX_BL_SRCCLR,
+ GX_BL_INVDSTCLR = GX_BL_INVSRCCLR,
+} GXBlendFactor;
+
+typedef enum _GXLogicOp {
+ GX_LO_CLEAR,
+ GX_LO_AND,
+ GX_LO_REVAND,
+ GX_LO_COPY,
+ GX_LO_INVAND,
+ GX_LO_NOOP,
+ GX_LO_XOR,
+ GX_LO_OR,
+ GX_LO_NOR,
+ GX_LO_EQUIV,
+ GX_LO_INV,
+ GX_LO_REVOR,
+ GX_LO_INVCOPY,
+ GX_LO_INVOR,
+ GX_LO_NAND,
+ GX_LO_SET,
+} GXLogicOp;
+
+typedef enum _GXCompCnt {
+ GX_POS_XY = 0,
+ GX_POS_XYZ = 1,
+ GX_NRM_XYZ = 0,
+ GX_NRM_NBT = 1,
+ GX_NRM_NBT3 = 2,
+ GX_CLR_RGB = 0,
+ GX_CLR_RGBA = 1,
+ GX_TEX_S = 0,
+ GX_TEX_ST = 1,
+} GXCompCnt;
+
+typedef enum _GXCompType {
+ GX_U8 = 0,
+ GX_S8 = 1,
+ GX_U16 = 2,
+ GX_S16 = 3,
+ GX_F32 = 4,
+ GX_RGB565 = 0,
+ GX_RGB8 = 1,
+ GX_RGBX8 = 2,
+ GX_RGBA4 = 3,
+ GX_RGBA6 = 4,
+ GX_RGBA8 = 5,
+} GXCompType;
+
+typedef enum _GXPTTexMtx {
+ GX_PTTEXMTX0 = 64,
+ GX_PTTEXMTX1 = 67,
+ GX_PTTEXMTX2 = 70,
+ GX_PTTEXMTX3 = 73,
+ GX_PTTEXMTX4 = 76,
+ GX_PTTEXMTX5 = 79,
+ GX_PTTEXMTX6 = 82,
+ GX_PTTEXMTX7 = 85,
+ GX_PTTEXMTX8 = 88,
+ GX_PTTEXMTX9 = 91,
+ GX_PTTEXMTX10 = 94,
+ GX_PTTEXMTX11 = 97,
+ GX_PTTEXMTX12 = 100,
+ GX_PTTEXMTX13 = 103,
+ GX_PTTEXMTX14 = 106,
+ GX_PTTEXMTX15 = 109,
+ GX_PTTEXMTX16 = 112,
+ GX_PTTEXMTX17 = 115,
+ GX_PTTEXMTX18 = 118,
+ GX_PTTEXMTX19 = 121,
+ GX_PTIDENTITY = 125,
+} GXPTTexMtx;
+
+typedef enum _GXTevRegID {
+ GX_TEVPREV,
+ GX_TEVREG0,
+ GX_TEVREG1,
+ GX_TEVREG2,
+ GX_MAX_TEVREG,
+} GXTevRegID;
+
+typedef enum _GXDiffuseFn {
+ GX_DF_NONE,
+ GX_DF_SIGN,
+ GX_DF_CLAMP,
+} GXDiffuseFn;
+
+typedef enum _GXColorSrc {
+ GX_SRC_REG,
+ GX_SRC_VTX,
+} GXColorSrc;
+
+typedef enum _GXAttnFn {
+ GX_AF_SPEC,
+ GX_AF_SPOT,
+ GX_AF_NONE,
+} GXAttnFn;
+
+typedef enum _GXLightID {
+ GX_LIGHT0 = 0x001,
+ GX_LIGHT1 = 0x002,
+ GX_LIGHT2 = 0x004,
+ GX_LIGHT3 = 0x008,
+ GX_LIGHT4 = 0x010,
+ GX_LIGHT5 = 0x020,
+ GX_LIGHT6 = 0x040,
+ GX_LIGHT7 = 0x080,
+ GX_MAX_LIGHT = 0x100,
+ GX_LIGHT_NULL = 0,
+} GXLightID;
+
+typedef enum _GXTexOffset {
+ GX_TO_ZERO,
+ GX_TO_SIXTEENTH,
+ GX_TO_EIGHTH,
+ GX_TO_FOURTH,
+ GX_TO_HALF,
+ GX_TO_ONE,
+ GX_MAX_TEXOFFSET,
+} GXTexOffset;
+
+typedef enum _GXSpotFn {
+ GX_SP_OFF,
+ GX_SP_FLAT,
+ GX_SP_COS,
+ GX_SP_COS2,
+ GX_SP_SHARP,
+ GX_SP_RING1,
+ GX_SP_RING2,
+} GXSpotFn;
+
+typedef enum _GXDistAttnFn {
+ GX_DA_OFF,
+ GX_DA_GENTLE,
+ GX_DA_MEDIUM,
+ GX_DA_STEEP,
+} GXDistAttnFn;
+
+typedef enum _GXCullMode {
+ GX_CULL_NONE,
+ GX_CULL_FRONT,
+ GX_CULL_BACK,
+ GX_CULL_ALL,
+} GXCullMode;
+
+typedef enum _GXTevSwapSel {
+ GX_TEV_SWAP0 = 0,
+ GX_TEV_SWAP1,
+ GX_TEV_SWAP2,
+ GX_TEV_SWAP3,
+ GX_MAX_TEVSWAP,
+} GXTevSwapSel;
+
+typedef enum _GXTevColorChan {
+ GX_CH_RED = 0,
+ GX_CH_GREEN,
+ GX_CH_BLUE,
+ GX_CH_ALPHA,
+} GXTevColorChan;
+
+typedef enum _GXFogType {
+ GX_FOG_NONE = 0,
+ GX_FOG_PERSP_LIN = 2,
+ GX_FOG_PERSP_EXP = 4,
+ GX_FOG_PERSP_EXP2 = 5,
+ GX_FOG_PERSP_REVEXP = 6,
+ GX_FOG_PERSP_REVEXP2 = 7,
+ GX_FOG_ORTHO_LIN = 10,
+ GX_FOG_ORTHO_EXP = 12,
+ GX_FOG_ORTHO_EXP2 = 13,
+ GX_FOG_ORTHO_REVEXP = 14,
+ GX_FOG_ORTHO_REVEXP2 = 15,
+ GX_FOG_LIN = GX_FOG_PERSP_LIN,
+ GX_FOG_EXP = GX_FOG_PERSP_EXP,
+ GX_FOG_EXP2 = GX_FOG_PERSP_EXP2,
+ GX_FOG_REVEXP = GX_FOG_PERSP_REVEXP,
+ GX_FOG_REVEXP2 = GX_FOG_PERSP_REVEXP2,
+} GXFogType;
+
+typedef enum _GXTevColorArg {
+ GX_CC_CPREV,
+ GX_CC_APREV,
+ GX_CC_C0,
+ GX_CC_A0,
+ GX_CC_C1,
+ GX_CC_A1,
+ GX_CC_C2,
+ GX_CC_A2,
+ GX_CC_TEXC,
+ GX_CC_TEXA,
+ GX_CC_RASC,
+ GX_CC_RASA,
+ GX_CC_ONE,
+ GX_CC_HALF,
+ GX_CC_KONST,
+ GX_CC_ZERO,
+} GXTevColorArg;
+
+typedef enum _GXTevAlphaArg {
+ GX_CA_APREV,
+ GX_CA_A0,
+ GX_CA_A1,
+ GX_CA_A2,
+ GX_CA_TEXA,
+ GX_CA_RASA,
+ GX_CA_KONST,
+ GX_CA_ZERO,
+} GXTevAlphaArg;
+
+typedef enum _GXTevOp {
+ GX_TEV_ADD = 0,
+ GX_TEV_SUB = 1,
+ GX_TEV_COMP_R8_GT = 8,
+ GX_TEV_COMP_R8_EQ = 9,
+ GX_TEV_COMP_GR16_GT = 10,
+ GX_TEV_COMP_GR16_EQ = 11,
+ GX_TEV_COMP_BGR24_GT = 12,
+ GX_TEV_COMP_BGR24_EQ = 13,
+ GX_TEV_COMP_RGB8_GT = 14,
+ GX_TEV_COMP_RGB8_EQ = 15,
+ GX_TEV_COMP_A8_GT = GX_TEV_COMP_RGB8_GT,
+ GX_TEV_COMP_A8_EQ = GX_TEV_COMP_RGB8_EQ,
+} GXTevOp;
+
+typedef enum _GXTevBias {
+ GX_TB_ZERO,
+ GX_TB_ADDHALF,
+ GX_TB_SUBHALF,
+ GX_MAX_TEVBIAS,
+} GXTevBias;
+
+typedef enum _GXTevScale {
+ GX_CS_SCALE_1,
+ GX_CS_SCALE_2,
+ GX_CS_SCALE_4,
+ GX_CS_DIVIDE_2,
+ GX_MAX_TEVSCALE,
+} GXTevScale;
+
+typedef enum _GXTevKColorSel {
+ GX_TEV_KCSEL_8_8 = 0x00,
+ GX_TEV_KCSEL_7_8 = 0x01,
+ GX_TEV_KCSEL_6_8 = 0x02,
+ GX_TEV_KCSEL_5_8 = 0x03,
+ GX_TEV_KCSEL_4_8 = 0x04,
+ GX_TEV_KCSEL_3_8 = 0x05,
+ GX_TEV_KCSEL_2_8 = 0x06,
+ GX_TEV_KCSEL_1_8 = 0x07,
+ GX_TEV_KCSEL_1 = GX_TEV_KCSEL_8_8,
+ GX_TEV_KCSEL_3_4 = GX_TEV_KCSEL_6_8,
+ GX_TEV_KCSEL_1_2 = GX_TEV_KCSEL_4_8,
+ GX_TEV_KCSEL_1_4 = GX_TEV_KCSEL_2_8,
+ GX_TEV_KCSEL_K0 = 0x0C,
+ GX_TEV_KCSEL_K1 = 0x0D,
+ GX_TEV_KCSEL_K2 = 0x0E,
+ GX_TEV_KCSEL_K3 = 0x0F,
+ GX_TEV_KCSEL_K0_R = 0x10,
+ GX_TEV_KCSEL_K1_R = 0x11,
+ GX_TEV_KCSEL_K2_R = 0x12,
+ GX_TEV_KCSEL_K3_R = 0x13,
+ GX_TEV_KCSEL_K0_G = 0x14,
+ GX_TEV_KCSEL_K1_G = 0x15,
+ GX_TEV_KCSEL_K2_G = 0x16,
+ GX_TEV_KCSEL_K3_G = 0x17,
+ GX_TEV_KCSEL_K0_B = 0x18,
+ GX_TEV_KCSEL_K1_B = 0x19,
+ GX_TEV_KCSEL_K2_B = 0x1A,
+ GX_TEV_KCSEL_K3_B = 0x1B,
+ GX_TEV_KCSEL_K0_A = 0x1C,
+ GX_TEV_KCSEL_K1_A = 0x1D,
+ GX_TEV_KCSEL_K2_A = 0x1E,
+ GX_TEV_KCSEL_K3_A = 0x1F,
+} GXTevKColorSel;
+
+typedef enum _GXTevKAlphaSel {
+ GX_TEV_KASEL_8_8 = 0x00,
+ GX_TEV_KASEL_7_8 = 0x01,
+ GX_TEV_KASEL_6_8 = 0x02,
+ GX_TEV_KASEL_5_8 = 0x03,
+ GX_TEV_KASEL_4_8 = 0x04,
+ GX_TEV_KASEL_3_8 = 0x05,
+ GX_TEV_KASEL_2_8 = 0x06,
+ GX_TEV_KASEL_1_8 = 0x07,
+ GX_TEV_KASEL_1 = GX_TEV_KASEL_8_8,
+ GX_TEV_KASEL_3_4 = GX_TEV_KASEL_6_8,
+ GX_TEV_KASEL_1_2 = GX_TEV_KASEL_4_8,
+ GX_TEV_KASEL_1_4 = GX_TEV_KASEL_2_8,
+ GX_TEV_KASEL_K0_R = 0x10,
+ GX_TEV_KASEL_K1_R = 0x11,
+ GX_TEV_KASEL_K2_R = 0x12,
+ GX_TEV_KASEL_K3_R = 0x13,
+ GX_TEV_KASEL_K0_G = 0x14,
+ GX_TEV_KASEL_K1_G = 0x15,
+ GX_TEV_KASEL_K2_G = 0x16,
+ GX_TEV_KASEL_K3_G = 0x17,
+ GX_TEV_KASEL_K0_B = 0x18,
+ GX_TEV_KASEL_K1_B = 0x19,
+ GX_TEV_KASEL_K2_B = 0x1A,
+ GX_TEV_KASEL_K3_B = 0x1B,
+ GX_TEV_KASEL_K0_A = 0x1C,
+ GX_TEV_KASEL_K1_A = 0x1D,
+ GX_TEV_KASEL_K2_A = 0x1E,
+ GX_TEV_KASEL_K3_A = 0x1F,
+} GXTevKAlphaSel;
+
+typedef enum _GXTevKColorID {
+ GX_KCOLOR0 = 0,
+ GX_KCOLOR1,
+ GX_KCOLOR2,
+ GX_KCOLOR3,
+ GX_MAX_KCOLOR,
+} GXTevKColorID;
+
+typedef enum _GXZTexOp {
+ GX_ZT_DISABLE,
+ GX_ZT_ADD,
+ GX_ZT_REPLACE,
+ GX_MAX_ZTEXOP,
+} GXZTexOp;
+
+typedef enum _GXIndTexFormat {
+ GX_ITF_8,
+ GX_ITF_5,
+ GX_ITF_4,
+ GX_ITF_3,
+ GX_MAX_ITFORMAT,
+} GXIndTexFormat;
+
+typedef enum _GXIndTexBiasSel {
+ GX_ITB_NONE,
+ GX_ITB_S,
+ GX_ITB_T,
+ GX_ITB_ST,
+ GX_ITB_U,
+ GX_ITB_SU,
+ GX_ITB_TU,
+ GX_ITB_STU,
+ GX_MAX_ITBIAS,
+} GXIndTexBiasSel;
+
+typedef enum _GXIndTexAlphaSel {
+ GX_ITBA_OFF,
+ GX_ITBA_S,
+ GX_ITBA_T,
+ GX_ITBA_U,
+ GX_MAX_ITBALPHA,
+} GXIndTexAlphaSel;
+
+typedef enum _GXIndTexMtxID {
+ GX_ITM_OFF,
+ GX_ITM_0,
+ GX_ITM_1,
+ GX_ITM_2,
+ GX_ITM_S0 = 5,
+ GX_ITM_S1,
+ GX_ITM_S2,
+ GX_ITM_T0 = 9,
+ GX_ITM_T1,
+ GX_ITM_T2,
+} GXIndTexMtxID;
+
+typedef enum _GXIndTexWrap {
+ GX_ITW_OFF,
+ GX_ITW_256,
+ GX_ITW_128,
+ GX_ITW_64,
+ GX_ITW_32,
+ GX_ITW_16,
+ GX_ITW_0,
+ GX_MAX_ITWRAP,
+} GXIndTexWrap;
+
+typedef enum _GXIndTexStageID {
+ GX_INDTEXSTAGE0,
+ GX_INDTEXSTAGE1,
+ GX_INDTEXSTAGE2,
+ GX_INDTEXSTAGE3,
+ GX_MAX_INDTEXSTAGE,
+} GXIndTexStageID;
+
+typedef enum _GXIndTexScale {
+ GX_ITS_1,
+ GX_ITS_2,
+ GX_ITS_4,
+ GX_ITS_8,
+ GX_ITS_16,
+ GX_ITS_32,
+ GX_ITS_64,
+ GX_ITS_128,
+ GX_ITS_256,
+ GX_MAX_ITSCALE,
+} GXIndTexScale;
+
+typedef enum _GXClipMode {
+ GX_CLIP_ENABLE = 0,
+ GX_CLIP_DISABLE = 1,
+} GXClipMode;
+
+typedef enum _GXTlut {
+ GX_TLUT0 = 0,
+ GX_TLUT1 = 1,
+ GX_TLUT2 = 2,
+ GX_TLUT3 = 3,
+ GX_TLUT4 = 4,
+ GX_TLUT5 = 5,
+ GX_TLUT6 = 6,
+ GX_TLUT7 = 7,
+ GX_TLUT8 = 8,
+ GX_TLUT9 = 9,
+ GX_TLUT10 = 10,
+ GX_TLUT11 = 11,
+ GX_TLUT12 = 12,
+ GX_TLUT13 = 13,
+ GX_TLUT14 = 14,
+ GX_TLUT15 = 15,
+ GX_BIGTLUT0 = 16,
+ GX_BIGTLUT1 = 17,
+ GX_BIGTLUT2 = 18,
+ GX_BIGTLUT3 = 19,
+} GXTlut;
+
+typedef enum _GXTlutFmt {
+ GX_TL_IA8,
+ GX_TL_RGB565,
+ GX_TL_RGB5A3,
+ GX_MAX_TLUTFMT,
+} GXTlutFmt;
+
+typedef enum _GXMiscToken {
+ GX_MT_NULL = 0,
+ GX_MT_XF_FLUSH = 1,
+ GX_MT_DL_SAVE_CONTEXT = 2,
+ GX_MT_ABORT_WAIT_COPYOUT = 3,
+} GXMiscToken;
+
+typedef enum _GXTexCacheSize {
+ GX_TEXCACHE_32K,
+ GX_TEXCACHE_128K,
+ GX_TEXCACHE_512K,
+ GX_TEXCACHE_NONE
+} GXTexCacheSize;
+
+typedef enum _GXPerf0 {
+ GX_PERF0_VERTICES,
+ GX_PERF0_CLIP_VTX,
+ GX_PERF0_CLIP_CLKS,
+ GX_PERF0_XF_WAIT_IN,
+ GX_PERF0_XF_WAIT_OUT,
+ GX_PERF0_XF_XFRM_CLKS,
+ GX_PERF0_XF_LIT_CLKS,
+ GX_PERF0_XF_BOT_CLKS,
+ GX_PERF0_XF_REGLD_CLKS,
+ GX_PERF0_XF_REGRD_CLKS,
+ GX_PERF0_CLIP_RATIO,
+
+ GX_PERF0_TRIANGLES,
+ GX_PERF0_TRIANGLES_CULLED,
+ GX_PERF0_TRIANGLES_PASSED,
+ GX_PERF0_TRIANGLES_SCISSORED,
+ GX_PERF0_TRIANGLES_0TEX,
+ GX_PERF0_TRIANGLES_1TEX,
+ GX_PERF0_TRIANGLES_2TEX,
+ GX_PERF0_TRIANGLES_3TEX,
+ GX_PERF0_TRIANGLES_4TEX,
+ GX_PERF0_TRIANGLES_5TEX,
+ GX_PERF0_TRIANGLES_6TEX,
+ GX_PERF0_TRIANGLES_7TEX,
+ GX_PERF0_TRIANGLES_8TEX,
+ GX_PERF0_TRIANGLES_0CLR,
+ GX_PERF0_TRIANGLES_1CLR,
+ GX_PERF0_TRIANGLES_2CLR,
+
+ GX_PERF0_QUAD_0CVG,
+ GX_PERF0_QUAD_NON0CVG,
+ GX_PERF0_QUAD_1CVG,
+ GX_PERF0_QUAD_2CVG,
+ GX_PERF0_QUAD_3CVG,
+ GX_PERF0_QUAD_4CVG,
+ GX_PERF0_AVG_QUAD_CNT,
+
+ GX_PERF0_CLOCKS,
+ GX_PERF0_NONE
+
+} GXPerf0;
+
+typedef enum _GXPerf1 {
+ GX_PERF1_TEXELS,
+ GX_PERF1_TX_IDLE,
+ GX_PERF1_TX_REGS,
+ GX_PERF1_TX_MEMSTALL,
+ GX_PERF1_TC_CHECK1_2,
+ GX_PERF1_TC_CHECK3_4,
+ GX_PERF1_TC_CHECK5_6,
+ GX_PERF1_TC_CHECK7_8,
+ GX_PERF1_TC_MISS,
+
+ GX_PERF1_VC_ELEMQ_FULL,
+ GX_PERF1_VC_MISSQ_FULL,
+ GX_PERF1_VC_MEMREQ_FULL,
+ GX_PERF1_VC_STATUS7,
+ GX_PERF1_VC_MISSREP_FULL,
+ GX_PERF1_VC_STREAMBUF_LOW,
+ GX_PERF1_VC_ALL_STALLS,
+ GX_PERF1_VERTICES,
+
+ GX_PERF1_FIFO_REQ,
+ GX_PERF1_CALL_REQ,
+ GX_PERF1_VC_MISS_REQ,
+ GX_PERF1_CP_ALL_REQ,
+
+ GX_PERF1_CLOCKS,
+ GX_PERF1_NONE
+
+} GXPerf1;
+
+typedef enum _GXVCachePerf {
+ GX_VC_POS,
+ GX_VC_NRM,
+ GX_VC_CLR0,
+ GX_VC_CLR1,
+ GX_VC_TEX0,
+ GX_VC_TEX1,
+ GX_VC_TEX2,
+ GX_VC_TEX3,
+ GX_VC_TEX4,
+ GX_VC_TEX5,
+ GX_VC_TEX6,
+ GX_VC_TEX7,
+ GX_VC_ALL = 0xf
+
+} GXVCachePerf;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXENUM
diff --git a/include/dolphin/gx/GXExtra.h b/include/dolphin/gx/GXExtra.h
new file mode 100644
index 0000000..afd29ca
--- /dev/null
+++ b/include/dolphin/gx/GXExtra.h
@@ -0,0 +1,36 @@
+#ifndef _DOLPHIN_GXEXTRA
+#define _DOLPHIN_GXEXTRA
+
+// Extra types for PC
+#ifdef TARGET_PC
+#include <dolphin/gx/GXStruct.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ float r;
+ float g;
+ float b;
+ float a;
+} GXColorF32;
+
+typedef enum {
+ GX_TF_R8_PC = 0x60,
+ GX_TF_RGBA8_PC = 0x61,
+} GXPCTexFmt;
+
+void GXDestroyTexObj(GXTexObj* obj);
+void GXDestroyTlutObj(GXTlutObj* obj);
+
+void GXColor4f32(float r, float g, float b, float a);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TARGET_PC
+
+#endif // _DOLPHIN_GXEXTRA
diff --git a/include/dolphin/gx/GXFifo.h b/include/dolphin/gx/GXFifo.h
new file mode 100644
index 0000000..85d6168
--- /dev/null
+++ b/include/dolphin/gx/GXFifo.h
@@ -0,0 +1,37 @@
+#ifndef _DOLPHIN_GXFIFO
+#define _DOLPHIN_GXFIFO
+
+#include <dolphin/gx/GXEnum.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ u8 pad[128];
+} GXFifoObj;
+
+typedef void (*GXBreakPtCallback)(void);
+
+void GXInitFifoBase(GXFifoObj* fifo, void* base, u32 size);
+void GXInitFifoPtrs(GXFifoObj* fifo, void* readPtr, void* writePtr);
+void GXGetFifoPtrs(GXFifoObj* fifo, void** readPtr, void** writePtr);
+GXFifoObj* GXGetCPUFifo(void);
+GXFifoObj* GXGetGPFifo(void);
+void GXSetCPUFifo(GXFifoObj* fifo);
+void GXSetGPFifo(GXFifoObj* fifo);
+void GXSaveCPUFifo(GXFifoObj* fifo);
+void GXGetFifoStatus(GXFifoObj* fifo, GXBool* overhi, GXBool* underlow, u32* fifoCount,
+ GXBool* cpu_write, GXBool* gp_read, GXBool* fifowrap);
+void GXGetGPStatus(GXBool* overhi, GXBool* underlow, GXBool* readIdle, GXBool* cmdIdle,
+ GXBool* brkpt);
+void GXInitFifoLimits(GXFifoObj* fifo, u32 hiWaterMark, u32 loWaterMark);
+GXBreakPtCallback GXSetBreakPtCallback(GXBreakPtCallback cb);
+void GXEnableBreakPt(void* breakPt);
+void GXDisableBreakPt(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXFIFO
diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h
new file mode 100644
index 0000000..55b97bc
--- /dev/null
+++ b/include/dolphin/gx/GXFrameBuffer.h
@@ -0,0 +1,62 @@
+#ifndef _DOLPHIN_GXFRAMEBUFFER
+#define _DOLPHIN_GXFRAMEBUFFER
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/gx/GXStruct.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// extern GXRenderModeObj GXNtsc240Ds;
+// extern GXRenderModeObj GXNtsc240DsAa;
+// extern GXRenderModeObj GXNtsc240Int;
+// extern GXRenderModeObj GXNtsc240IntAa;
+extern GXRenderModeObj GXNtsc480IntDf;
+// extern GXRenderModeObj GXNtsc480Int;
+// extern GXRenderModeObj GXNtsc480IntAa;
+// extern GXRenderModeObj GXNtsc480Prog;
+// extern GXRenderModeObj GXNtsc480ProgSoft;
+// extern GXRenderModeObj GXNtsc480ProgAa;
+// extern GXRenderModeObj GXMpal240Ds;
+// extern GXRenderModeObj GXMpal240DsAa;
+// extern GXRenderModeObj GXMpal240Int;
+// extern GXRenderModeObj GXMpal240IntAa;
+extern GXRenderModeObj GXMpal480IntDf;
+// extern GXRenderModeObj GXMpal480Int;
+// extern GXRenderModeObj GXMpal480IntAa;
+// extern GXRenderModeObj GXPal264Ds;
+// extern GXRenderModeObj GXPal264DsAa;
+// extern GXRenderModeObj GXPal264Int;
+// extern GXRenderModeObj GXPal264IntAa;
+extern GXRenderModeObj GXPal528IntDf;
+// extern GXRenderModeObj GXPal528Int;
+// extern GXRenderModeObj GXPal524IntAa;
+// extern GXRenderModeObj GXEurgb60Hz240Ds;
+// extern GXRenderModeObj GXEurgb60Hz240DsAa;
+// extern GXRenderModeObj GXEurgb60Hz240Int;
+// extern GXRenderModeObj GXEurgb60Hz240IntAa;
+extern GXRenderModeObj GXEurgb60Hz480IntDf;
+// extern GXRenderModeObj GXEurgb60Hz480Int;
+// extern GXRenderModeObj GXEurgb60Hz480IntAa;
+
+#define GX_MAX_Z24 0x00FFFFFF
+
+void GXSetCopyClear(GXColor clear_clr, u32 clear_z);
+void GXAdjustForOverscan(GXRenderModeObj* rmin, GXRenderModeObj* rmout, u16 hor, u16 ver);
+void GXCopyDisp(void* dest, GXBool clear);
+void GXSetDispCopyGamma(GXGamma gamma);
+void GXSetDispCopySrc(u16 left, u16 top, u16 wd, u16 ht);
+void GXSetDispCopyDst(u16 wd, u16 ht);
+u32 GXSetDispCopyYScale(f32 vscale);
+void GXSetCopyFilter(GXBool aa, u8 sample_pattern[12][2], GXBool vf, u8 vfilter[7]);
+void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt);
+void GXSetTexCopySrc(u16 left, u16 top, u16 wd, u16 ht);
+void GXSetTexCopyDst(u16 wd, u16 ht, GXTexFmt fmt, GXBool mipmap);
+void GXCopyTex(void* dest, GXBool clear);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXFRAMEBUFFER
diff --git a/include/dolphin/gx/GXGeometry.h b/include/dolphin/gx/GXGeometry.h
new file mode 100644
index 0000000..632ebc6
--- /dev/null
+++ b/include/dolphin/gx/GXGeometry.h
@@ -0,0 +1,37 @@
+#ifndef _DOLPHIN_GXGEOMETRY
+#define _DOLPHIN_GXGEOMETRY
+
+#include <dolphin/gx/GXEnum.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXSetVtxDesc(GXAttr attr, GXAttrType type);
+void GXSetVtxDescv(GXVtxDescList* list);
+void GXClearVtxDesc(void);
+void GXSetVtxAttrFmt(GXVtxFmt vtxfmt, GXAttr attr, GXCompCnt cnt, GXCompType type, u8 frac);
+void GXSetNumTexGens(u8 nTexGens);
+void GXBegin(GXPrimitive type, GXVtxFmt vtxfmt, u16 nverts);
+void GXSetTexCoordGen2(GXTexCoordID dst_coord, GXTexGenType func, GXTexGenSrc src_param, u32 mtx,
+ GXBool normalize, u32 postmtx);
+void GXSetLineWidth(u8 width, GXTexOffset texOffsets);
+void GXSetPointSize(u8 pointSize, GXTexOffset texOffsets);
+void GXEnableTexOffsets(GXTexCoordID coord, GXBool line_enable, GXBool point_enable);
+#ifdef TARGET_PC
+void GXSetArray(GXAttr attr, const void* data, u32 size, u8 stride);
+#else
+void GXSetArray(GXAttr attr, const void* data, u8 stride);
+#endif
+void GXInvalidateVtxCache(void);
+
+static inline void GXSetTexCoordGen(GXTexCoordID dst_coord, GXTexGenType func,
+ GXTexGenSrc src_param, u32 mtx) {
+ GXSetTexCoordGen2(dst_coord, func, src_param, mtx, GX_FALSE, GX_PTIDENTITY);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXGEOMETRY
diff --git a/include/dolphin/gx/GXGet.h b/include/dolphin/gx/GXGet.h
new file mode 100644
index 0000000..1eff8eb
--- /dev/null
+++ b/include/dolphin/gx/GXGet.h
@@ -0,0 +1,28 @@
+#ifndef _DOLPHIN_GXGET
+#define _DOLPHIN_GXGET
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/gx/GXStruct.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GXBool GXGetTexObjMipMap(const GXTexObj* obj);
+GXTexFmt GXGetTexObjFmt(const GXTexObj* obj);
+u16 GXGetTexObjHeight(const GXTexObj* obj);
+u16 GXGetTexObjWidth(const GXTexObj* obj);
+GXTexWrapMode GXGetTexObjWrapS(const GXTexObj* obj);
+GXTexWrapMode GXGetTexObjWrapT(const GXTexObj* obj);
+void* GXGetTexObjData(const GXTexObj* obj);
+void GXGetProjectionv(f32* p);
+void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z);
+void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color);
+void GXGetVtxAttrFmt(GXVtxFmt idx, GXAttr attr, GXCompCnt* compCnt, GXCompType* compType,
+ u8* shift);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXGET
diff --git a/include/dolphin/gx/GXLighting.h b/include/dolphin/gx/GXLighting.h
new file mode 100644
index 0000000..a7e0ccc
--- /dev/null
+++ b/include/dolphin/gx/GXLighting.h
@@ -0,0 +1,32 @@
+#ifndef _DOLPHIN_GXLIGHTING
+#define _DOLPHIN_GXLIGHTING
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/gx/GXStruct.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXSetNumChans(u8 nChans);
+void GXSetChanCtrl(GXChannelID chan, GXBool enable, GXColorSrc amb_src, GXColorSrc mat_src,
+ u32 light_mask, GXDiffuseFn diff_fn, GXAttnFn attn_fn);
+void GXSetChanAmbColor(GXChannelID chan, GXColor amb_color);
+void GXSetChanMatColor(GXChannelID chan, GXColor mat_color);
+
+void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func);
+void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_distance, f32 ref_brightness,
+ GXDistAttnFn dist_func);
+void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z);
+void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz);
+void GXInitLightColor(GXLightObj* lt_obj, GXColor color);
+void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2);
+void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2);
+void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2);
+void GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXLIGHTING
diff --git a/include/dolphin/gx/GXManage.h b/include/dolphin/gx/GXManage.h
new file mode 100644
index 0000000..ab3a72c
--- /dev/null
+++ b/include/dolphin/gx/GXManage.h
@@ -0,0 +1,24 @@
+#ifndef _DOLPHIN_GXMANAGE
+#define _DOLPHIN_GXMANAGE
+
+#include <dolphin/gx/GXFifo.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*GXDrawDoneCallback)(void);
+
+GXFifoObj* GXInit(void* base, u32 size);
+GXDrawDoneCallback GXSetDrawDoneCallback(GXDrawDoneCallback cb);
+void GXDrawDone(void);
+void GXSetDrawDone(void);
+void GXFlush(void);
+void GXPixModeSync(void);
+void GXSetMisc(GXMiscToken token, u32 val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXMANAGE
diff --git a/include/dolphin/gx/GXPerf.h b/include/dolphin/gx/GXPerf.h
new file mode 100644
index 0000000..c3850dc
--- /dev/null
+++ b/include/dolphin/gx/GXPerf.h
@@ -0,0 +1,16 @@
+#ifndef _DOLPHIN_GXPERF
+#define _DOLPHIN_GXPERF
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXReadXfRasMetric(u32* xf_wait_in, u32* xf_wait_out, u32* ras_busy, u32* clocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXPERF
diff --git a/include/dolphin/gx/GXPixel.h b/include/dolphin/gx/GXPixel.h
new file mode 100644
index 0000000..7dfae08
--- /dev/null
+++ b/include/dolphin/gx/GXPixel.h
@@ -0,0 +1,29 @@
+#ifndef _DOLPHIN_GXPIXEL
+#define _DOLPHIN_GXPIXEL
+
+#include <dolphin/gx/GXEnum.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color);
+void GXSetFogColor(GXColor color);
+// ? GXSetFogRangeAdj();
+void GXSetBlendMode(GXBlendMode type, GXBlendFactor src_factor, GXBlendFactor dst_factor,
+ GXLogicOp op);
+void GXSetColorUpdate(GXBool update_enable);
+void GXSetAlphaUpdate(GXBool update_enable);
+void GXSetZMode(GXBool compare_enable, GXCompare func, GXBool update_enable);
+void GXSetZCompLoc(GXBool before_tex);
+void GXSetPixelFmt(GXPixelFmt pix_fmt, GXZFmt16 z_fmt);
+void GXSetDither(GXBool dither);
+void GXSetDstAlpha(GXBool enable, u8 alpha);
+// ? GXSetFieldMask();
+// ? GXSetFieldMode();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXPIXEL
diff --git a/include/dolphin/gx/GXPriv.h b/include/dolphin/gx/GXPriv.h
new file mode 100644
index 0000000..db0286b
--- /dev/null
+++ b/include/dolphin/gx/GXPriv.h
@@ -0,0 +1,38 @@
+#ifndef _DOLPHIN_GXPRIV
+#define _DOLPHIN_GXPRIV
+
+#include "dolphin/gx/GXVert.h"
+
+typedef struct GXLightObj_ {
+ u32 padding[3];
+ u32 color;
+ float a0;
+ float a1;
+ float a2;
+ float k0;
+ float k1;
+ float k2;
+ float px;
+ float py;
+ float pz;
+ float nx;
+ float ny;
+ float nz;
+} GXLightObj_;
+
+#define XF_LIGHT_BASE 0x0600
+#define XF_LIGHT_SIZE 0x10
+
+#define GX_FIFO_ADDR 0xCC008000
+
+#define GX_WRITE_U8(v) (GXWGFifo.u8 = v)
+#define GX_WRITE_U32(v) (GXWGFifo.u32 = v)
+
+typedef struct GXData {
+ u16 cpSRreg;
+ u16 cpCRreg;
+} GXData;
+
+extern GXData* __GXData;
+
+#endif // _DOLPHIN_GXPRIV
diff --git a/include/dolphin/gx/GXStruct.h b/include/dolphin/gx/GXStruct.h
new file mode 100644
index 0000000..eebc736
--- /dev/null
+++ b/include/dolphin/gx/GXStruct.h
@@ -0,0 +1,108 @@
+#ifndef _DOLPHIN_GXSTRUCT
+#define _DOLPHIN_GXSTRUCT
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VI_TVMODE(format, interlace) (((format) << 2) + (interlace))
+
+#define VI_INTERLACE 0
+#define VI_NON_INTERLACE 1
+#define VI_PROGRESSIVE 2
+
+#define VI_NTSC 0
+#define VI_PAL 1
+#define VI_MPAL 2
+#define VI_DEBUG 3
+#define VI_DEBUG_PAL 4
+#define VI_EURGB60 5
+
+typedef enum {
+ VI_TVMODE_NTSC_INT = VI_TVMODE(VI_NTSC, VI_INTERLACE),
+ VI_TVMODE_NTSC_DS = VI_TVMODE(VI_NTSC, VI_NON_INTERLACE),
+ VI_TVMODE_NTSC_PROG = VI_TVMODE(VI_NTSC, VI_PROGRESSIVE),
+ VI_TVMODE_PAL_INT = VI_TVMODE(VI_PAL, VI_INTERLACE),
+ VI_TVMODE_PAL_DS = VI_TVMODE(VI_PAL, VI_NON_INTERLACE),
+ VI_TVMODE_EURGB60_INT = VI_TVMODE(VI_EURGB60, VI_INTERLACE),
+ VI_TVMODE_EURGB60_DS = VI_TVMODE(VI_EURGB60, VI_NON_INTERLACE),
+ VI_TVMODE_MPAL_INT = VI_TVMODE(VI_MPAL, VI_INTERLACE),
+ VI_TVMODE_MPAL_DS = VI_TVMODE(VI_MPAL, VI_NON_INTERLACE),
+ VI_TVMODE_DEBUG_INT = VI_TVMODE(VI_DEBUG, VI_INTERLACE),
+ VI_TVMODE_DEBUG_PAL_INT = VI_TVMODE(VI_DEBUG_PAL, VI_INTERLACE),
+ VI_TVMODE_DEBUG_PAL_DS = VI_TVMODE(VI_DEBUG_PAL, VI_NON_INTERLACE)
+} VITVMode;
+
+typedef enum { VI_XFBMODE_SF = 0, VI_XFBMODE_DF } VIXFBMode;
+
+typedef struct _GXRenderModeObj {
+ /*0x00*/ VITVMode viTVmode;
+ /*0x04*/ u16 fbWidth;
+ /*0x06*/ u16 efbHeight;
+ /*0x08*/ u16 xfbHeight;
+ /*0x0A*/ u16 viXOrigin;
+ /*0x0C*/ u16 viYOrigin;
+ /*0x0E*/ u16 viWidth;
+ /*0x10*/ u16 viHeight;
+ /*0x14*/ VIXFBMode xFBmode;
+ /*0x18*/ u8 field_rendering;
+ u8 aa;
+ u8 sample_pattern[12][2];
+ u8 vfilter[7];
+} GXRenderModeObj;
+
+typedef struct _GXColor {
+ u8 r;
+ u8 g;
+ u8 b;
+ u8 a;
+} GXColor;
+
+typedef struct _GXTexObj {
+#ifdef TARGET_PC
+ u32 dummy[22];
+#else
+ u32 dummy[8];
+#endif
+} GXTexObj;
+
+typedef struct _GXTlutObj {
+#ifdef TARGET_PC
+ u32 dummy[4];
+#else
+ u32 dummy[3];
+#endif
+} GXTlutObj;
+
+typedef struct _GXLightObj {
+ u32 dummy[16];
+} GXLightObj;
+
+typedef struct _GXVtxDescList {
+ GXAttr attr;
+ GXAttrType type;
+} GXVtxDescList;
+
+typedef struct _GXColorS10 {
+ s16 r;
+ s16 g;
+ s16 b;
+ s16 a;
+} GXColorS10;
+
+typedef struct _GXTexRegion {
+ u32 dummy[4];
+} GXTexRegion;
+
+typedef struct _GXTlutRegion {
+ u32 dummy[4];
+} GXTlutRegion;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXSTRUCT
diff --git a/include/dolphin/gx/GXTev.h b/include/dolphin/gx/GXTev.h
new file mode 100644
index 0000000..01290a9
--- /dev/null
+++ b/include/dolphin/gx/GXTev.h
@@ -0,0 +1,37 @@
+#ifndef _DOLPHIN_GXTEV
+#define _DOLPHIN_GXTEV
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/gx/GXStruct.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GXSetTevOp(GXTevStageID id, GXTevMode mode);
+void GXSetTevColorIn(GXTevStageID stage, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c,
+ GXTevColorArg d);
+void GXSetTevAlphaIn(GXTevStageID stage, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c,
+ GXTevAlphaArg d);
+void GXSetTevColorOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp,
+ GXTevRegID out_reg);
+void GXSetTevAlphaOp(GXTevStageID stage, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp,
+ GXTevRegID out_reg);
+void GXSetTevColor(GXTevRegID id, GXColor color);
+void GXSetTevColorS10(GXTevRegID id, GXColorS10 color);
+void GXSetTevKColor(GXTevKColorID id, GXColor color);
+void GXSetTevKColorSel(GXTevStageID stage, GXTevKColorSel sel);
+void GXSetTevKAlphaSel(GXTevStageID stage, GXTevKAlphaSel sel);
+void GXSetTevSwapMode(GXTevStageID stage, GXTevSwapSel ras_sel, GXTevSwapSel tex_sel);
+void GXSetTevSwapModeTable(GXTevSwapSel table, GXTevColorChan red, GXTevColorChan green,
+ GXTevColorChan blue, GXTevColorChan alpha);
+void GXSetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1);
+void GXSetZTexture(GXZTexOp op, GXTexFmt fmt, u32 bias);
+void GXSetTevOrder(GXTevStageID stage, GXTexCoordID coord, GXTexMapID map, GXChannelID color);
+void GXSetNumTevStages(u8 nStages);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXTEV
diff --git a/include/dolphin/gx/GXTexture.h b/include/dolphin/gx/GXTexture.h
new file mode 100644
index 0000000..44a3861
--- /dev/null
+++ b/include/dolphin/gx/GXTexture.h
@@ -0,0 +1,37 @@
+#ifndef _DOLPHIN_GXTEXTURE
+#define _DOLPHIN_GXTEXTURE
+
+#include <dolphin/gx/GXEnum.h>
+#include <dolphin/gx/GXStruct.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id);
+
+void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, u32 format,
+ GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap);
+void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format,
+ GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut);
+void GXInitTexObjData(GXTexObj* obj, const void* data);
+void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod,
+ f32 max_lod, f32 lod_bias, GXBool bias_clamp, GXBool do_edge_lod,
+ GXAnisotropy max_aniso);
+void GXLoadTexObj(GXTexObj* obj, GXTexMapID id);
+u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod);
+void GXInvalidateTexAll();
+void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t);
+void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entries);
+void GXLoadTlut(const GXTlutObj* obj, GXTlut idx);
+void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts);
+void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even,
+ GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd);
+GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback);
+void GXInvalidateTexRegion(const GXTexRegion* region);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXTEXTURE
diff --git a/include/dolphin/gx/GXTransform.h b/include/dolphin/gx/GXTransform.h
new file mode 100644
index 0000000..bc3bf10
--- /dev/null
+++ b/include/dolphin/gx/GXTransform.h
@@ -0,0 +1,33 @@
+#ifndef _DOLPHIN_GXTRANSFORM
+#define _DOLPHIN_GXTRANSFORM
+
+#include <dolphin/gx/GXEnum.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GX_PROJECTION_SZ 7
+
+#ifdef TARGET_PC
+void GXSetProjection(const void* mtx, GXProjectionType type);
+void GXLoadPosMtxImm(const void* mtx, u32 id);
+void GXLoadNrmMtxImm(const void* mtx, u32 id);
+void GXLoadTexMtxImm(const void* mtx, u32 id, GXTexMtxType type);
+#else
+void GXSetProjection(f32 mtx[4][4], GXProjectionType type);
+void GXLoadPosMtxImm(f32 mtx[3][4], u32 id);
+void GXLoadNrmMtxImm(f32 mtx[3][4], u32 id);
+void GXLoadTexMtxImm(f32 mtx[][4], u32 id, GXTexMtxType type);
+#endif
+void GXSetViewport(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz);
+void GXSetCurrentMtx(u32 id);
+void GXSetViewportJitter(f32 left, f32 top, f32 wd, f32 ht, f32 nearz, f32 farz, u32 field);
+void GXSetScissorBoxOffset(s32 x_off, s32 y_off);
+void GXSetClipMode(GXClipMode mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXTRANSFORM
diff --git a/include/dolphin/gx/GXVert.h b/include/dolphin/gx/GXVert.h
new file mode 100644
index 0000000..af0eec3
--- /dev/null
+++ b/include/dolphin/gx/GXVert.h
@@ -0,0 +1,141 @@
+#ifndef _DOLPHIN_GXVERT
+#define _DOLPHIN_GXVERT
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GXFIFO_ADDR 0xCC008000
+
+typedef union {
+ u8 u8;
+ u16 u16;
+ u32 u32;
+ u64 u64;
+ s8 s8;
+ s16 s16;
+ s32 s32;
+ s64 s64;
+ f32 f32;
+ f64 f64;
+} PPCWGPipe;
+
+#ifdef __MWERKS__
+/*volatile*/ PPCWGPipe GXWGFifo : GXFIFO_ADDR;
+#else
+#define GXWGFifo (*(volatile PPCWGPipe*)GXFIFO_ADDR)
+#endif
+
+#ifdef TARGET_PC
+
+void GXPosition3f32(f32 x, f32 y, f32 z);
+void GXPosition3u16(u16 x, u16 y, u16 z);
+void GXPosition3s16(s16 x, s16 y, s16 z);
+void GXPosition3u8(u8 x, u8 y, u8 z);
+void GXPosition3s8(s8 x, s8 y, s8 z);
+
+void GXPosition2f32(f32 x, f32 y);
+void GXPosition2u16(u16 x, u16 y);
+void GXPosition2s16(s16 x, s16 y);
+void GXPosition2u8(u8 x, u8 y);
+void GXPosition2s8(s8 x, s8 y);
+
+void GXPosition1x16(u16 index);
+void GXPosition1x8(u8 index);
+
+void GXNormal3f32(f32 x, f32 y, f32 z);
+void GXNormal3s16(s16 x, s16 y, s16 z);
+void GXNormal3s8(s8 x, s8 y, s8 z);
+
+void GXNormal1x16(u16 index);
+void GXNormal1x8(u8 index);
+
+void GXColor4u8(u8 r, u8 g, u8 b, u8 a);
+
+void GXColor3u8(u8 r, u8 g, u8 b);
+
+void GXColor1u32(u32 clr);
+void GXColor1u16(u16 clr);
+
+void GXColor1x16(u16 index);
+void GXColor1x8(u8 index);
+
+void GXTexCoord2f32(f32 s, f32 t);
+void GXTexCoord2u16(u16 s, u16 t);
+void GXTexCoord2s16(s16 s, s16 t);
+void GXTexCoord2u8(u8 s, u8 t);
+void GXTexCoord2s8(s8 s, s8 t);
+
+void GXTexCoord1f32(f32 s, f32 t);
+void GXTexCoord1u16(u16 s, u16 t);
+void GXTexCoord1s16(s16 s, s16 t);
+void GXTexCoord1u8(u8 s, u8 t);
+void GXTexCoord1s8(s8 s, s8 t);
+
+void GXTexCoord1x16(u16 index);
+void GXTexCoord1x8(u8 index);
+
+extern void GXEnd(void);
+
+#else
+
+static inline void GXPosition2f32(const f32 x, const f32 y) {
+ GXWGFifo.f32 = x;
+ GXWGFifo.f32 = y;
+}
+
+static inline void GXPosition3s16(const s16 x, const s16 y, const s16 z) {
+ GXWGFifo.s16 = x;
+ GXWGFifo.s16 = y;
+ GXWGFifo.s16 = z;
+}
+
+static inline void GXPosition3f32(const f32 x, const f32 y, const f32 z) {
+ GXWGFifo.f32 = x;
+ GXWGFifo.f32 = y;
+ GXWGFifo.f32 = z;
+}
+
+static inline void GXNormal3f32(const f32 x, const f32 y, const f32 z) {
+ GXWGFifo.f32 = x;
+ GXWGFifo.f32 = y;
+ GXWGFifo.f32 = z;
+}
+
+static inline void GXColor1u32(const u32 v) {
+ GXWGFifo.u32 = v;
+}
+
+static inline void GXColor4u8(const u8 r, const u8 g, const u8 b, const u8 a) {
+ GXWGFifo.u8 = r;
+ GXWGFifo.u8 = g;
+ GXWGFifo.u8 = b;
+ GXWGFifo.u8 = a;
+}
+
+static inline void GXTexCoord2s16(const s16 u, const s16 v) {
+ GXWGFifo.s16 = u;
+ GXWGFifo.s16 = v;
+}
+
+static inline void GXTexCoord2f32(const f32 u, const f32 v) {
+ GXWGFifo.f32 = u;
+ GXWGFifo.f32 = v;
+}
+
+
+static inline void GXPosition1x8(u8 index) {
+ GXWGFifo.u8 = index;
+}
+
+static inline void GXEnd(void) {}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_GXVERT
diff --git a/include/dolphin/mtx.h b/include/dolphin/mtx.h
new file mode 100644
index 0000000..f57beea
--- /dev/null
+++ b/include/dolphin/mtx.h
@@ -0,0 +1,145 @@
+#ifndef _DOLPHIN_MTX
+#define _DOLPHIN_MTX
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef f32 Mtx[3][4];
+typedef f32 (*MtxPtr)[4];
+typedef f32 ROMtx[4][3];
+typedef f32 (*ROMtxPtr)[3];
+typedef f32 Mtx44[4][4];
+typedef f32 (*Mtx44Ptr)[4];
+
+typedef struct {
+ f32 x, y, z;
+} Vec, *VecPtr;
+
+typedef struct {
+ s16 x, y, z;
+} S16Vec, *S16VecPtr;
+
+typedef struct {
+ f32 x, y, z, w;
+} Quaternion, *QuaternionPtr;
+
+void C_MTXIdentity(Mtx m);
+void C_MTXCopy(const Mtx src, Mtx dst);
+void C_MTXConcat(const Mtx a, const Mtx b, Mtx ab);
+void C_MTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count);
+void C_MTXTranspose(const Mtx src, Mtx xPose);
+u32 C_MTXInverse(const Mtx src, Mtx inv);
+u32 C_MTXInvXpose(const Mtx src, Mtx invX);
+void C_MTXMultVec(const Mtx m, const Vec* src, Vec* dst);
+void C_MTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count);
+void C_MTXMultVecSR(const Mtx m, const Vec* src, Vec* dst);
+void C_MTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count);
+void C_MTXQuat(Mtx m, const Quaternion* q);
+void C_MTXReflect(Mtx m, const Vec* p, const Vec* n);
+void C_MTXTrans(Mtx m, f32 xT, f32 yT, f32 zT);
+void C_MTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT);
+void C_MTXScale(Mtx m, f32 xS, f32 yS, f32 zS);
+void C_MTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS);
+void C_MTXRotRad(Mtx m, char axis, f32 rad);
+void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA);
+void C_MTXRotAxisRad(Mtx m, const Vec* axis, f32 rad);
+void C_MTXLookAt(Mtx m, const Vec* camPos, const Vec* camUp, const Vec* target);
+void C_MTXFrustum(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f);
+void C_MTXPerspective(Mtx44 m, f32 fovY, f32 aspect, f32 n, f32 f);
+void C_MTXOrtho(Mtx44 m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 f);
+void C_MTXLightFrustum(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 n, f32 scaleS, f32 scaleT, f32 transS,
+ f32 transT);
+
+void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, f32 scaleS, f32 scaleT, f32 transS,
+ f32 transT);
+
+void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 scaleT, f32 transS,
+ f32 transT);
+
+#ifdef __MWERKS__
+void PSMTXIdentity(Mtx m);
+void PSMTXCopy(const Mtx src, Mtx dst);
+void PSMTXConcat(const Mtx a, const Mtx b, Mtx ab);
+void PSMTXConcatArray(const Mtx a, const Mtx* srcBase, Mtx* dstBase, u32 count);
+void PSMTXTranspose(const Mtx src, Mtx xPose);
+u32 PSMTXInverse(const Mtx src, Mtx inv);
+u32 PSMTXInvXpose(const Mtx src, Mtx invX);
+void PSMTXMultVec(const Mtx m, const Vec* src, Vec* dst);
+void PSMTXMultVecArray(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count);
+void PSMTXMultVecSR(const Mtx m, const Vec* src, Vec* dst);
+void PSMTXMultVecArraySR(const Mtx m, const Vec* srcBase, Vec* dstBase, u32 count);
+void PSMTXQuat(Mtx m, const Quaternion* q);
+void PSMTXReflect(Mtx m, const Vec* p, const Vec* n);
+void PSMTXTrans(Mtx m, f32 xT, f32 yT, f32 zT);
+void PSMTXTransApply(const Mtx src, Mtx dst, f32 xT, f32 yT, f32 zT);
+void PSMTXScale(Mtx m, f32 xS, f32 yS, f32 zS);
+void PSMTXScaleApply(const Mtx src, Mtx dst, f32 xS, f32 yS, f32 zS);
+void PSMTXRotRad(Mtx m, char axis, f32 rad);
+void PSMTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA);
+void PSMTXRotAxisRad(Mtx m, const Vec* axis, f32 rad);
+#endif
+
+#ifdef __MWERKS__
+#define MTXIdentity PSMTXIdentity
+#define MTXCopy PSMTXCopy
+#define MTXConcat PSMTXConcat
+#define MTXConcatArray PSMTXConcatArray
+#define MTXTranspose PSMTXTranspose
+#define MTXInverse PSMTXInverse
+#define MTXInvXpose PSMTXInvXpose
+#define MTXMultVec PSMTXMultVec
+#define MTXMultVecArray PSMTXMultVecArray
+#define MTXMultVecSR PSMTXMultVecSR
+#define MTXMultVecArraySR PSMTXMultVecArraySR
+#define MTXQuat PSMTXQuat
+#define MTXReflect PSMTXReflect
+#define MTXTrans PSMTXTrans
+#define MTXTransApply PSMTXTransApply
+#define MTXScale PSMTXScale
+#define MTXScaleApply PSMTXScaleApply
+#define MTXRotRad PSMTXRotRad
+#define MTXRotTrig PSMTXRotTrig
+#define MTXRotAxisRad PSMTXRotAxisRad
+#define MTXRotDeg(m, axis, deg) PSMTXRotRad(m, axis, MTXDegToRad(deg))
+#define MTXRotAxisDeg(m, axis, deg) PSMTXRotAxisRad(m, axis, MTXDegToRad(deg))
+#else
+#define MTXIdentity C_MTXIdentity
+#define MTXCopy C_MTXCopy
+#define MTXConcat C_MTXConcat
+#define MTXConcatArray C_MTXConcatArray
+#define MTXTranspose C_MTXTranspose
+#define MTXInverse C_MTXInverse
+#define MTXInvXpose C_MTXInvXpose
+#define MTXMultVec C_MTXMultVec
+#define MTXMultVecArray C_MTXMultVecArray
+#define MTXMultVecSR C_MTXMultVecSR
+#define MTXMultVecArraySR C_MTXMultVecArraySR
+#define MTXQuat C_MTXQuat
+#define MTXReflect C_MTXReflect
+#define MTXTrans C_MTXTrans
+#define MTXTransApply C_MTXTransApply
+#define MTXScale C_MTXScale
+#define MTXScaleApply C_MTXScaleApply
+#define MTXRotRad C_MTXRotRad
+#define MTXRotTrig C_MTXRotTrig
+#define MTXRotAxisRad C_MTXRotAxisRad
+#define MTXRotDeg(m, axis, deg) C_MTXRotRad(m, axis, MTXDegToRad(deg))
+#define MTXRotAxisDeg(m, axis, deg) C_MTXRotAxisRad(m, axis, MTXDegToRad(deg))
+#endif
+
+#define MTXLookAt C_MTXLookAt
+#define MTXFrustum C_MTXFrustum
+#define MTXPerspective C_MTXPerspective
+#define MTXOrtho C_MTXOrtho
+#define MTXLightFrustum C_MTXLightFrustum
+#define MTXLightPerspective C_MTXLightPerspective
+#define MTXLightOrtho C_MTXLightOrtho
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_MTX
diff --git a/include/dolphin/os.h b/include/dolphin/os.h
new file mode 100644
index 0000000..8dadda8
--- /dev/null
+++ b/include/dolphin/os.h
@@ -0,0 +1,175 @@
+#ifndef _DOLPHIN_OS
+#define _DOLPHIN_OS
+
+#include <dolphin/gx.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+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
+#define OS_PHYSICAL_MASK 0x3FFF
+
+#define OS_BASE_CACHED (OS_CACHED_REGION_PREFIX << 16)
+#define OS_BASE_UNCACHED (OS_UNCACHED_REGION_PREFIX << 16)
+
+#ifdef __MWERKS__
+#define AT_ADDRESS(xyz) : (xyz)
+#else
+#define AT_ADDRESS
+#endif
+typedef s64 OSTime;
+typedef u32 OSTick;
+u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h
+u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h
+#define OS_BUS_CLOCK __OSBusClock
+#define OS_CORE_CLOCK __OSCoreClock
+#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4)
+
+#define OSPhysicalToCached(paddr) ((void*)((u32)(paddr) + OS_BASE_CACHED))
+#define OSPhysicalToUncached(paddr) ((void*)((u32)(paddr) + OS_BASE_UNCACHED))
+#define OSCachedToPhysical(caddr) ((u32)((u8*)(caddr)-OS_BASE_CACHED))
+#define OSUncachedToPhysical(ucaddr) ((u32)((u8*)(ucaddr)-OS_BASE_UNCACHED))
+#define OSCachedToUncached(caddr) ((void*)((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED)))
+#define OSUncachedToCached(ucaddr) ((void*)((u8*)(ucaddr) - (OS_BASE_UNCACHED - OS_BASE_CACHED)))
+
+#define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2)
+#define OSTicksToSeconds(ticks) ((ticks) / OS_TIMER_CLOCK)
+#define OSTicksToMilliseconds(ticks) ((ticks) / (OS_TIMER_CLOCK / 1000))
+#define OSTicksToMicroseconds(ticks) (((ticks)*8) / (OS_TIMER_CLOCK / 125000))
+#define OSTicksToNanoseconds(ticks) (((ticks)*8000) / (OS_TIMER_CLOCK / 125000))
+#define OSSecondsToTicks(sec) ((sec)*OS_TIMER_CLOCK)
+#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000))
+#define OSMicrosecondsToTicks(usec) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8)
+#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000)
+
+#define OSDiffTick(tick1, tick0) ((s32)(tick1) - (s32)(tick0))
+
+#define OSRoundUp32B(v) ((((u32)(v) + 31) & ~31))
+#define OSRoundDown32B(v) (((u32) (v)) & ~31)
+
+#define OSRoundUp32BPtr(v) (void *)OSRoundUp32B(v)
+#define OSRoundDown32BPtr(v) (void *)OSRoundDown32B(v)
+
+void* OSGetArenaHi(void);
+void* OSGetArenaLo(void);
+void OSSetArenaHi(void* newHi);
+void OSSetArenaLo(void* newLo);
+
+void* OSAllocFromArenaLo(u32 size, u32 align);
+void* OSAllocFromArenaHi(u32 size, u32 align);
+
+void OSInit();
+
+OSTime OSGetTime();
+OSTick OSGetTick();
+
+typedef struct OSCalendarTime {
+ int sec; // seconds after the minute [0, 61]
+ int min; // minutes after the hour [0, 59]
+ int hour; // hours since midnight [0, 23]
+ int mday; // day of the month [1, 31]
+ int mon; // month since January [0, 11]
+ int year; // years in AD [1, ...]
+ int wday; // days since Sunday [0, 6]
+ int yday; // days since January 1 [0, 365]
+
+ int msec; // milliseconds after the second [0,999]
+ int usec; // microseconds after the millisecond [0,999]
+} OSCalendarTime;
+
+OSTime OSCalendarTimeToTicks(OSCalendarTime* td);
+void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td);
+
+#define OS_CONSOLE_MASK 0xf0000000
+#define OS_CONSOLE_RETAIL 0x00000000
+#define OS_CONSOLE_DEVELOPMENT 0x10000000
+#define OS_CONSOLE_TDEV 0x20000000
+
+#define OS_CONSOLE_RETAIL4 0x00000004
+#define OS_CONSOLE_RETAIL3 0x00000003
+#define OS_CONSOLE_RETAIL2 0x00000002
+#define OS_CONSOLE_RETAIL1 0x00000001
+#define OS_CONSOLE_TDEVHW4 0x20000007
+#define OS_CONSOLE_TDEVHW3 0x20000006
+#define OS_CONSOLE_TDEVHW2 0x20000005
+#define OS_CONSOLE_TDEVHW1 0x20000004
+#define OS_CONSOLE_DEVHW4 0x10000007
+#define OS_CONSOLE_DEVHW3 0x10000006
+#define OS_CONSOLE_DEVHW2 0x10000005
+#define OS_CONSOLE_DEVHW1 0x10000004
+#define OS_CONSOLE_MINNOW 0x10000003
+#define OS_CONSOLE_ARTHUR 0x10000002
+#define OS_CONSOLE_PC_EMULATOR 0x10000001
+#define OS_CONSOLE_EMULATOR 0x10000000
+
+u32 OSGetConsoleType();
+
+#define OS_SOUND_MODE_MONO 0u
+#define OS_SOUND_MODE_STEREO 1u
+
+u32 OSGetSoundMode(void);
+void OSSetSoundMode(u32 mode);
+
+#define OS_PROGRESSIVE_MODE_OFF 0u
+#define OS_PROGRESSIVE_MODE_ON 1u
+
+u32 OSGetProgressiveMode(void);
+void OSSetProgressiveMode(u32 on);
+
+#define OS_LANG_ENGLISH 0u
+#define OS_LANG_GERMAN 1u
+#define OS_LANG_FRENCH 2u
+#define OS_LANG_SPANISH 3u
+#define OS_LANG_ITALIAN 4u
+#define OS_LANG_DUTCH 5u
+
+u8 OSGetLanguage(void);
+void OSSetLanguage(u8 language);
+
+#define OS_EURGB60_OFF 0u
+#define OS_EURGB60_ON 1u
+
+u32 OSGetEuRgb60Mode(void);
+void OSSetEuRgb60Mode(u32 on);
+
+void OSRegisterVersion(const char* id);
+
+BOOL OSDisableInterrupts(void);
+BOOL OSEnableInterrupts(void);
+BOOL OSRestoreInterrupts(BOOL level);
+
+void OSReport(const char* msg, ...);
+void OSPanic(const char* file, int line, const char* msg, ...);
+void OSFatal(GXColor fg, GXColor bg, const char* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <dolphin/os/OSAlarm.h>
+#include <dolphin/os/OSArena.h>
+#include <dolphin/os/OSCache.h>
+#include <dolphin/os/OSContext.h>
+#include <dolphin/os/OSError.h>
+#include <dolphin/os/OSException.h>
+#include <dolphin/os/OSExpansion.h>
+#include <dolphin/os/OSFastCast.h>
+#include <dolphin/os/OSFont.h>
+#include <dolphin/os/OSInterrupt.h>
+#include <dolphin/os/OSMemory.h>
+#include <dolphin/os/OSMessage.h>
+#include <dolphin/os/OSModule.h>
+#include <dolphin/os/OSMutex.h>
+#include <dolphin/os/OSReboot.h>
+#include <dolphin/os/OSReset.h>
+#include <dolphin/os/OSResetSW.h>
+#include <dolphin/os/OSSerial.h>
+#include <dolphin/os/OSThread.h>
+#endif // _DOLPHIN_OS
diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h
new file mode 100644
index 0000000..a0c9d38
--- /dev/null
+++ b/include/dolphin/os/OSAlarm.h
@@ -0,0 +1,39 @@
+#ifndef _DOLPHIN_OSALARM
+#define _DOLPHIN_OSALARM
+
+#include <dolphin/os/OSContext.h>
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct OSAlarm OSAlarm;
+typedef void (*OSAlarmHandler)(OSAlarm* alarm, OSContext* context);
+
+struct OSAlarm {
+ OSAlarmHandler handler;
+ u32 tag;
+ OSTime fire;
+ OSAlarm* prev;
+ OSAlarm* next;
+ OSTime period;
+ OSTime start;
+};
+
+void OSInitAlarm(void);
+void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler);
+void OSSetAlarmTag(OSAlarm* alarm, u32 tag);
+void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler);
+void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler);
+void OSCreateAlarm(OSAlarm* alarm);
+void OSCancelAlarm(OSAlarm* alarm);
+void OSCancelAlarms(u32 tag);
+
+BOOL OSCheckAlarmQueue(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSALARM
diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h
new file mode 100644
index 0000000..9dc1570
--- /dev/null
+++ b/include/dolphin/os/OSArena.h
@@ -0,0 +1,13 @@
+#ifndef _DOLPHIN_OSARENA
+#define _DOLPHIN_OSARENA
+
+#include <dolphin/types.h>
+
+void* OSGetArenaHi(void);
+void* OSGetArenaLo(void);
+void OSSetArenaHi(void* addr);
+void OSSetArenaLo(void* addr);
+void* OSAllocFromArenaLo(u32 size, u32 align);
+void* OSAllocFromArenaLo(u32 size, u32 align);
+
+#endif // _DOLPHIN_OSARENA
diff --git a/include/dolphin/os/OSBootInfo.h b/include/dolphin/os/OSBootInfo.h
new file mode 100644
index 0000000..e52a4ac
--- /dev/null
+++ b/include/dolphin/os/OSBootInfo.h
@@ -0,0 +1,39 @@
+#ifndef _DOLPHIN_OSBOOTINFO
+#define _DOLPHIN_OSBOOTINFO
+
+typedef struct OSBootInfo {
+ DVDDiskID DVDDiskID;
+ u32 magic;
+ u32 version;
+ u32 memorySize;
+ u32 consoleType;
+ void* arenaLo;
+ void* arenaHi;
+ void* FSTLocation;
+ u32 FSTMaxLength;
+} OSBootInfo;
+
+typedef struct {
+ BOOL valid;
+ u32 restartCode;
+ u32 bootDol;
+ void* regionStart;
+ void* regionEnd;
+ BOOL argsUseDefault;
+ void* argsAddr; // valid only when argsUseDefault = FALSE
+
+} OSExecParams;
+
+typedef struct BI2Debug {
+ s32 debugMonSize; // 0x0
+ s32 simMemSize; // 0x4
+ u32 argOffset; // 0x8
+ u32 debugFlag; // 0xC
+ int trackLocation; // 0x10
+ int trackSize; // 0x14
+ u32 countryCode; // 0x18
+ u8 unk[8]; // 0x1C
+ u32 padSpec; // 0x24
+} BI2Debug;
+
+#endif // _DOLPHIN_OSBOOTINFO
diff --git a/include/dolphin/os/OSCache.h b/include/dolphin/os/OSCache.h
new file mode 100644
index 0000000..b3dd94a
--- /dev/null
+++ b/include/dolphin/os/OSCache.h
@@ -0,0 +1,37 @@
+#ifndef _DOLPHIN_OSCACHE
+#define _DOLPHIN_OSCACHE
+
+#include "dolphin/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void DCInvalidateRange(void* addr, u32 nBytes);
+void DCFlushRange(void* addr, u32 nBytes);
+void DCStoreRange(void* addr, u32 nBytes);
+void DCFlushRangeNoSync(void* addr, u32 nBytes);
+void DCStoreRangeNoSync(void* addr, u32 nBytes);
+void DCZeroRange(void* addr, u32 nBytes);
+void DCTouchRange(void* addr, u32 nBytes);
+void ICInvalidateRange(void* addr, u32 nBytes);
+
+#define LC_BASE_PREFIX 0xE000
+#define LC_BASE (LC_BASE_PREFIX << 16)
+#define LCGetBase() ((void*)LC_BASE)
+
+void LCEnable();
+void LCDisable(void);
+void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks);
+void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks);
+u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes);
+u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes);
+u32 LCQueueLength(void);
+void LCQueueWait(u32 len);
+void LCFlushQueue(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSCACHE
diff --git a/include/dolphin/os/OSContext.h b/include/dolphin/os/OSContext.h
new file mode 100644
index 0000000..bbd0aaa
--- /dev/null
+++ b/include/dolphin/os/OSContext.h
@@ -0,0 +1,170 @@
+#ifndef _DOLPHIN_OSCONTEXT
+#define _DOLPHIN_OSCONTEXT
+
+#include <types.h>
+
+#ifdef __cplusplus
+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
+#define OS_CONTEXT_STATE_EXC 0x02u
+
+#define OS_CONTEXT_STATE_FPSAVED 0x01u
+
+typedef struct OSContext {
+ u32 gpr[32];
+ u32 cr;
+ u32 lr;
+ u32 ctr;
+ u32 xer;
+
+ f64 fpr[32];
+
+ u32 fpscr_pad;
+ u32 fpscr;
+
+ u32 srr0;
+ u32 srr1;
+
+ u16 mode;
+ u16 state;
+
+ u32 gqr[8];
+ u32 psf_pad;
+ f64 psf[32];
+
+} OSContext;
+
+u32 OSSaveContext(OSContext* context);
+void OSClearContext(OSContext* context);
+OSContext* OSGetCurrentContext();
+void OSSetCurrentContext(OSContext* context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSCONTEXT
diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h
new file mode 100644
index 0000000..8764fbe
--- /dev/null
+++ b/include/dolphin/os/OSError.h
@@ -0,0 +1,39 @@
+#ifndef _DOLPHIN_OSERROR
+#define _DOLPHIN_OSERROR
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_ERROR_SYSTEM_RESET 0
+#define OS_ERROR_MACHINE_CHECK 1
+#define OS_ERROR_DSI 2
+#define OS_ERROR_ISI 3
+#define OS_ERROR_EXTERNAL_INTERRUPT 4
+#define OS_ERROR_ALIGNMENT 5
+#define OS_ERROR_PROGRAM 6
+#define OS_ERROR_FLOATING_POINT 7
+#define OS_ERROR_DECREMENTER 8
+#define OS_ERROR_SYSTEM_CALL 9
+#define OS_ERROR_TRACE 10
+#define OS_ERROR_PERFORMACE_MONITOR 11
+#define OS_ERROR_BREAKPOINT 12
+#define OS_ERROR_SYSTEM_INTERRUPT 13
+#define OS_ERROR_THERMAL_INTERRUPT 14
+#define OS_ERROR_PROTECTION 15
+#define OS_ERROR_FPE 16
+
+#define OS_ERROR_MAX (OS_ERROR_FPE + 1)
+
+typedef u16 OSError;
+typedef void (*OSErrorHandler)( OSError error, OSContext* context, ... );
+
+OSErrorHandler OSSetErrorHandler(OSError code, OSErrorHandler handler);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSERROR
diff --git a/include/dolphin/os/OSException.h b/include/dolphin/os/OSException.h
new file mode 100644
index 0000000..f342369
--- /dev/null
+++ b/include/dolphin/os/OSException.h
@@ -0,0 +1,56 @@
+
+#ifndef _DOLPHIN_OSEXCEPTION
+#define _DOLPHIN_OSEXCEPTION
+
+#include <dolphin/os/OSContext.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define __OS_EXCEPTION_SYSTEM_RESET 0
+#define __OS_EXCEPTION_MACHINE_CHECK 1
+#define __OS_EXCEPTION_DSI 2
+#define __OS_EXCEPTION_ISI 3
+#define __OS_EXCEPTION_EXTERNAL_INTERRUPT 4
+#define __OS_EXCEPTION_ALIGNMENT 5
+#define __OS_EXCEPTION_PROGRAM 6
+#define __OS_EXCEPTION_FLOATING_POINT 7
+#define __OS_EXCEPTION_DECREMENTER 8
+#define __OS_EXCEPTION_SYSTEM_CALL 9
+#define __OS_EXCEPTION_TRACE 10
+#define __OS_EXCEPTION_PERFORMACE_MONITOR 11
+#define __OS_EXCEPTION_BREAKPOINT 12
+#define __OS_EXCEPTION_SYSTEM_INTERRUPT 13
+#define __OS_EXCEPTION_THERMAL_INTERRUPT 14
+#define __OS_EXCEPTION_MAX \
+ (__OS_EXCEPTION_THERMAL_INTERRUPT+1)
+
+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
+
+#endif // _DOLPHIN_OSEXCEPTION
diff --git a/include/dolphin/os/OSExpansion.h b/include/dolphin/os/OSExpansion.h
new file mode 100644
index 0000000..6e848b8
--- /dev/null
+++ b/include/dolphin/os/OSExpansion.h
@@ -0,0 +1,79 @@
+#ifndef _DOLPHIN_OSEXPANSION
+#define _DOLPHIN_OSEXPANSION
+
+#include <dolphin/os.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EXI_MEMORY_CARD_59 0x00000004
+#define EXI_MEMORY_CARD_123 0x00000008
+#define EXI_MEMORY_CARD_251 0x00000010
+#define EXI_MEMORY_CARD_507 0x00000020
+
+#define EXI_MEMORY_CARD_1019 0x00000040
+#define EXI_MEMORY_CARD_2043 0x00000080
+
+#define EXI_MEMORY_CARD_1019A 0x00000140
+#define EXI_MEMORY_CARD_1019B 0x00000240
+#define EXI_MEMORY_CARD_1019C 0x00000340
+#define EXI_MEMORY_CARD_1019D 0x00000440
+#define EXI_MEMORY_CARD_1019E 0x00000540
+#define EXI_MEMORY_CARD_1019F 0x00000640
+#define EXI_MEMORY_CARD_1019G 0x00000740
+
+#define EXI_MEMORY_CARD_2043A 0x00000180
+#define EXI_MEMORY_CARD_2043B 0x00000280
+#define EXI_MEMORY_CARD_2043C 0x00000380
+#define EXI_MEMORY_CARD_2043D 0x00000480
+#define EXI_MEMORY_CARD_2043E 0x00000580
+#define EXI_MEMORY_CARD_2043F 0x00000680
+#define EXI_MEMORY_CARD_2043G 0x00000780
+
+#define EXI_USB_ADAPTER 0x01010000
+#define EXI_NPDP_GDEV 0x01020000
+
+#define EXI_MODEM 0x02020000
+#define EXI_ETHER 0x04020200
+#define EXI_ETHER_VIEWER 0x04220001
+#define EXI_STREAM_HANGER 0x04130000
+
+#define EXI_MARLIN 0x03010000
+
+#define EXI_IS_VIEWER 0x05070000
+
+#define EXI_FREQ_1M 0
+#define EXI_FREQ_2M 1
+#define EXI_FREQ_4M 2
+#define EXI_FREQ_8M 3
+#define EXI_FREQ_16M 4
+#define EXI_FREQ_32M 5
+
+#define EXI_READ 0
+#define EXI_WRITE 1
+
+#define EXI_STATE_IDLE 0x00
+#define EXI_STATE_DMA 0x01
+#define EXI_STATE_IMM 0x02
+#define EXI_STATE_BUSY (EXI_STATE_DMA | EXI_STATE_IMM)
+#define EXI_STATE_SELECTED 0x04
+#define EXI_STATE_ATTACHED 0x08
+#define EXI_STATE_LOCKED 0x10
+
+BOOL EXIProbe(s32 chan);
+s32 EXIProbeEx(s32 chan);
+
+s32 EXIGetType(s32 chan, u32 dev, u32* type);
+char* EXIGetTypeString(u32 type);
+u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext);
+s32 EXIGetID(s32 chan, u32 dev, u32* id);
+
+typedef void (*EXICallback)(s32 chan, OSContext* context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSEXPANSION
diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h
new file mode 100644
index 0000000..b6ca50d
--- /dev/null
+++ b/include/dolphin/os/OSFastCast.h
@@ -0,0 +1,48 @@
+#ifndef _DOLPHIN_OSFASTCAST
+#define _DOLPHIN_OSFASTCAST
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_GQR_F32 0x0000
+#define OS_GQR_U8 0x0004
+#define OS_GQR_U16 0x0005
+#define OS_GQR_S8 0x0006
+#define OS_GQR_S16 0x0007
+
+#define OS_FASTCAST_U8 2
+#define OS_FASTCAST_U16 3
+#define OS_FASTCAST_S16 5
+// clang-format off
+static inline void OSInitFastCast(void) {
+#ifdef __MWERKS__
+ asm
+ {
+ li r3, OS_GQR_U8
+ oris r3, r3, OS_GQR_U8
+ mtspr GQR2, r3
+
+ li r3, OS_GQR_U16
+ oris r3, r3, OS_GQR_U16
+ mtspr GQR3, r3
+
+ li r3, OS_GQR_S8
+ oris r3, r3, OS_GQR_S8
+ mtspr GQR4, r3
+
+ li r3, OS_GQR_S16
+ oris r3, r3, OS_GQR_S16
+ mtspr GQR5, r3
+ }
+#else
+
+#endif
+}
+// clang-format off
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSFASTCAST
diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h
new file mode 100644
index 0000000..35ddced
--- /dev/null
+++ b/include/dolphin/os/OSFont.h
@@ -0,0 +1,56 @@
+#ifndef RVL_SDK_OS_FONT_H
+#define RVL_SDK_OS_FONT_H
+#include <types.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Documentation from:
+ * https://www.gc-forever.com/yagcd/chap16.html#sec16.1.3
+ */
+
+typedef enum {
+ OS_FONT_ENCODE_ANSI,
+ OS_FONT_ENCODE_SJIS,
+ OS_FONT_ENCODE_2,
+ OS_FONT_ENCODE_UTF8,
+ OS_FONT_ENCODE_UTF16,
+ OS_FONT_ENCODE_UTF32,
+ OS_FONT_ENCODE_MAX
+} OSFontEncode;
+
+typedef struct OSFontData {
+ u16 type; // at 0x0
+ u16 firstChar; // at 0x2
+ u16 lastChar; // at 0x4
+ u16 invalidChar; // at 0x6
+ u16 ascent; // at 0x8
+ u16 descent; // at 0xA
+ u16 charWidth; // at 0xC
+ u16 lineFeed; // at 0xE
+ u16 cellWidth; // at 0x10
+ u16 cellHeight; // at 0x12
+ u32 texSize; // at 0x14
+ u16 texFmt; // at 0x18
+ u16 texNumCol; // at 0x1A
+ u16 texNumRow; // at 0x1C
+ u16 texWidth; // at 0x1E
+ u16 texHeight; // at 0x20
+ u16 charWidthTblOfs; // at 0x22
+ u32 fontSheetOfs; // at 0x24
+ u32 fontSheetSize; // at 0x28
+} OSFontData;
+
+u16 OSGetFontEncode(void);
+u16 OSSetFontEncode(u16);
+u32 OSLoadFont(OSFontData*, void*);
+const char* OSGetFontTexel(const char*, void*, s32, s32, u32*);
+BOOL OSInitFont(OSFontData*);
+const char* OSGetFontTexture(const char*, void**, u32*, u32*, u32*);
+const char* OSGetFontWidth(const char*, u32*);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h
new file mode 100644
index 0000000..9e5d2aa
--- /dev/null
+++ b/include/dolphin/os/OSInterrupt.h
@@ -0,0 +1,115 @@
+#ifndef _DOLPHIN_OSINTERRUPT
+#define _DOLPHIN_OSINTERRUPT
+
+#include <dolphin/os/OSContext.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __OS_INTERRUPT_MEM_0 0
+#define __OS_INTERRUPT_MEM_1 1
+#define __OS_INTERRUPT_MEM_2 2
+#define __OS_INTERRUPT_MEM_3 3
+#define __OS_INTERRUPT_MEM_ADDRESS 4
+#define __OS_INTERRUPT_DSP_AI 5
+#define __OS_INTERRUPT_DSP_ARAM 6
+#define __OS_INTERRUPT_DSP_DSP 7
+#define __OS_INTERRUPT_AI_AI 8
+#define __OS_INTERRUPT_EXI_0_EXI 9
+#define __OS_INTERRUPT_EXI_0_TC 10
+#define __OS_INTERRUPT_EXI_0_EXT 11
+#define __OS_INTERRUPT_EXI_1_EXI 12
+#define __OS_INTERRUPT_EXI_1_TC 13
+#define __OS_INTERRUPT_EXI_1_EXT 14
+#define __OS_INTERRUPT_EXI_2_EXI 15
+#define __OS_INTERRUPT_EXI_2_TC 16
+#define __OS_INTERRUPT_PI_CP 17
+#define __OS_INTERRUPT_PI_PE_TOKEN 18
+#define __OS_INTERRUPT_PI_PE_FINISH 19
+#define __OS_INTERRUPT_PI_SI 20
+#define __OS_INTERRUPT_PI_DI 21
+#define __OS_INTERRUPT_PI_RSW 22
+#define __OS_INTERRUPT_PI_ERROR 23
+#define __OS_INTERRUPT_PI_VI 24
+#define __OS_INTERRUPT_PI_DEBUG 25
+#define __OS_INTERRUPT_PI_HSP 26
+#define __OS_INTERRUPT_MAX 32
+
+#define OS_INTERRUPTMASK(interrupt) (0x80000000u >> (interrupt))
+
+#define OS_INTERRUPTMASK_MEM_0 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0)
+#define OS_INTERRUPTMASK_MEM_1 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_1)
+#define OS_INTERRUPTMASK_MEM_2 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_2)
+#define OS_INTERRUPTMASK_MEM_3 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_3)
+#define OS_INTERRUPTMASK_MEM_ADDRESS OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_ADDRESS)
+#define OS_INTERRUPTMASK_MEM \
+ (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \
+ OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS)
+#define OS_INTERRUPTMASK_DSP_AI OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_AI)
+#define OS_INTERRUPTMASK_DSP_ARAM OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_ARAM)
+#define OS_INTERRUPTMASK_DSP_DSP OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_DSP)
+#define OS_INTERRUPTMASK_DSP \
+ (OS_INTERRUPTMASK_DSP_AI | OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP)
+#define OS_INTERRUPTMASK_AI_AI OS_INTERRUPTMASK(__OS_INTERRUPT_AI_AI)
+#define OS_INTERRUPTMASK_AI (OS_INTERRUPTMASK_AI_AI)
+#define OS_INTERRUPTMASK_EXI_0_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXI)
+#define OS_INTERRUPTMASK_EXI_0_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_TC)
+#define OS_INTERRUPTMASK_EXI_0_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXT)
+#define OS_INTERRUPTMASK_EXI_0 \
+ (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT)
+#define OS_INTERRUPTMASK_EXI_1_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXI)
+#define OS_INTERRUPTMASK_EXI_1_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_TC)
+#define OS_INTERRUPTMASK_EXI_1_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXT)
+#define OS_INTERRUPTMASK_EXI_1 \
+ (OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT)
+#define OS_INTERRUPTMASK_EXI_2_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_EXI)
+#define OS_INTERRUPTMASK_EXI_2_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_TC)
+#define OS_INTERRUPTMASK_EXI_2 (OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC)
+#define OS_INTERRUPTMASK_EXI \
+ (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | \
+ OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | \
+ OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC)
+#define OS_INTERRUPTMASK_PI_PE_TOKEN OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_TOKEN)
+#define OS_INTERRUPTMASK_PI_PE_FINISH OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_FINISH)
+#define OS_INTERRUPTMASK_PI_PE (OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH)
+#define OS_INTERRUPTMASK_PI_CP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_CP)
+#define OS_INTERRUPTMASK_PI_SI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_SI)
+#define OS_INTERRUPTMASK_PI_DI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DI)
+#define OS_INTERRUPTMASK_PI_RSW OS_INTERRUPTMASK(__OS_INTERRUPT_PI_RSW)
+#define OS_INTERRUPTMASK_PI_ERROR OS_INTERRUPTMASK(__OS_INTERRUPT_PI_ERROR)
+#define OS_INTERRUPTMASK_PI_VI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_VI)
+#define OS_INTERRUPTMASK_PI_DEBUG OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DEBUG)
+#define OS_INTERRUPTMASK_PI_HSP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_HSP)
+#define OS_INTERRUPTMASK_PI \
+ (OS_INTERRUPTMASK_PI_CP | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI | \
+ OS_INTERRUPTMASK_PI_RSW | OS_INTERRUPTMASK_PI_ERROR | OS_INTERRUPTMASK_PI_VI | \
+ OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \
+ OS_INTERRUPTMASK_PI_HSP)
+
+typedef s16 __OSInterrupt;
+typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context);
+
+typedef u32 OSInterruptMask;
+
+extern volatile __OSInterrupt __OSLastInterrupt;
+extern volatile u32 __OSLastInterruptSrr0;
+extern volatile OSTime __OSLastInterruptTime;
+
+__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler);
+
+__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt);
+
+void __OSDispatchInterrupt(__OSException exception, OSContext* context);
+
+OSInterruptMask OSGetInterruptMask(void);
+OSInterruptMask OSSetInterruptMask(OSInterruptMask mask);
+OSInterruptMask __OSMaskInterrupts(OSInterruptMask mask);
+OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSINTERRUPT
diff --git a/include/dolphin/os/OSMemory.h b/include/dolphin/os/OSMemory.h
new file mode 100644
index 0000000..00c6ab0
--- /dev/null
+++ b/include/dolphin/os/OSMemory.h
@@ -0,0 +1,26 @@
+#ifndef _DOLPHIN_OSMEMORY
+#define _DOLPHIN_OSMEMORY
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_PROTECT_CHAN0 0
+#define OS_PROTECT_CHAN1 1
+#define OS_PROTECT_CHAN2 2
+#define OS_PROTECT_CHAN3 3
+
+#define OS_PROTECT_CONTROL_NONE 0x00
+#define OS_PROTECT_CONTROL_READ 0x01
+#define OS_PROTECT_CONTROL_WRITE 0x02
+#define OS_PROTECT_CONTROL_RDWR (OS_PROTECT_CONTROL_READ | OS_PROTECT_CONTROL_WRITE)
+
+void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMEMORY
diff --git a/include/dolphin/os/OSMessage.h b/include/dolphin/os/OSMessage.h
new file mode 100644
index 0000000..f67a84e
--- /dev/null
+++ b/include/dolphin/os/OSMessage.h
@@ -0,0 +1,34 @@
+#ifndef _DOLPHIN_OSMESSAGE
+#define _DOLPHIN_OSMESSAGE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dolphin/os/OSThread.h>
+typedef struct OSMessageQueue OSMessageQueue;
+typedef void* OSMessage;
+
+struct OSMessageQueue {
+ OSThreadQueue queueSend;
+ OSThreadQueue queueReceive;
+ OSMessage* msgArray;
+ s32 msgCount;
+ s32 firstIndex;
+ s32 usedCount;
+};
+
+// Flags to turn blocking on/off when sending/receiving message
+#define OS_MESSAGE_NOBLOCK 0
+#define OS_MESSAGE_BLOCK 1
+
+void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount);
+BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags);
+BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags);
+BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMESSAGE
diff --git a/include/dolphin/os/OSModule.h b/include/dolphin/os/OSModule.h
new file mode 100644
index 0000000..7baf2a9
--- /dev/null
+++ b/include/dolphin/os/OSModule.h
@@ -0,0 +1,115 @@
+#ifndef _DOLPHIN_OSMODULE
+#define _DOLPHIN_OSMODULE
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_MODULE_VERSION 2
+typedef struct OSModuleHeader OSModuleHeader;
+
+typedef u32 OSModuleID;
+typedef struct OSModuleQueue OSModuleQueue;
+typedef struct OSModuleLink OSModuleLink;
+typedef struct OSModuleInfo OSModuleInfo;
+typedef struct OSSectionInfo OSSectionInfo;
+typedef struct OSImportInfo OSImportInfo;
+typedef struct OSRel OSRel;
+
+struct OSModuleQueue {
+ OSModuleInfo* head;
+ OSModuleInfo* tail;
+};
+
+struct OSModuleLink {
+ OSModuleInfo* next;
+ OSModuleInfo* prev;
+};
+
+struct OSModuleInfo {
+ OSModuleID id; // unique identifier for the module
+ OSModuleLink link; // doubly linked list of modules
+ u32 numSections; // # of sections
+ u32 sectionInfoOffset; // offset to section info table
+ u32 nameOffset; // offset to module name
+ u32 nameSize; // size of module name
+ u32 version; // version number
+};
+
+struct OSModuleHeader {
+ // CAUTION: info must be the 1st member
+ OSModuleInfo info;
+
+ // OS_MODULE_VERSION == 1
+ u32 bssSize; // total size of bss sections in bytes
+ u32 relOffset;
+ u32 impOffset;
+ u32 impSize; // size in bytes
+ u8 prologSection; // section # for prolog function
+ u8 epilogSection; // section # for epilog function
+ u8 unresolvedSection; // section # for unresolved function
+ u8 bssSection; // section # for bss section (set at run-time)
+ u32 prolog; // prolog function offset
+ u32 epilog; // epilog function offset
+ u32 unresolved; // unresolved function offset
+
+ // OS_MODULE_VERSION == 2
+#if (2 <= OS_MODULE_VERSION)
+ u32 align; // module alignment constraint
+ u32 bssAlign; // bss alignment constraint
+#endif
+
+ // OS_MODULE_VERSION == 3
+#if (3 <= OS_MODULE_VERSION)
+ u32 fixSize;
+#endif
+};
+
+#define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset))
+
+struct OSSectionInfo {
+ u32 offset;
+ u32 size;
+};
+
+// OSSectionInfo.offset bit
+#define OS_SECTIONINFO_EXEC 0x1
+#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1)
+
+struct OSImportInfo {
+ OSModuleID id; // external module id
+ u32 offset; // offset to OSRel instructions
+};
+
+struct OSRel {
+ u16 offset; // byte offset from the previous entry
+ u8 type;
+ u8 section;
+ u32 addend;
+};
+
+#define R_DOLPHIN_NOP 201 // C9h current offset += OSRel.offset
+#define R_DOLPHIN_SECTION 202 // CAh current section = OSRel.section
+#define R_DOLPHIN_END 203 // CBh
+#define R_DOLPHIN_MRKREF 204 // CCh
+
+void OSSetStringTable(const void* stringTable);
+BOOL OSLink(OSModuleInfo* newModule, void* bss);
+#if (3 <= OS_MODULE_VERSION)
+BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss);
+#endif
+BOOL OSUnlink(OSModuleInfo* oldModule);
+
+OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset);
+
+// debugger notification
+void OSNotifyLink(OSModuleInfo* module);
+void OSNotifyUnlink(OSModuleInfo* module);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMODULE
diff --git a/include/dolphin/os/OSMutex.h b/include/dolphin/os/OSMutex.h
new file mode 100644
index 0000000..9ee6ffe
--- /dev/null
+++ b/include/dolphin/os/OSMutex.h
@@ -0,0 +1,35 @@
+#ifndef _DOLPHIN_OSMUTEX
+#define _DOLPHIN_OSMUTEX
+
+#include "types.h"
+
+#include "dolphin/os/OSThread.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct OSMutex {
+ OSThreadQueue queue;
+ OSThread* thread; // the current owner
+ s32 count; // lock count
+ OSMutexLink link; // for OSThread.queueMutex
+};
+
+struct OSCond {
+ OSThreadQueue queue;
+};
+
+void OSInitMutex(OSMutex* mutex);
+void OSLockMutex(OSMutex* mutex);
+void OSUnlockMutex(OSMutex* mutex);
+BOOL OSTryLockMutex(OSMutex* mutex);
+void OSInitCond(OSCond* cond);
+void OSWaitCond(OSCond* cond, OSMutex* mutex);
+void OSSignalCond(OSCond* cond);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMUTEX
diff --git a/include/dolphin/os/OSPriv.h b/include/dolphin/os/OSPriv.h
new file mode 100644
index 0000000..b3db327
--- /dev/null
+++ b/include/dolphin/os/OSPriv.h
@@ -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
diff --git a/include/dolphin/os/OSReboot.h b/include/dolphin/os/OSReboot.h
new file mode 100644
index 0000000..837de88
--- /dev/null
+++ b/include/dolphin/os/OSReboot.h
@@ -0,0 +1,10 @@
+#ifndef DOLPHIN_OS_OSREBOOT_H
+#define DOLPHIN_OS_OSREBOOT_H
+typedef void (*Event)(void);
+
+void __OSReboot(u32 resetCode, BOOL forceMenu);
+
+void Run(Event);
+//void __OSReboot(u32 resetCode, BOOL forceMenu);
+
+#endif
diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h
new file mode 100644
index 0000000..6c1e33b
--- /dev/null
+++ b/include/dolphin/os/OSReset.h
@@ -0,0 +1,48 @@
+#ifndef _DOLPHIN_OSRESET
+#define _DOLPHIN_OSRESET
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_RESETCODE_RESTART 0x80000000
+#define OS_RESETCODE_SYSTEM 0x40000000
+
+#define OS_RESETCODE_EXEC 0xC0000000
+#define OS_RESETCODE_NETCONFIG 0xC0010000
+
+#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;
+
+struct OSResetFunctionInfo {
+ // public
+ OSResetFunction func;
+ u32 priority;
+
+ // private
+ OSResetFunctionInfo* next;
+ OSResetFunctionInfo* prev;
+};
+
+void __OSDoHotReset(s32 arg0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSRESET
diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h
new file mode 100644
index 0000000..5551f68
--- /dev/null
+++ b/include/dolphin/os/OSResetSW.h
@@ -0,0 +1,22 @@
+#ifndef _DOLPHIN_OSRESETSW
+#define _DOLPHIN_OSRESETSW
+
+#include <dolphin/os/OSContext.h>
+#include <dolphin/types.h>
+
+#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/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h
new file mode 100644
index 0000000..f0a6a4d
--- /dev/null
+++ b/include/dolphin/os/OSSerial.h
@@ -0,0 +1,69 @@
+#ifndef _DOLPHIN_OSSERIAL
+#define _DOLPHIN_OSSERIAL
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SI_MAX_CHAN 4
+#define SI_MAX_COMCSR_INLNGTH 128
+#define SI_MAX_COMCSR_OUTLNGTH 128
+#define SI_ERROR_UNDER_RUN 0x0001
+#define SI_ERROR_OVER_RUN 0x0002
+#define SI_ERROR_COLLISION 0x0004
+#define SI_ERROR_NO_RESPONSE 0x0008
+#define SI_ERROR_WRST 0x0010
+#define SI_ERROR_RDST 0x0020
+#define SI_ERROR_UNKNOWN 0x0040
+#define SI_ERROR_BUSY 0x0080
+#define SI_CHAN0 0
+#define SI_CHAN1 1
+#define SI_CHAN2 2
+#define SI_CHAN3 3
+#define SI_CHAN0_BIT 0x80000000
+#define SI_CHAN1_BIT 0x40000000
+#define SI_CHAN2_BIT 0x20000000
+#define SI_CHAN3_BIT 0x10000000
+#define SI_CHAN_BIT(chan) (SI_CHAN0_BIT >> (chan))
+#define SI_TYPE_MASK 0x18000000u
+#define SI_TYPE_N64 0x00000000u
+#define SI_TYPE_DOLPHIN 0x08000000u
+#define SI_TYPE_GC SI_TYPE_DOLPHIN
+#define SI_GC_WIRELESS 0x80000000
+#define SI_GC_NOMOTOR 0x20000000
+#define SI_GC_STANDARD 0x01000000
+#define SI_WIRELESS_RECEIVED 0x40000000
+#define SI_WIRELESS_IR 0x04000000
+#define SI_WIRELESS_STATE 0x02000000
+#define SI_WIRELESS_ORIGIN 0x00200000
+#define SI_WIRELESS_FIX_ID 0x00100000
+#define SI_WIRELESS_TYPE 0x000f0000
+#define SI_WIRELESS_LITE_MASK 0x000c0000
+#define SI_WIRELESS_LITE 0x00040000
+#define SI_WIRELESS_CONT_MASK 0x00080000
+#define SI_WIRELESS_CONT 0x00000000
+#define SI_WIRELESS_ID 0x00c0ff00
+#define SI_WIRELESS_TYPE_ID (SI_WIRELESS_TYPE | SI_WIRELESS_ID)
+#define SI_N64_CONTROLLER (SI_TYPE_N64 | 0x05000000)
+#define SI_N64_MIC (SI_TYPE_N64 | 0x00010000)
+#define SI_N64_KEYBOARD (SI_TYPE_N64 | 0x00020000)
+#define SI_N64_MOUSE (SI_TYPE_N64 | 0x02000000)
+#define SI_GBA (SI_TYPE_N64 | 0x00040000)
+#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD)
+#define SI_GC_RECEIVER (SI_TYPE_GC | SI_GC_WIRELESS)
+#define SI_GC_WAVEBIRD \
+ (SI_TYPE_GC | SI_GC_WIRELESS | SI_GC_STANDARD | SI_WIRELESS_STATE | SI_WIRELESS_FIX_ID)
+#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000)
+#define SI_GC_STEERING (SI_TYPE_GC | 0x00000000)
+
+u32 SIProbe(s32 chan);
+char* SIGetTypeString(u32 type);
+void SIRefreshSamplingRate(void);
+void SISetSamplingRate(u32 msec);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _DOLPHIN_OSSERIAL
diff --git a/include/dolphin/os/OSThread.h b/include/dolphin/os/OSThread.h
new file mode 100644
index 0000000..7464e68
--- /dev/null
+++ b/include/dolphin/os/OSThread.h
@@ -0,0 +1,113 @@
+#ifndef _DOLPHIN_OSTHREAD
+#define _DOLPHIN_OSTHREAD
+
+#include <dolphin/os/OSContext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_THREAD_SPECIFIC_MAX 2
+
+typedef struct OSThread OSThread;
+typedef struct OSThreadQueue OSThreadQueue;
+typedef struct OSThreadLink OSThreadLink;
+typedef s32 OSPriority; // 0 highest, 31 lowest
+
+typedef struct OSMutex OSMutex;
+typedef struct OSMutexQueue OSMutexQueue;
+typedef struct OSMutexLink OSMutexLink;
+typedef struct OSCond OSCond;
+
+typedef void (*OSIdleFunction)(void* param);
+typedef void (*OSSwitchThreadCallback)(OSThread* from, OSThread* to);
+
+struct OSThreadQueue {
+ OSThread* head;
+ OSThread* tail;
+};
+
+struct OSThreadLink {
+ OSThread* next;
+ OSThread* prev;
+};
+
+struct OSMutexQueue {
+ OSMutex* head;
+ OSMutex* tail;
+};
+
+struct OSMutexLink {
+ OSMutex* next;
+ OSMutex* prev;
+};
+
+struct OSThread {
+ OSContext context;
+ u16 state;
+ u16 attr;
+ s32 suspend;
+ OSPriority priority;
+ OSPriority base;
+ void* val;
+ OSThreadQueue* queue;
+ OSThreadLink link;
+ OSThreadQueue queueJoin;
+ OSMutex* mutex;
+ OSMutexQueue queueMutex;
+ OSThreadLink linkActive;
+ u8* stackBase;
+ u32* stackEnd;
+ s32 error;
+ void* specific[OS_THREAD_SPECIFIC_MAX];
+};
+
+enum OS_THREAD_STATE {
+ OS_THREAD_STATE_READY = 1,
+ OS_THREAD_STATE_RUNNING = 2,
+ OS_THREAD_STATE_WAITING = 4,
+ OS_THREAD_STATE_MORIBUND = 8
+};
+
+#define OS_THREAD_ATTR_DETACH 0x0001u
+
+#define OS_THREAD_STACK_MAGIC 0xDEADBABE
+
+#define OS_PRIORITY_MIN 0 // highest
+#define OS_PRIORITY_MAX 31 // lowest
+#define OS_PRIORITY_IDLE OS_PRIORITY_MAX
+
+
+void OSInitThreadQueue(OSThreadQueue* queue);
+OSThread* OSGetCurrentThread(void);
+BOOL OSIsThreadSuspended(OSThread* thread);
+BOOL OSIsThreadTerminated(OSThread* thread);
+s32 OSDisableScheduler(void);
+s32 OSEnableScheduler(void);
+void OSYieldThread(void);
+BOOL OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize,
+ OSPriority priority, u16 attr);
+void OSExitThread(void* val);
+void OSCancelThread(OSThread* thread);
+BOOL OSJoinThread(OSThread* thread, void** val);
+void OSDetachThread(OSThread* thread);
+s32 OSResumeThread(OSThread* thread);
+s32 OSSuspendThread(OSThread* thread);
+BOOL OSSetThreadPriority(OSThread* thread, OSPriority priority);
+OSPriority OSGetThreadPriority(OSThread* thread);
+void OSSleepThread(OSThreadQueue* queue);
+void OSWakeupThread(OSThreadQueue* queue);
+
+void* OSGetThreadSpecific(s32 index);
+void OSSetThreadSpecific(s32 index, void* ptr);
+
+OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize);
+OSThread* OSGetIdleFunction(void);
+void OSClearStack(u8 val);
+long OSCheckActiveThreads(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSTHREAD
diff --git a/include/dolphin/pad.h b/include/dolphin/pad.h
new file mode 100644
index 0000000..0d52500
--- /dev/null
+++ b/include/dolphin/pad.h
@@ -0,0 +1,128 @@
+#ifndef _DOLPHIN_PAD
+#define _DOLPHIN_PAD
+
+#include <dolphin/types.h>
+
+extern u32 __PADFixBits;
+
+#define PAD_SPEC_0 0
+#define PAD_SPEC_1 1
+#define PAD_SPEC_2 2
+#define PAD_SPEC_3 3
+#define PAD_SPEC_4 4
+#define PAD_SPEC_5 5
+
+#define PAD_CHAN0 0
+#define PAD_CHAN1 1
+#define PAD_CHAN2 2
+#define PAD_CHAN3 3
+#define PAD_CHANMAX 4
+
+#define PAD_MOTOR_STOP 0
+#define PAD_MOTOR_RUMBLE 1
+#define PAD_MOTOR_STOP_HARD 2
+
+#define PAD_ERR_NONE 0
+#define PAD_ERR_NO_CONTROLLER -1
+#define PAD_ERR_NOT_READY -2
+#define PAD_ERR_TRANSFER -3
+
+#define PAD_BUTTON_LEFT 0x0001
+#define PAD_BUTTON_RIGHT 0x0002
+#define PAD_BUTTON_DOWN 0x0004
+#define PAD_BUTTON_UP 0x0008
+#define PAD_TRIGGER_Z 0x0010
+#define PAD_TRIGGER_R 0x0020
+#define PAD_TRIGGER_L 0x0040
+#define PAD_BUTTON_A 0x0100
+#define PAD_BUTTON_B 0x0200
+#define PAD_BUTTON_X 0x0400
+#define PAD_BUTTON_Y 0x0800
+#define PAD_BUTTON_MENU 0x1000
+#define PAD_BUTTON_START 0x1000
+
+#define PAD_CHAN0_BIT 0x80000000
+#define PAD_CHAN1_BIT 0x40000000
+#define PAD_CHAN2_BIT 0x20000000
+#define PAD_CHAN3_BIT 0x10000000
+
+#define PADButtonDown(buttonLast, button) ((((buttonLast) ^ (button)) & (button)))
+
+#define PADButtonUp(buttonLast, button) ((((buttonLast) ^ (button)) & (buttonLast)))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*PADSamplingCallback)(void);
+
+typedef struct PADStatus {
+ u16 button;
+ s8 stickX;
+ s8 stickY;
+ s8 substickX;
+ s8 substickY;
+ u8 triggerL;
+ u8 triggerR;
+ u8 analogA;
+ u8 analogB;
+ s8 err;
+} PADStatus;
+
+BOOL PADInit();
+u32 PADRead(PADStatus* status);
+BOOL PADReset(u32 mask);
+BOOL PADRecalibrate(u32 mask);
+void PADClamp(PADStatus* status);
+void PADClampCircle(PADStatus* status);
+void PADControlMotor(s32 chan, u32 cmd);
+void PADSetSpec(u32 spec);
+void PADControlAllMotors(const u32* cmdArr);
+void PADSetAnalogMode(u32 mode);
+PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback);
+
+#ifdef TARGET_PC
+/* New API to facilitate controller interactions */
+typedef struct PADDeadZones {
+ bool emulateTriggers;
+ bool useDeadzones;
+ u16 stickDeadZone;
+ u16 substickDeadZone;
+ u16 leftTriggerActivationZone;
+ u16 rightTriggerActivationZone;
+} PADDeadZones;
+
+typedef u16 PADButton;
+
+typedef struct PADButtonMapping {
+ u32 nativeButton;
+ PADButton padButton;
+} PADButtonMapping;
+
+/* Returns the total number of controllers */
+u32 PADCount();
+/* Returns the controller name for the given index into the controller map */
+const char* PADGetNameForControllerIndex(u32 idx);
+void PADSetPortForIndex(u32 index, s32 port);
+s32 PADGetIndexForPort(u32 port);
+void PADGetVidPid(u32 port, u32* vid, u32* pid);
+void PADClearPort(u32 port);
+const char* PADGetName(u32 port);
+void PADSetButtonMapping(u32 port, PADButtonMapping mapping);
+void PADSetAllButtonMappings(u32 port, PADButtonMapping buttons[12]);
+PADButtonMapping* PADGetButtonMappings(u32 port, u32* buttonCount);
+void PADSerializeMappings();
+PADDeadZones* PADGetDeadZones(u32 port);
+const char* PADGetButtonName(PADButton);
+const char* PADGetNativeButtonName(u32 button);
+/* Returns any pressed native button */
+s32 PADGetNativeButtonPressed(u32 port);
+void PADRestoreDefaultMapping(u32 port);
+void PADBlockInput(bool block);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_PAD
diff --git a/include/dolphin/sipriv.h b/include/dolphin/sipriv.h
new file mode 100644
index 0000000..8c8508c
--- /dev/null
+++ b/include/dolphin/sipriv.h
@@ -0,0 +1,52 @@
+#ifndef _DOLPHIN_SIPRIV
+#define _DOLPHIN_SIPRIV
+
+#include "dolphin/os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context);
+typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type);
+
+typedef struct SIPacket {
+ s32 chan;
+ void* output;
+ u32 outputBytes;
+ void* input;
+ u32 inputBytes;
+ SICallback callback;
+ OSTime fire;
+} SIPacket;
+
+void SIInit(void);
+u32 SIGetStatus(s32 chan);
+
+BOOL SIBusy(void);
+BOOL SIIsChanBusy(s32 chan);
+
+BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
+ SICallback callback, OSTime delay);
+u32 SISync(void);
+
+void SISetCommand(s32 chan, u32 command);
+u32 SIGetCommand(s32 chan);
+void SITransferCommands(void);
+u32 SISetXY(u32 x, u32 y);
+u32 SIEnablePolling(u32 poll);
+u32 SIDisablePolling(u32 poll);
+BOOL SIGetResponse(s32 chan, void* data);
+
+BOOL SIRegisterPollingHandler(__OSInterruptHandler handler);
+BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler);
+
+u32 SIGetType(s32 chan);
+u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback);
+u32 SIDecodeType(u32 type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_SIPRIV
diff --git a/include/dolphin/types.h b/include/dolphin/types.h
index 77e1053..7180dc0 100644
--- a/include/dolphin/types.h
+++ b/include/dolphin/types.h
@@ -1,5 +1,3 @@
-// This file was taken from the Metroid Prime decompilation project.
-// https://github.com/PrimeDecomp/prime/blob/main/include/dolphin/types.h
#ifndef _DOLPHIN_TYPES
#define _DOLPHIN_TYPES
diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h
new file mode 100644
index 0000000..fdedc8c
--- /dev/null
+++ b/include/dolphin/vi.h
@@ -0,0 +1,35 @@
+#ifndef _DOLPHIN_VI
+#define _DOLPHIN_VI
+
+#include <dolphin/gx/GXStruct.h>
+#include <dolphin/vifuncs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void VIInit(void);
+void VIConfigure(GXRenderModeObj* rm);
+void VIFlush(void);
+u32 VIGetTvFormat(void);
+void VISetNextFrameBuffer(void* fb);
+void VIWaitForRetrace(void);
+void VISetBlack(BOOL black);
+
+#ifdef TARGET_PC
+void VISetWindowTitle(const char* title);
+void VISetWindowFullscreen(bool fullscreen);
+bool VIGetWindowFullscreen();
+#endif
+
+#ifdef __MWERKS__
+vu16 __VIRegs[59] : 0xCC002000;
+#else
+vu16 __VIRegs[59];
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_VI
diff --git a/include/dolphin/vifuncs.h b/include/dolphin/vifuncs.h
new file mode 100644
index 0000000..1a36994
--- /dev/null
+++ b/include/dolphin/vifuncs.h
@@ -0,0 +1,21 @@
+#ifndef _DOLPHIN_VIFUNCS
+#define _DOLPHIN_VIFUNCS
+
+#include <dolphin/types.h>
+
+#include <dolphin/vitypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+u32 VIGetNextField(void);
+VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback);
+VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback);
+u32 VIGetDTVStatus(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_VIFUNCS
diff --git a/include/dolphin/vitypes.h b/include/dolphin/vitypes.h
new file mode 100644
index 0000000..f4e2930
--- /dev/null
+++ b/include/dolphin/vitypes.h
@@ -0,0 +1,16 @@
+#ifndef _DOLPHIN_VITYPES
+#define _DOLPHIN_VITYPES
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*VIRetraceCallback)(u32 retraceCount);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_VITYPES
diff --git a/include/libc/ansi_files.h b/include/libc/ansi_files.h
new file mode 100644
index 0000000..60a39ec
--- /dev/null
+++ b/include/libc/ansi_files.h
@@ -0,0 +1,30 @@
+#ifndef _DOLPHIN_ANSI_FILES_H
+#define _DOLPHIN_ANSI_FILES_H
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif // ifdef __cplusplus
+
+#define set_eof(file) \
+ do { \
+ (file)->state.io_state = __neutral; \
+ (file)->state.eof = 1; \
+ (file)->buffer_len = 0; \
+ } while (0)
+
+#define set_error(file) \
+ do { \
+ (file)->state.error = 1; \
+ (file)->buffer_len = 0; \
+ } while (0)
+
+int __flush_buffer(FILE* file, size_t* length);
+void __prep_buffer(FILE* file);
+int __flush_all();
+
+#ifdef __cplusplus
+};
+#endif // ifdef __cplusplus
+
+#endif
diff --git a/include/libc/assert.h b/include/libc/assert.h
new file mode 100644
index 0000000..32ec1dc
--- /dev/null
+++ b/include/libc/assert.h
@@ -0,0 +1,20 @@
+#ifndef _ASSERT_H_
+#define _ASSERT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+// The C11 way
+#define static_assert(cond, msg) _Static_assert(cond, #msg)
+#else
+// The old, hacky way
+#define static_assert(cond, msg) typedef char static_assertion_##msg[(cond) ? 1 : -1]
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/buffer_io.h b/include/libc/buffer_io.h
new file mode 100644
index 0000000..f0b762b
--- /dev/null
+++ b/include/libc/buffer_io.h
@@ -0,0 +1,14 @@
+#ifndef _BUFFER_IO
+#define _BUFFER_IO
+
+#include <stdio.h>
+
+enum { __align_buffer, __dont_align_buffer };
+
+void __convert_from_newlines(unsigned char* p, size_t* n);
+void __convert_to_newlines(unsigned char* p, size_t* n);
+void __prep_buffer(FILE*);
+int __load_buffer(FILE*, size_t* bytes_loaded, int alignment);
+int __flush_buffer(FILE*, size_t* bytes_flushed);
+
+#endif // _BUFFER_IO
diff --git a/include/libc/console_io.h b/include/libc/console_io.h
new file mode 100644
index 0000000..2399e98
--- /dev/null
+++ b/include/libc/console_io.h
@@ -0,0 +1,17 @@
+#ifndef _CONSOLE_IO
+#define _CONSOLE_IO
+
+#include "stddef.h"
+#include "file_struc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __write_console(__file_handle handle, unsigned char * buffer, size_t * count, __idle_proc idle_proc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CONSOLE_IO
diff --git a/include/libc/ctype.h b/include/libc/ctype.h
new file mode 100644
index 0000000..b8f6067
--- /dev/null
+++ b/include/libc/ctype.h
@@ -0,0 +1,69 @@
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// eof.h
+#define EOF -1L
+
+extern unsigned char __ctype_map[];
+extern unsigned char __lower_map[];
+extern unsigned char __upper_map[];
+
+#define __control_char 0x01
+#define __motion_char 0x02
+#define __space_char 0x04
+#define __punctuation 0x08
+#define __digit 0x10
+#define __hex_digit 0x20
+#define __lower_case 0x40
+#define __upper_case 0x80
+
+#define __letter (__lower_case | __upper_case)
+#define __alphanumeric (__letter | __digit)
+#define __graphic (__alphanumeric | __punctuation)
+#define __printable (__graphic | __space_char)
+#define __whitespace (__motion_char | __space_char)
+#define __control (__motion_char | __control_char)
+#define __zero_fill(c) ((int)(unsigned char)(c))
+
+#ifndef _CTYPE_INLINE
+#define _CTYPE_INLINE static inline
+#endif
+
+_CTYPE_INLINE
+int isalnum(int c) { return __ctype_map[__zero_fill(c)] & __alphanumeric; }
+_CTYPE_INLINE
+int isalpha(int c) { return __ctype_map[__zero_fill(c)] & __letter; }
+_CTYPE_INLINE
+int iscntrl(int c) { return __ctype_map[__zero_fill(c)] & __control; }
+_CTYPE_INLINE
+int isdigit(int c) { return __ctype_map[__zero_fill(c)] & __digit; }
+_CTYPE_INLINE
+int isgraph(int c) { return __ctype_map[__zero_fill(c)] & __graphic; }
+_CTYPE_INLINE
+int islower(int c) { return __ctype_map[__zero_fill(c)] & __lower_case; }
+_CTYPE_INLINE
+int isprint(int c) { return __ctype_map[__zero_fill(c)] & __printable; }
+_CTYPE_INLINE
+int ispunct(int c) { return __ctype_map[__zero_fill(c)] & __punctuation; }
+_CTYPE_INLINE
+int isspace(int c) { return __ctype_map[__zero_fill(c)] & __whitespace; }
+_CTYPE_INLINE
+int isupper(int c) { return __ctype_map[__zero_fill(c)] & __upper_case; }
+_CTYPE_INLINE
+int isxdigit(int c) { return __ctype_map[__zero_fill(c)] & __hex_digit; }
+_CTYPE_INLINE
+int tolower(int c) { return ((c == EOF) ? EOF : ((int)__lower_map[__zero_fill(c)])); }
+_CTYPE_INLINE
+int toupper(int c) { return ((c == EOF) ? EOF : ((int)__upper_map[__zero_fill(c)])); }
+_CTYPE_INLINE
+int iswblank(int c) { return ((c == (int)L' ') || (c == (int)L'\t')); }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/errno.h b/include/libc/errno.h
new file mode 100644
index 0000000..f06a661
--- /dev/null
+++ b/include/libc/errno.h
@@ -0,0 +1,21 @@
+#ifndef _ERRNO_H_
+#define _ERRNO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int errno;
+
+#define ENOERR 0
+#define EDOM 33
+#define ERANGE 34
+#define ESIGPARM 36
+#define EFPOS 40
+#define EILSEQ 84
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/file_struc.h b/include/libc/file_struc.h
new file mode 100644
index 0000000..b347543
--- /dev/null
+++ b/include/libc/file_struc.h
@@ -0,0 +1,22 @@
+#ifndef _FILE_STRUC
+#define _FILE_STRUC
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long __file_handle;
+typedef unsigned long fpos_t;
+
+typedef void (*__idle_proc)(void);
+typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc);
+typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count,
+ __idle_proc idle_proc);
+typedef int (*__close_proc)(__file_handle file);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _FILE_STRUC
diff --git a/include/libc/float.h b/include/libc/float.h
new file mode 100644
index 0000000..ee8b96b
--- /dev/null
+++ b/include/libc/float.h
@@ -0,0 +1,18 @@
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FLT_MAX 3.402823466e+38f
+#define FLT_EPSILON 1.192092896e-07f
+#define FLT_MIN 1.175494351e-38f
+
+#define DBL_EPSILON 1.1920929e-07
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/limits.h b/include/libc/limits.h
new file mode 100644
index 0000000..e4bb310
--- /dev/null
+++ b/include/libc/limits.h
@@ -0,0 +1,24 @@
+#ifndef _LIMITS_H_
+#define _LIMITS_H_
+
+#define SCHAR_MAX 0x7f
+#define UCHAR_MAX 0xffU
+
+#if defined(__MWERKS__) && __option(unsigned_char)
+#define CHAR_MIN 0U
+#define CHAR_MAX UCHAR_MAX
+#else
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX SCHAR_MAX
+#endif
+
+#define SHRT_MAX 0x7fff
+#define USHRT_MAX 0xffffU
+
+#define INT_MAX 0x7fffffff
+#define UINT_MAX 0xffffffffU
+
+#define LONG_MAX 0x7fffffffL
+#define ULONG_MAX 0xffffffffUL
+
+#endif
diff --git a/include/libc/locale.h b/include/libc/locale.h
new file mode 100644
index 0000000..ba79c67
--- /dev/null
+++ b/include/libc/locale.h
@@ -0,0 +1,39 @@
+#ifndef _LOCALE_H_
+#define _LOCALE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct lconv {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char* currency_symbol;
+ char frac_digits;
+ char p_cs_precedes;
+ char n_cs_precedes;
+ char p_sep_by_space;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char* int_curr_symbol;
+ char int_frac_digits;
+ char int_p_cs_precedes;
+ char int_n_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/math.h b/include/libc/math.h
new file mode 100644
index 0000000..0ad14fe
--- /dev/null
+++ b/include/libc/math.h
@@ -0,0 +1,210 @@
+#ifndef _MATH_H_
+#define _MATH_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _MATH_INLINE
+#define _MATH_INLINE static inline
+#endif
+
+#ifdef __MWERKS__
+
+/* Metrowerks */
+#if __option(little_endian)
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#else
+
+/* GCC */
+#ifdef __BIG_ENDIAN__
+#define __IEEE_BIG_ENDIAN
+#endif
+#ifdef __LITTLE_ENDIAN__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#endif
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+#error Must define endianness
+#endif
+#endif
+
+#ifndef _INT32
+typedef int _INT32;
+typedef unsigned int _UINT32;
+#endif
+
+int abs(int n);
+#ifdef __MWERKS__
+#define abs(n) __abs(n)
+#define labs(n) __labs(n)
+static inline double fabs(double x) { return __fabs(x); }
+#else
+// static inline int abs(int n) {
+// int mask = n >> 31;
+// return (n + mask) ^ mask;
+// }
+#endif
+
+extern _INT32 __float_huge[];
+extern _INT32 __float_nan[];
+extern _INT32 __double_huge[];
+extern _INT32 __extended_huge[];
+
+#define HUGE_VAL (*(double*)__double_huge)
+#define INFINITY (*(float*)__float_huge)
+#define NAN (*(float*)__float_nan)
+#define HUGE_VALF (*(float*)__float_huge)
+#define HUGE_VALL (*(long double*)__extended_huge)
+
+double fabs(double x);
+double fmod(double x, double m);
+double sin(double x);
+double cos(double x);
+double atan(double x);
+double atan2(double y, double x);
+double tan(double x);
+
+_MATH_INLINE float fabsf(float x) { return (float)fabs((double)x); }
+_MATH_INLINE float sinf(float x) { return (float)sin((double)x); }
+_MATH_INLINE float cosf(float x) { return (float)cos((double)x); }
+_MATH_INLINE float atan2f(float y, float x) { return (float)atan2((double)y, (double)x); }
+float tanf(float x);
+double acos(double x);
+float acosf(float x);
+
+double ldexp(double x, int exp);
+
+double copysign(double x, double y);
+
+double floor(double x);
+
+double fabs(double x);
+double pow(double x, double y);
+
+#ifdef __MWERKS__
+#pragma cplusplus on
+#endif
+
+#ifdef __IEEE_LITTLE_ENDIAN
+#define __HI(x) (sizeof(x) == 8 ? *(1 + (_INT32*)&x) : (*(_INT32*)&x))
+#define __LO(x) (*(_INT32*)&x)
+#define __UHI(x) (sizeof(x) == 8 ? *(1 + (_UINT32*)&x) : (*(_UINT32*)&x))
+#define __ULO(x) (*(_UINT32*)&x)
+#else
+#define __LO(x) (sizeof(x) == 8 ? *(1 + (_INT32*)&x) : (*(_INT32*)&x))
+#define __HI(x) (*(_INT32*)&x)
+#define __ULO(x) (sizeof(x) == 8 ? *(1 + (_UINT32*)&x) : (*(_UINT32*)&x))
+#define __UHI(x) (*(_UINT32*)&x)
+#endif
+
+#define FP_NAN 1
+#define FP_INFINITE 2
+#define FP_ZERO 3
+#define FP_NORMAL 4
+#define FP_SUBNORMAL 5
+
+static inline int __fpclassifyf(float x) {
+ switch ((*(_INT32*)&x) & 0x7f800000) {
+ case 0x7f800000: {
+ if ((*(_INT32*)&x) & 0x007fffff)
+ return FP_NAN;
+ else
+ return FP_INFINITE;
+ break;
+ }
+ case 0: {
+ if ((*(_INT32*)&x) & 0x007fffff)
+ return FP_SUBNORMAL;
+ else
+ return FP_ZERO;
+ break;
+ }
+ }
+ return FP_NORMAL;
+}
+
+static inline int __fpclassifyd(double x) {
+ switch (__HI(x) & 0x7ff00000) {
+ case 0x7ff00000: {
+ if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff))
+ return FP_NAN;
+ else
+ return FP_INFINITE;
+ break;
+ }
+ case 0: {
+ if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff))
+ return FP_SUBNORMAL;
+ else
+ return FP_ZERO;
+ break;
+ }
+ }
+ return FP_NORMAL;
+}
+
+#define fpclassify(x) \
+ (sizeof(x) == sizeof(float) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x)))
+#define isnormal(x) (fpclassify(x) == FP_NORMAL)
+#define isnan(x) (fpclassify(x) == FP_NAN)
+#define isinf(x) (fpclassify(x) == FP_INFINITE)
+#define isfinite(x) ((fpclassify(x) > FP_INFINITE))
+
+inline float sqrtf(float x) {
+ const double _half = .5;
+ const double _three = 3.0;
+ volatile float y;
+
+ if (x > 0.0f) {
+ double guess = __frsqrte((double)x); /* returns an approximation to */
+ guess = _half * guess * (_three - guess * guess * x); /* now have 12 sig bits
+ */
+ guess = _half * guess * (_three - guess * guess * x); /* now have 24 sig bits
+ */
+ guess = _half * guess * (_three - guess * guess * x); /* now have 32 sig bits
+ */
+ y = (float)(x * guess);
+ return y;
+ }
+ return x;
+}
+
+static inline double sqrt(double x) {
+ if (x > 0.0) {
+ double guess = __frsqrte(x); /* returns an approximation to */
+ guess = .5 * guess * (3.0 - guess * guess * x); /* now have 8 sig bits */
+ guess = .5 * guess * (3.0 - guess * guess * x); /* now have 16 sig bits */
+ guess = .5 * guess * (3.0 - guess * guess * x); /* now have 32 sig bits */
+ guess = .5 * guess * (3.0 - guess * guess * x); /* now have > 53 sig bits */
+ return x * guess;
+ } else if (x == 0.0) {
+ return 0;
+ } else if (x) {
+ return NAN;
+ }
+ return INFINITY;
+}
+
+static inline float ldexpf(float x, int exp) { return (float)ldexp((double)x, exp); }
+static inline double scalbn(double x, int n) { return ldexp(x, n); }
+static inline float scalbnf(float x, int n) { return (float)ldexpf(x, n); }
+
+#ifdef __MWERKS__
+#pragma cplusplus reset
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/mem_funcs.h b/include/libc/mem_funcs.h
new file mode 100644
index 0000000..92f19d4
--- /dev/null
+++ b/include/libc/mem_funcs.h
@@ -0,0 +1,22 @@
+#ifndef _MEM_FUNCS_H_
+#define _MEM_FUNCS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __min_bytes_for_long_copy 32
+
+void __copy_mem(void* dst, const void* src, unsigned long n);
+void __move_mem(void* dst, const void* src, unsigned long n);
+void __copy_longs_aligned(void* dst, const void* src, unsigned long n);
+void __copy_longs_rev_aligned(void* dst, const void* src, unsigned long n);
+void __copy_longs_unaligned(void* dst, const void* src, unsigned long n);
+void __copy_longs_rev_unaligned(void* dst, const void* src, unsigned long n);
+void __fill_mem(void* dst, int val, unsigned long n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/stdarg.h b/include/libc/stdarg.h
new file mode 100644
index 0000000..8834b29
--- /dev/null
+++ b/include/libc/stdarg.h
@@ -0,0 +1,39 @@
+#ifndef _STDARG_H_
+#define _STDARG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __MWERKS__
+typedef struct {
+ char gpr;
+ char fpr;
+ char reserved[2];
+ char* input_arg_area;
+ char* reg_save_area;
+} __va_list[1];
+typedef __va_list va_list;
+
+#ifndef __MWERKS__
+extern void __builtin_va_info(va_list*);
+#endif
+
+void* __va_arg(va_list v_list, unsigned char type);
+
+#define va_start(ap, fmt) ((void)fmt, __builtin_va_info(&ap))
+#define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t))))
+#define va_end(ap) (void)0
+
+#else
+typedef __builtin_va_list va_list;
+#define va_start(v, l) __builtin_va_start(v, l)
+#define va_end(v) __builtin_va_end(v)
+#define va_arg(v, l) __builtin_va_arg(v, l)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/stddef.h b/include/libc/stddef.h
new file mode 100644
index 0000000..d6b4a8d
--- /dev/null
+++ b/include/libc/stddef.h
@@ -0,0 +1,23 @@
+#ifndef _STDDEF_H_
+#define _STDDEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define offsetof(type, member) ((size_t) & (((type*)0)->member))
+
+/* These break 1.2.5 */
+//typedef __typeof__(sizeof(0)) size_t;
+//typedef __typeof__((char*)0 - (char*)0) ptrdiff_t;
+typedef unsigned long size_t;
+typedef long ptrdiff_t;
+#ifndef NULL
+#define NULL 0L
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/stdint.h b/include/libc/stdint.h
new file mode 100644
index 0000000..fd88f2e
--- /dev/null
+++ b/include/libc/stdint.h
@@ -0,0 +1,14 @@
+#ifndef _STDINT_H_
+#define _STDINT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long int uintptr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/stdio.h b/include/libc/stdio.h
new file mode 100644
index 0000000..9937d4d
--- /dev/null
+++ b/include/libc/stdio.h
@@ -0,0 +1,135 @@
+#ifndef _STDIO
+#define _STDIO
+
+#include "types.h"
+#include <stdarg.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define __ungetc_buffer_size 2
+
+typedef unsigned long __file_handle;
+typedef unsigned long fpos_t;
+#ifndef __cplusplus
+typedef unsigned short wchar_t;
+#endif
+
+enum __io_modes {
+ __read = 1,
+ __write = 2,
+ __read_write = 3,
+ __append = 4,
+};
+enum __file_kinds {
+ __closed_file,
+ __disk_file,
+ __console_file,
+ __unavailable_file,
+};
+enum __file_orientation {
+ __unoriented,
+ __char_oriented,
+ __wide_oriented,
+};
+
+enum __io_results {
+ __no_io_error,
+ __io_error,
+ __io_EOF,
+};
+
+typedef struct {
+ unsigned int open_mode : 2;
+ unsigned int io_mode : 3;
+ unsigned int buffer_mode : 2;
+ unsigned int file_kind : 3;
+ unsigned int file_orientation : 2;
+ unsigned int binary_io : 1;
+} __file_modes;
+
+enum __io_states {
+ __neutral,
+ __writing,
+ __reading,
+ __rereading,
+};
+
+typedef struct {
+ unsigned int io_state : 3;
+ unsigned int free_buffer : 1;
+ unsigned char eof;
+ unsigned char error;
+} __file_state;
+
+typedef void (*__idle_proc)(void);
+typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc);
+typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count,
+ __idle_proc idle_proc);
+typedef int (*__close_proc)(__file_handle file);
+
+typedef struct _IO_FILE {
+ __file_handle handle;
+ __file_modes mode;
+ __file_state state;
+ unsigned char is_dynamically_allocated;
+ unsigned char char_buffer;
+ unsigned char char_buffer_overflow;
+ unsigned char ungetc_buffer[__ungetc_buffer_size];
+ wchar_t ungetwc_buffer[__ungetc_buffer_size];
+ unsigned long position;
+ unsigned char* buffer;
+ unsigned long buffer_size;
+ unsigned char* buffer_ptr;
+ unsigned long buffer_len;
+ unsigned long buffer_alignment;
+ unsigned long saved_buffer_len;
+ unsigned long buffer_pos;
+ __pos_proc position_proc;
+ __io_proc read_proc;
+ __io_proc write_proc;
+ __close_proc close_proc;
+ __idle_proc idle_proc;
+ struct _IO_FILE* next_file_struct;
+} FILE;
+
+typedef struct {
+ char* CharStr;
+ size_t MaxCharCount;
+ size_t CharsWritten;
+} __OutStrCtrl;
+
+typedef struct {
+ char* NextChar;
+ int NullCharDetected;
+} __InStrCtrl;
+
+#define EOF -1L
+
+enum __ReadProcActions { __GetChar, __UngetChar, __CheckForError };
+
+#define _IONBF 0
+#define _IOLBF 1
+#define _IOFBF 2
+
+int puts(const char* s);
+int printf(const char*, ...);
+int sprintf(char* s, const char* format, ...);
+int vprintf(const char* format, va_list arg);
+int vsprintf(char* s, const char* format, va_list arg);
+size_t fread(const void*, size_t memb_size, size_t num_memb, FILE*);
+size_t fwrite(const void*, size_t memb_size, size_t num_memb, FILE*);
+int fseek(FILE* file, long offset, int mode);
+size_t __fwrite(const void*, size_t, size_t, FILE*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _STDIO
diff --git a/include/libc/stdlib.h b/include/libc/stdlib.h
new file mode 100644
index 0000000..0c1a972
--- /dev/null
+++ b/include/libc/stdlib.h
@@ -0,0 +1,25 @@
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <stddef.h>
+#include <wchar.h>
+
+#define RAND_MAX 32767
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void srand(unsigned int seed);
+int rand(void);
+void exit(int status);
+size_t wcstombs(char* dest, const wchar_t* src, size_t max);
+
+typedef int (*_compare_function)(const void*, const void*);
+void qsort(void*, size_t, size_t, _compare_function);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/string.h b/include/libc/string.h
new file mode 100644
index 0000000..59b8893
--- /dev/null
+++ b/include/libc/string.h
@@ -0,0 +1,27 @@
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma section code_type ".init"
+void* memcpy(void* dst, const void* src, size_t n);
+void* memset(void* dst, int val, size_t n);
+void __fill_mem(void* dst, int val, size_t n);
+#pragma section code_type
+
+size_t strlen(const char* s);
+char* strcpy(char* dest, const char* src);
+char* strncpy(char* dest, const char* src, size_t num);
+int strcmp(const char* s1, const char* s2);
+int strncmp(const char* s1, const char* s2, size_t n);
+char* strncat(char* dest, const char* src, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/libc/wchar.h b/include/libc/wchar.h
new file mode 100644
index 0000000..6dc82b0
--- /dev/null
+++ b/include/libc/wchar.h
@@ -0,0 +1,16 @@
+#ifndef _WCHAR_H_
+#define _WCHAR_H_
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int fwide(FILE* stream, int mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/Dolphin/GBA/GBA.c b/src/Dolphin/GBA/GBA.c
new file mode 100644
index 0000000..bb89f2e
--- /dev/null
+++ b/src/Dolphin/GBA/GBA.c
@@ -0,0 +1,109 @@
+#include "dolphin/GBAPriv.h"
+
+static GBASecParams SecParams[4];
+GBA __GBA[4];
+BOOL __GBAReset = FALSE;
+
+static BOOL OnReset(BOOL);
+
+static OSResetFunctionInfo ResetFunctionInfo = {
+ OnReset,
+ 127
+};
+
+void ShortCommandProc(s32 chan) {
+ GBA* gba;
+ gba = &__GBA[chan];
+
+ if (gba->result != 0) {
+ return;
+ }
+
+ if (gba->dst[0] != 0 || gba->dst[1] != 4) {
+ gba->result = 1;
+ return;
+ }
+
+ gba->status[0] = gba->dst[2] & GBA_JSTAT_MASK;
+}
+
+void GBAInit() {
+ s32 i;
+ GBA* gba;
+ for (i = 0; i < 4; ++i) {
+ gba = &__GBA[i];
+ gba->delay = OSMicrosecondsToTicks(60);
+ OSInitThreadQueue(&gba->thread_queue);
+ gba->param = &SecParams[i];
+
+ // ASSERTMSG((u32) gba->param % 32 == 0)
+ }
+
+ OSInitAlarm();
+ DSPInit();
+ __GBAReset = FALSE;
+
+ OSRegisterResetFunction(&ResetFunctionInfo);
+}
+
+s32 GBAGetStatusAsync(s32 chan, u8* status, GBACallback callback) {
+ GBA* gba;
+ s32 ret;
+ gba = &__GBA[chan];
+ if (gba->callback != NULL) {
+ ret = GBA_BUSY;
+ } else {
+ gba->command = 0;
+ gba->status = status;
+ gba->callback = callback;
+ ret = __GBATransfer(chan, 1, 3, ShortCommandProc);
+ }
+
+ return ret;
+}
+
+
+s32 GBAGetStatus(s32 chan, u8* status) {
+ s32 ret;
+ ret = GBAGetStatusAsync(chan, status, __GBASyncCallback);
+
+ if (ret != GBA_READY) {
+ return ret;
+ }
+
+ return __GBASync(chan);
+}
+
+
+s32 GBAResetAsync(s32 chan, u8* status, GBACallback callback) {
+ GBA* gba;
+ s32 ret;
+ gba = &__GBA[chan];
+ if (gba->callback != NULL) {
+ ret = GBA_BUSY;
+ } else {
+ gba->command = 0xFF;
+ gba->status = status;
+ gba->callback = callback;
+ ret = __GBATransfer(chan, 1, 3, ShortCommandProc);
+ }
+
+ return ret;
+}
+
+
+s32 GBAReset(s32 chan, u8* status) {
+ s32 ret;
+
+ ret = GBAResetAsync(chan, status, __GBASyncCallback);
+ if (ret != GBA_READY) {
+ return ret;
+ }
+
+ return __GBASync(chan);
+}
+
+BOOL OnReset(BOOL) {
+ __GBAReset = TRUE;
+ return TRUE;
+}
diff --git a/src/Dolphin/GBA/GBAGetProcessStatus.c b/src/Dolphin/GBA/GBAGetProcessStatus.c
new file mode 100644
index 0000000..38d8c38
--- /dev/null
+++ b/src/Dolphin/GBA/GBAGetProcessStatus.c
@@ -0,0 +1,25 @@
+#include "dolphin/GBAPriv.h"
+
+s32 GBAGetProcessStatus(s32 chan, u8* percentp) {
+ GBA* gba;
+ s32 ret;
+ BOOL enabled;
+
+ gba = &__GBA[chan];
+ enabled = OSDisableInterrupts();
+
+ if (gba->jboot_callback == NULL) {
+ if (gba->callback == NULL) {
+ ret = 0;
+ } else {
+ ret = 2;
+ }
+ } else {
+ ret = 2;
+
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ return ret;
+}
diff --git a/src/Dolphin/GBA/GBARead.c b/src/Dolphin/GBA/GBARead.c
new file mode 100644
index 0000000..ab19bbb
--- /dev/null
+++ b/src/Dolphin/GBA/GBARead.c
@@ -0,0 +1,42 @@
+#include "dolphin/GBAPriv.h"
+
+void ReadProc(s32 chan) {
+ GBA* gba;
+ gba = &__GBA[chan];
+
+ if (gba->result == 0) {
+ memcpy(gba->buffer, &gba->dst, 4);
+ gba->status[0] = gba->_09 & GBA_JSTAT_MASK;
+ }
+}
+
+s32 GBAReadAsync(s32 chan, u8* dst, u8* status, GBACallback callback) {
+ GBA* gba;
+ s32 ret;
+
+ gba = &__GBA[chan];
+
+ if (gba->callback != NULL) {
+ ret = 2;
+ } else {
+ gba->command = 0x14;
+ gba->buffer = dst;
+ gba->status = status;
+ gba->callback = callback;
+ ret = __GBATransfer(chan, 1, 5, ReadProc);
+ }
+
+ return ret;
+}
+
+
+s32 GBARead(s32 chan, u8* dst, u8* status) {
+ s32 tmp;
+ s32 ret;
+ ret = GBAReadAsync(chan, dst, status, __GBASyncCallback);
+ if (ret != GBA_READY) {
+ return ret;
+ }
+
+ return __GBASync(chan);
+}
diff --git a/src/Dolphin/GBA/GBAWrite.c b/src/Dolphin/GBA/GBAWrite.c
new file mode 100644
index 0000000..f040f92
--- /dev/null
+++ b/src/Dolphin/GBA/GBAWrite.c
@@ -0,0 +1,42 @@
+#include "dolphin/GBAPriv.h"
+
+void WriteProc(s32 chan) {
+ GBA* gba;
+ gba = &__GBA[chan];
+
+ if (gba->result != 0) {
+ return;
+ }
+
+ gba->status[0] = gba->dst[0] & GBA_JSTAT_MASK;
+}
+
+s32 GBAWriteAsync(s32 chan, u8* src, u8* status, GBACallback callback) {
+ GBA* gba;
+ s32 ret;
+ gba = &__GBA[chan];
+
+ if (gba->callback != NULL) {
+ ret = GBA_BUSY;
+ } else {
+ gba->command = 0x15;
+ memcpy(gba->src, src, 4);
+ gba->buffer = src;
+ gba->status = status;
+ gba->callback = callback;
+ ret = __GBATransfer(chan, 5, 1, WriteProc);
+ }
+
+ return ret;
+}
+
+
+s32 GBAWrite(s32 chan, u8* src, u8* status) {
+ s32 ret;
+ s32 tmp;
+ ret = GBAWriteAsync(chan, src, status, __GBASyncCallback);
+ if (ret != GBA_READY) {
+ return ret;
+ }
+ return __GBASync(chan);
+}
diff --git a/src/Dolphin/GBA/GBAXfer.c b/src/Dolphin/GBA/GBAXfer.c
new file mode 100644
index 0000000..c88ffd1
--- /dev/null
+++ b/src/Dolphin/GBA/GBAXfer.c
@@ -0,0 +1,163 @@
+#include "dolphin/GBAPriv.h"
+#include "dolphin/sipriv.h"
+
+void __GBAHandler(s32 chan, u32 sr, OSContext* context) {
+ int tmp;
+ GBA* gba;
+ OSContext tmpCtx;
+ GBACallback callback;
+ GBATransferCallback xferCallback;
+ gba = &__GBA[chan];
+ if (__GBAReset != 0) {
+ return;
+ }
+
+ if ((sr & 0xf)) {
+ gba->result = 1;
+ } else {
+ gba->result = 0;
+ }
+
+ if (gba->_38 != NULL) {
+ xferCallback = gba->_38;
+ gba->_38 = NULL;
+ xferCallback(chan);
+ }
+
+ if (gba->callback == NULL) {
+ return;
+ }
+
+ OSClearContext(&tmpCtx);
+ OSSetCurrentContext(&tmpCtx);
+ callback = gba->callback;
+ gba->callback = NULL;
+ callback(chan, gba->result);
+ OSClearContext(&tmpCtx);
+ OSSetCurrentContext(context);
+}
+
+void __GBASyncCallback(s32 chan, s32 ret) { OSWakeupThread(&__GBA[chan].thread_queue); }
+
+#ifdef FULL_FRANK
+/* This actually does match, but has an epilogue swap */
+s32 __GBASync(s32 chan) {
+ GBA* gba;
+ s32 enabled;
+ s32 ret;
+ gba = &__GBA[chan];
+
+ enabled = OSDisableInterrupts();
+ while (gba->callback != NULL) {
+ OSSleepThread(&gba->thread_queue);
+ }
+
+ ret = gba->result;
+ OSRestoreInterrupts(enabled);
+
+ return ret;
+}
+#else
+extern void OSSleepThread();
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm s32 __GBASync(s32 chan) {
+ nofralloc
+ mflr r0
+ lis r4, __GBA@ha
+ stw r0, 4(r1)
+ slwi r3, r3, 8
+ addi r0, r4, __GBA@l
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ add r31, r0, r3
+ stw r30, 0x10(r1)
+ bl OSDisableInterrupts
+ mr r30, r3
+ b lbl_803CAD50
+lbl_803CAD48:
+ addi r3, r31, 0x24
+ bl OSSleepThread
+lbl_803CAD50:
+ lwz r0, 0x1c(r31)
+ cmplwi r0, 0
+ bne lbl_803CAD48
+ lwz r31, 0x20(r31)
+ mr r3, r30
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+void TypeAndStatusCallback(s32 chan, u32 type) {
+ s32 tmp;
+ GBA* gba;
+ OSContext* context;
+ GBACallback callback;
+ GBATransferCallback xferCallback;
+ OSContext tmpContext;
+ gba = &__GBA[chan];
+ if (__GBAReset != 0) {
+ return;
+ }
+
+ if ((type & 0xFF) != 0 || (type & 0xffff0000) != 0x40000) {
+ gba->result = GBA_NOT_READY;
+ } else {
+ if (SITransfer(chan, &gba->command, gba->_0c, gba->dst, gba->_10, __GBAHandler, gba->delay)) {
+ return;
+ }
+ gba->result = GBA_BUSY;
+ }
+
+ if (gba->_38 != NULL) {
+ xferCallback = gba->_38;
+ gba->_38 = NULL;
+ xferCallback(chan);
+ }
+
+ if (gba->callback != NULL) {
+ context = OSGetCurrentContext();
+ OSClearContext(&tmpContext);
+ OSSetCurrentContext(&tmpContext);
+ callback = gba->callback;
+ gba->callback = NULL;
+ callback(chan, gba->result);
+ OSClearContext(&tmpContext);
+ OSSetCurrentContext(context);
+ __OSReschedule();
+ }
+}
+
+s32 __GBATransfer(s32 chan, s32 w1, s32 w2, GBATransferCallback callback) {
+ s32 enabled;
+ GBA* gba;
+ gba = &__GBA[chan];
+ enabled = OSDisableInterrupts();
+ gba->_38 = callback;
+ gba->_0c = w1;
+ gba->_10 = w2;
+ SIGetTypeAsync(chan, TypeAndStatusCallback);
+ OSRestoreInterrupts(enabled);
+
+ return GBA_READY;
+}
+
+OSTime __GBASetDelay(s32 chan, OSTime delay) {
+ OSTime oldDelay;
+ GBA* gba;
+ gba = &__GBA[chan];
+ oldDelay = gba->delay;
+ gba->delay = delay;
+ return oldDelay;
+}
diff --git a/src/Dolphin/PPCArch.c b/src/Dolphin/PPCArch.c
new file mode 100644
index 0000000..173c685
--- /dev/null
+++ b/src/Dolphin/PPCArch.c
@@ -0,0 +1,563 @@
+#include "types.h"
+#include "asm_types.h"
+// clang-format off
+
+union FpscrUnion
+{
+ f64 f;
+ struct
+ {
+ u32 fpscr_pad;
+ u32 fpscr;
+ } u;
+};
+
+#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable)
+
+void PPCMthid0 ( u32 newHID0 );
+
+/*
+ * --INFO--
+ * Address: 8036F7D4
+ * Size: 000008
+ */
+asm u32 PPCMfmsr (void)
+{
+ nofralloc
+ mfmsr r3
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F7DC
+ * Size: 000008
+ */
+asm void PPCMtmsr (register u32 newMSR)
+{
+ nofralloc
+ mtmsr newMSR
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 00000C
+ */
+void PPCOrMsr(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 00000C
+ */
+void PPCAndMsr(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 00000C
+ */
+void PPCAndCMsr(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: 8036F7E4
+ * Size: 000008
+ */
+asm u32 PPCMfhid0 (void)
+{
+ nofralloc
+ mfspr r3, HID0
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F7EC
+ * Size: 000008
+ */
+asm void PPCMthid0 (register u32 newHID0)
+{
+ nofralloc
+ mtspr HID0, newHID0
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+void PPCMfhid1(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: 8036F7F4
+ * Size: 000008
+ */
+asm u32 PPCMfl2cr (void)
+{
+ nofralloc
+ mfspr r3, L2CR
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F7FC
+ * Size: 000008
+ */
+asm void PPCMtl2cr (register u32 newL2cr)
+{
+ nofralloc
+ mtspr L2CR, newL2cr
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F804
+ * Size: 000008
+ */
+__declspec ( weak ) asm void PPCMtdec ( register u32 newDec )
+{
+ nofralloc
+ mtdec newDec
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+void PPCMfdec(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: 8036F80C
+ * Size: 000008
+ */
+asm void PPCSync (void)
+{
+ nofralloc
+ sc
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000034
+ */
+asm void PPCEieio(void) {
+ nofralloc
+ mfmsr r5
+ rlwinm r6, r5, 0, 0x11, 0xf
+ mtmsr r6
+ mfspr r3, hid0
+ ori r4, r3, 8
+ mtspr hid0, r4
+ isync
+ eieio
+ isync
+
+ mtspr hid0, r3
+ mtmsr r5
+ isync
+
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F814
+ * Size: 000014
+ */
+__declspec ( weak ) asm void PPCHalt (void) //spins infinitely
+{
+ nofralloc
+
+ sync
+
+_spin:
+ nop
+ li r3, 0
+ nop
+ b _spin
+
+ // NEVER REACHED
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfmmcr0(void)
+{
+ nofralloc
+ mfspr r3, MMCR0
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ * UNUSED
+ */
+asm void PPCMtmmcr0 (register u32 newMmcr0)
+{
+ nofralloc
+ mtspr MMCR0, newMmcr0
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfmmcr1(void)
+{
+ nofralloc
+ mfspr r3, MMCR1
+ blr}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ * UNUSED
+ */
+asm void PPCMtmmcr1 (register u32 newMmcr1)
+{
+ nofralloc
+ mtspr MMCR1, newMmcr1
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfpmc1(void)
+{
+ nofralloc
+ mfspr r3, PMC1
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ * UNUSED
+ */
+asm void PPCMtpmc1 (register u32 newPmc1)
+{
+ nofralloc
+ mtspr PMC1, newPmc1
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfpmc2(void)
+{
+ nofralloc
+ mfspr r3, PMC2
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ * UNUSED
+ */
+asm void PPCMtpmc2 (register u32 newPmc2)
+{
+ nofralloc
+ mtspr PMC2, newPmc2
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfpmc3(void)
+{
+ nofralloc
+ mfspr r3, PMC2
+ blr}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ * UNUSED
+ */
+asm void PPCMtpmc3 (register u32 newPmc3)
+{
+ nofralloc
+ mtspr PMC3, newPmc3
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfpmc4(void)
+{
+ nofralloc
+ mfspr r3, PMC4
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ * UNUSED
+ */
+asm void PPCMtpmc4 (register u32 newPmc4)
+{
+ nofralloc
+ mtspr PMC4, newPmc4
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfsia(void)
+{
+ nofralloc
+ mfspr r3, SIA
+ blr}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMtsia(register u32 newSia)
+{
+ nofralloc
+ mtspr SIA, newSia
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F828
+ * Size: 000020
+ */
+u32 PPCMffpscr(void)
+{
+ union FpscrUnion m;
+
+
+ asm
+ {
+ mffs fp31
+ stfd fp31, m.f;
+ }
+
+ return m.u.fpscr;
+}
+
+/*
+ * --INFO--
+ * Address: 8036F848
+ * Size: 000028
+ */
+void PPCMtfpscr(register u32 newFPSCR)
+{
+ union FpscrUnion m;
+
+ asm
+ {
+ li r4, 0
+ stw r4, m.u.fpscr_pad;
+ stw newFPSCR, m.u.fpscr
+ lfd fp31, m.f
+ mtfsf 0xff, fp31
+ }
+}
+
+/*
+ * --INFO--
+ * Address: 8036F870
+ * Size: 000008
+ */
+asm u32 PPCMfhid2 ( void )
+{
+ nofralloc
+ mfspr r3, HID2
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F878
+ * Size: 000008
+ */
+asm void PPCMthid2 ( register u32 newhid2 )
+{
+ nofralloc
+ mtspr HID2, newhid2
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F880
+ * Size: 00000C
+ */
+asm u32 PPCMfwpar(void)
+{
+ nofralloc
+ sync
+ mfspr r3, WPAR
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: 8036F88C
+ * Size: 000008
+ */
+asm void PPCMtwpar ( register u32 newwpar )
+{
+ nofralloc
+ mtspr WPAR, newwpar
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfdmaU(void)
+{
+ nofralloc
+ mfspr r3, DMA_U
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+asm void PPCMfdmaL(void)
+{
+ nofralloc
+ mfspr r3, DMA_L
+ blr
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+void PPCMtdmaU(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+void PPCMtdmaL(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000008
+ */
+void PPCMfpvr(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: ........
+ * Size: 000028
+ */
+void PPCEnableSpeculation(void)
+{
+ // UNUSED FUNCTION
+}
+
+/*
+ * --INFO--
+ * Address: 8036F894
+ * Size: 000028
+ */
+void PPCDisableSpeculation (void)
+{
+ PPCMthid0(PPCMfhid0() | HID0_SPD);
+}
+
+/*
+ * --INFO--
+ * Address: 8036F8BC
+ * Size: 000008
+ */
+asm void PPCSetFpIEEEMode(void)
+{
+ nofralloc
+ mtfsb0 4*7+1
+ blr
+}
+/*
+ * --INFO--
+ * Address: 8036F8C4
+ * Size: 000008
+ */
+asm void PPCSetFpNonIEEEMode (void)
+{
+ nofralloc
+ mtfsb1 4*7+1
+ blr
+}
+// clang-format on
diff --git a/src/Dolphin/ai.c b/src/Dolphin/ai.c
new file mode 100644
index 0000000..fb39c78
--- /dev/null
+++ b/src/Dolphin/ai.c
@@ -0,0 +1,378 @@
+#include "dolphin/ai.h"
+#include "dolphin/dsp_regs.h"
+#include "dolphin/os.h"
+
+const char* __AIVersion = "<< Dolphin SDK - AI\trelease build: Sep 5 2002 05:34:25 (0x2301) >>";
+
+static AISCallback __AIS_Callback = NULL;
+static AIDCallback __AID_Callback = NULL;
+static u8* __CallbackStack;
+static u8* __OldStack;
+static volatile s32 __AI_init_flag = FALSE;
+static volatile s32 __AID_Active = FALSE;
+
+static OSTime bound_32KHz;
+static OSTime bound_48KHz;
+static OSTime min_wait;
+static OSTime max_wait;
+static OSTime buffer;
+
+void __AISHandler(s16 interrupt, OSContext* context);
+void __AIDHandler(s16 interrupt, OSContext* context);
+void __AICallbackStackSwitch(register AIDCallback cb);
+void __AI_SRC_INIT(void);
+
+#ifdef FULL_FRANK
+AIDCallback AIRegisterDMACallback(AIDCallback callback) {
+ s32 oldInts;
+ AIDCallback ret;
+
+ ret = __AID_Callback;
+ oldInts = OSDisableInterrupts();
+ __AID_Callback = callback;
+ OSRestoreInterrupts(oldInts);
+ return ret;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm AIDCallback AIRegisterDMACallback(AIDCallback callback) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ lwz r31, __AID_Callback
+ bl OSDisableInterrupts
+ stw r30, __AID_Callback
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+void AIInitDMA(u32 addr, u32 length) {
+ s32 oldInts;
+ oldInts = OSDisableInterrupts();
+ __DSPRegs[24] = (u16)((__DSPRegs[24] & ~0x3FF) | (addr >> 16));
+ __DSPRegs[25] = (u16)((__DSPRegs[25] & ~0xFFE0) | (0xffff & addr));
+ __DSPRegs[27] = (u16)((__DSPRegs[27] & ~0x7FFF) | (u16)((length >> 5) & 0xFFFF));
+ OSRestoreInterrupts(oldInts);
+}
+
+void AIStartDMA() { __DSPRegs[27] |= 0x8000; }
+
+void AIStopDMA(void) { __DSPRegs[27] &= ~0x8000; }
+
+u32 AIGetDMAStartAddr(void) {
+ return (u32)((__DSPRegs[24] & 0x03ff) << 16) | (__DSPRegs[25] & 0xffe0);
+}
+
+#ifdef FULL_FRANK
+AISCallback AIRegisterStreamCallback(AISCallback callback) {
+ AISCallback ret;
+ s32 oldInts;
+
+ ret = __AIS_Callback;
+ oldInts = OSDisableInterrupts();
+ __AIS_Callback = callback;
+ OSRestoreInterrupts(oldInts);
+ return ret;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm AISCallback AIRegisterStreamCallback(AISCallback callback) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ lwz r31, __AIS_Callback
+ bl OSDisableInterrupts
+ stw r30, __AIS_Callback
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+void AIResetStreamSampleCount(void) { __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20; }
+
+void AISetStreamTrigger(u32 trigger) { __AIRegs[3] = trigger; }
+
+void AISetStreamPlayState(u32 state) {
+ s32 oldInts;
+ u8 volRight;
+ u8 volLeft;
+
+ if (state == AIGetStreamPlayState()) {
+ return;
+ }
+ if ((AIGetStreamSampleRate() == 0U) && (state == 1)) {
+ volRight = AIGetStreamVolRight();
+ volLeft = AIGetStreamVolLeft();
+ AISetStreamVolRight(0);
+ AISetStreamVolLeft(0);
+ oldInts = OSDisableInterrupts();
+ __AI_SRC_INIT();
+ __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
+ __AIRegs[0] = (__AIRegs[0] & ~1) | 1;
+ OSRestoreInterrupts(oldInts);
+ AISetStreamVolLeft(volRight);
+ AISetStreamVolRight(volLeft);
+ } else {
+ __AIRegs[0] = (__AIRegs[0] & ~1) | state;
+ }
+}
+
+u32 AIGetStreamPlayState() { return __AIRegs[0] & 1; }
+
+void AISetDSPSampleRate(u32 rate) {
+ u32 state;
+ s32 oldInts;
+ u8 left;
+ u8 right;
+ u32 sampleRate;
+
+ if (rate == AIGetDSPSampleRate()) {
+ return;
+ }
+
+ __AIRegs[0] &= ~0x40;
+ if (rate == 0) {
+ left = AIGetStreamVolLeft();
+ right = AIGetStreamVolRight();
+ state = AIGetStreamPlayState();
+ sampleRate = AIGetStreamSampleRate();
+ AISetStreamVolLeft(0);
+ AISetStreamVolRight(0);
+ oldInts = OSDisableInterrupts();
+ __AI_SRC_INIT();
+ __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
+ __AIRegs[0] = (__AIRegs[0] & ~2) | (sampleRate * 2);
+ __AIRegs[0] = (__AIRegs[0] & ~1) | state;
+ __AIRegs[0] |= 0x40;
+ OSRestoreInterrupts(oldInts);
+ AISetStreamVolLeft(left);
+ AISetStreamVolRight(right);
+ }
+}
+
+u32 AIGetDSPSampleRate() { return ((__AIRegs[0] >> 6) & 1) ^ 1; }
+
+void __AI_set_stream_sample_rate(u32 rate) {
+ s32 oldInts;
+ s32 state;
+ u8 left;
+ u8 right;
+ s32 temp_r26;
+
+ if (rate == AIGetStreamSampleRate()) {
+ return;
+ }
+ state = AIGetStreamPlayState();
+ left = AIGetStreamVolLeft();
+ right = AIGetStreamVolRight();
+ AISetStreamVolRight(0);
+ AISetStreamVolLeft(0);
+ temp_r26 = __AIRegs[0] & 0x40;
+ __AIRegs[0] &= ~0x40;
+ oldInts = OSDisableInterrupts();
+ __AI_SRC_INIT();
+ __AIRegs[0] |= temp_r26;
+ __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
+ __AIRegs[0] = (__AIRegs[0] & ~2) | (rate * 2);
+ OSRestoreInterrupts(oldInts);
+ AISetStreamPlayState(state);
+ AISetStreamVolLeft(left);
+ AISetStreamVolRight(right);
+}
+
+u32 AIGetStreamSampleRate() { return (__AIRegs[0] >> 1) & 1; }
+
+void AISetStreamVolLeft(u8 volume) { __AIRegs[1] = (__AIRegs[1] & ~0xFF) | (volume & 0xFF); }
+
+u8 AIGetStreamVolLeft() { return __AIRegs[1]; }
+
+void AISetStreamVolRight(u8 volume) {
+ __AIRegs[1] = (__AIRegs[1] & ~0xFF00) | ((volume & 0xFF) << 8);
+}
+
+u8 AIGetStreamVolRight() { return __AIRegs[1] >> 8; }
+
+void AIInit(u8* stack) {
+ if (__AI_init_flag == TRUE) {
+ return;
+ }
+
+ OSRegisterVersion(__AIVersion);
+ bound_32KHz = OSNanosecondsToTicks(31524);
+ bound_48KHz = OSNanosecondsToTicks(42024);
+ min_wait = OSNanosecondsToTicks(42000);
+ max_wait = OSNanosecondsToTicks(63000);
+ buffer = OSNanosecondsToTicks(3000);
+
+ AISetStreamVolRight(0);
+ AISetStreamVolLeft(0);
+ AISetStreamTrigger(0);
+ AIResetStreamSampleCount();
+ __AI_set_stream_sample_rate(1);
+ AISetDSPSampleRate(0);
+ __AIS_Callback = 0;
+ __AID_Callback = 0;
+ __CallbackStack = stack;
+ __OSSetInterruptHandler(5, __AIDHandler);
+ __OSUnmaskInterrupts(0x04000000);
+ __OSSetInterruptHandler(8, __AISHandler);
+ __OSUnmaskInterrupts(0x800000);
+ __AI_init_flag = TRUE;
+}
+
+void __AISHandler(s16 interrupt, OSContext* context) {
+ OSContext tmpContext;
+ __AIRegs[0] |= 8;
+ OSClearContext(&tmpContext);
+ OSSetCurrentContext(&tmpContext);
+ if (__AIS_Callback != NULL) {
+ __AIS_Callback(__AIRegs[2]);
+ }
+ OSClearContext(&tmpContext);
+ OSSetCurrentContext(context);
+}
+
+void __AIDHandler(s16 interrupt, OSContext* context) {
+ OSContext tempContext;
+ u32 temp = __DSPRegs[5];
+ __DSPRegs[5] = (temp & ~0xA0) | 8;
+ OSClearContext(&tempContext);
+ OSSetCurrentContext(&tempContext);
+ if (__AID_Callback && !__AID_Active) {
+ __AID_Active = TRUE;
+ if (__CallbackStack) {
+ __AICallbackStackSwitch(__AID_Callback);
+ } else {
+ __AID_Callback();
+ }
+
+ __AID_Active = FALSE;
+ }
+
+ OSClearContext(&tempContext);
+ OSSetCurrentContext(context);
+}
+
+// clang-format off
+asm void __AICallbackStackSwitch(register AIDCallback cb) {
+ // Allocate stack frame
+ fralloc
+
+ // Store current stack
+ lis r5, __OldStack@ha
+ addi r5, r5, __OldStack@l
+ stw r1, 0(r5)
+
+ // Load stack for callback
+ lis r5, __CallbackStack@ha
+ addi r5, r5, __CallbackStack@l
+ lwz r1,0(r5)
+
+ // Move stack down 8 bytes
+ subi r1, r1, 8
+ // Call callback
+ mtlr cb
+ blrl
+
+ // Restore old stack
+ lis r5, __OldStack @ha
+ addi r5, r5, __OldStack@l
+ lwz r1,0(r5)
+
+ // Free stack frame
+ frfree
+
+ blr
+}
+// clang-format on
+
+void __AI_SRC_INIT(void) {
+ OSTime rise32 = 0;
+ OSTime rise48 = 0;
+ OSTime diff = 0;
+ OSTime unused1 = 0;
+ OSTime temp = 0;
+ u32 temp0 = 0;
+ u32 temp1 = 0;
+ u32 done = 0;
+ u32 walking = 0;
+ u32 unused2 = 0;
+ u32 initCnt = 0;
+
+ walking = 0;
+ initCnt = 0;
+ temp = 0;
+
+ while (!done) {
+ __AIRegs[0] = (__AIRegs[0] & ~0x20) | 0x20;
+ __AIRegs[0] &= ~2;
+ __AIRegs[0] = (__AIRegs[0] & ~1) | 1;
+
+ temp0 = __AIRegs[2];
+
+ while (temp0 == __AIRegs[2])
+ ;
+ rise32 = OSGetTime();
+
+ __AIRegs[0] = (__AIRegs[0] & ~2) | 2;
+ __AIRegs[0] = (__AIRegs[0] & ~1) | 1;
+
+ temp1 = __AIRegs[2];
+ while (temp1 == __AIRegs[2])
+ ;
+
+ rise48 = OSGetTime();
+
+ diff = rise48 - rise32;
+ __AIRegs[0] &= ~2;
+ __AIRegs[0] &= ~1;
+
+ if (diff < (bound_32KHz - buffer)) {
+ temp = min_wait;
+ done = 1;
+ ++initCnt;
+ } else if (diff >= (bound_32KHz + buffer) && diff < (bound_48KHz - buffer)) {
+ temp = max_wait;
+ done = 1;
+ ++initCnt;
+ } else {
+ done = 0;
+ walking = 1;
+ ++initCnt;
+ }
+ }
+
+ while ((rise48 + temp) > OSGetTime())
+ ;
+}
diff --git a/src/Dolphin/ar/ar.c b/src/Dolphin/ar/ar.c
new file mode 100644
index 0000000..1d59b30
--- /dev/null
+++ b/src/Dolphin/ar/ar.c
@@ -0,0 +1,518 @@
+#include "dolphin/ar.h"
+
+#include "dolphin/dsp_regs.h"
+#include "dolphin/os.h"
+
+static const char* __ARVersion =
+ "<< Dolphin SDK - AR\trelease build: Sep 5 2002 05:34:27 (0x2301) >>";
+
+static ARCallback __AR_Callback;
+static u32 __AR_Size;
+static u32 __AR_InternalSize;
+static u32 __AR_ExpansionSize;
+
+static u32 __AR_StackPointer;
+static u32 __AR_FreeBlocks;
+static u32* __AR_BlockLength;
+
+static volatile BOOL __AR_init_flag = FALSE;
+
+static void __ARHandler(__OSInterrupt interrupt, OSContext* context);
+static void __ARChecksize(void);
+static void __ARClearArea(u32 start_addr, u32 length);
+
+#ifdef FULL_FRANK
+ARCallback ARRegisterDMACallback(ARCallback callback) {
+ ARCallback oldCb;
+ BOOL enabled;
+ oldCb = __AR_Callback;
+ enabled = OSDisableInterrupts();
+ __AR_Callback = callback;
+ OSRestoreInterrupts(enabled);
+ return oldCb;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm ARCallback ARRegisterDMACallback(ARCallback callback) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ lwz r31, __AR_Callback
+ bl OSDisableInterrupts
+ stw r30, __AR_Callback
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+
+#pragma pop
+/* clang-format on */
+#endif
+#ifdef FULL_FRANK
+u32 ARGetDMAStatus() {
+ BOOL enabled;
+ u32 val;
+ enabled = OSDisableInterrupts();
+ val = __DSPRegs[5] & 0x0200;
+ OSRestoreInterrupts(enabled);
+ return val;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm u32 ARGetDMAStatus() {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x10(r1)
+ stw r31, 0xc(r1)
+ bl OSDisableInterrupts
+ lis r4, __DSPRegs + (5 * 2)@ha
+ lhz r0, __DSPRegs + (5 * 2)@l(r4)
+ rlwinm r31, r0, 0, 0x16, 0x16
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x14(r1)
+ lwz r31, 0xc(r1)
+ addi r1, r1, 0x10
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+void ARStartDMA(u32 type, u32 mainmem_addr, u32 aram_addr, u32 length) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+
+ __DSPRegs[16] = (u16)(__DSPRegs[16] & ~0x3ff) | (u16)(mainmem_addr >> 16);
+ __DSPRegs[17] = (u16)(__DSPRegs[17] & ~0xffe0) | (u16)(mainmem_addr & 0xffff);
+ __DSPRegs[18] = (u16)(__DSPRegs[18] & ~0x3ff) | (u16)(aram_addr >> 16);
+ __DSPRegs[19] = (u16)(__DSPRegs[19] & ~0xffe0) | (u16)(aram_addr & 0xffff);
+ __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x8000) | (type << 15));
+ __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x3ff) | (u16)(length >> 16);
+ __DSPRegs[21] = (u16)(__DSPRegs[21] & ~0xffe0) | (u16)(length & 0xffff);
+ OSRestoreInterrupts(enabled);
+}
+
+#ifdef FULL_FRANK
+u32 ARAlloc(u32 length) {
+ u32 tmp;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ tmp = __AR_StackPointer;
+ __AR_StackPointer += length;
+ *__AR_BlockLength = length;
+ __AR_BlockLength++;
+ __AR_FreeBlocks--;
+ OSRestoreInterrupts(enabled);
+
+ return tmp;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm u32 ARAlloc(u32 length) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ bl OSDisableInterrupts
+ lwz r31, __AR_StackPointer
+ lwz r4, __AR_BlockLength
+ add r0, r31, r30
+ stw r0, __AR_StackPointer
+ stw r30, 0(r4)
+ lwz r5, __AR_BlockLength
+ lwz r4, __AR_FreeBlocks
+ addi r5, r5, 4
+ addi r0, r4, -1
+ stw r5, __AR_BlockLength
+ stw r0, __AR_FreeBlocks
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+#if NONMATCHING
+u32 ARFree(u32* length) {
+ BOOL old;
+
+ old = OSDisableInterrupts();
+
+ __AR_BlockLength--;
+
+ if (length) {
+ *length = *__AR_BlockLength;
+ }
+
+ __AR_StackPointer -= *__AR_BlockLength;
+
+ __AR_FreeBlocks++;
+
+ OSRestoreInterrupts(old);
+
+ return __AR_StackPointer;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm u32 ARFree(u32* length) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ mr r31, r3
+ bl OSDisableInterrupts
+ lwz r4, __AR_BlockLength
+ cmplwi r31, 0
+ addi r0, r4, -4
+ stw r0, __AR_BlockLength
+ beq lbl_8036DAB4
+ lwz r4, __AR_BlockLength
+ lwz r0, 0(r4)
+ stw r0, 0(r31)
+lbl_8036DAB4:
+ lwz r5, __AR_BlockLength
+ lwz r4, __AR_FreeBlocks
+ lwz r6, 0(r5)
+ addi r0, r4, 1
+ lwz r5, __AR_StackPointer
+ stw r0, __AR_FreeBlocks
+ subf r0, r6, r5
+ stw r0, __AR_StackPointer
+ bl OSRestoreInterrupts
+ lwz r3, __AR_StackPointer
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+BOOL ARCheckInit() { return __AR_init_flag; }
+
+u32 ARInit(u32* stack_index_addr, u32 num_entries) {
+
+ BOOL old;
+ u16 refresh;
+
+ if (__AR_init_flag == TRUE) {
+ return 0x4000;
+ }
+
+ OSRegisterVersion(__ARVersion);
+
+ old = OSDisableInterrupts();
+
+ __AR_Callback = NULL;
+
+ __OSSetInterruptHandler(__OS_INTERRUPT_DSP_ARAM, __ARHandler);
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_ARAM);
+
+ __AR_StackPointer = 0x4000;
+ __AR_FreeBlocks = num_entries;
+ __AR_BlockLength = stack_index_addr;
+
+ refresh = (u16)(__DSPRegs[13] & 0x000000ff);
+
+ __DSPRegs[13] = (u16)((__DSPRegs[13] & ~0x000000ff) | (refresh & 0x000000ff));
+
+ __ARChecksize();
+
+ __AR_init_flag = TRUE;
+
+ OSRestoreInterrupts(old);
+
+ return __AR_StackPointer;
+}
+
+u32 ARGetBaseAddress(void) { return 0x4000; }
+
+u32 ARGetSize() { return __AR_Size; }
+
+static void __ARHandler(__OSInterrupt interrupt, OSContext* context) {
+
+ OSContext exceptionContext;
+ u16 tmp;
+
+ tmp = __DSPRegs[5];
+ tmp = (u16)((tmp & ~0x00000088) | 0x20);
+ __DSPRegs[5] = tmp;
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(&exceptionContext);
+
+ if (__AR_Callback) {
+ (*__AR_Callback)();
+ }
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(context);
+}
+
+#define RoundUP32(x) (((u32)(x) + 32 - 1) & ~(32 - 1))
+
+void __ARClearInterrupt(void) {
+
+ u16 tmp;
+ tmp = __DSPRegs[5];
+ tmp = (u16)((tmp & ~(0x00000080 | 0x00000008)) | 0x00000020);
+ __DSPRegs[5] = tmp;
+}
+u16 __ARGetInterruptStatus(void) { return ((u16)(__DSPRegs[5] & 0x0200)); }
+
+static void __ARWaitForDMA(void) {
+
+ while (__DSPRegs[5] & 0x0200) {
+ }
+}
+
+static void __ARWriteDMA(u32 mmem_addr, u32 aram_addr, u32 length) {
+
+ __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16));
+ __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff));
+
+ __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16));
+ __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff));
+
+ __DSPRegs[20] = (u16)(__DSPRegs[20] & ~0x8000);
+
+ __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16));
+ __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff));
+
+ __ARWaitForDMA();
+
+ __ARClearInterrupt();
+}
+
+static void __ARReadDMA(u32 mmem_addr, u32 aram_addr, u32 length) {
+
+ __DSPRegs[16] = (u16)((__DSPRegs[16] & ~0x03ff) | (u16)(mmem_addr >> 16));
+ __DSPRegs[16 + 1] = (u16)((__DSPRegs[16 + 1] & ~0xffe0) | (u16)(mmem_addr & 0xffff));
+
+ __DSPRegs[18] = (u16)((__DSPRegs[18] & ~0x03ff) | (u16)(aram_addr >> 16));
+ __DSPRegs[18 + 1] = (u16)((__DSPRegs[18 + 1] & ~0xffe0) | (u16)(aram_addr & 0xffff));
+
+ __DSPRegs[20] = (u16)(__DSPRegs[20] | 0x8000);
+
+ __DSPRegs[20] = (u16)((__DSPRegs[20] & ~0x03ff) | (u16)(length >> 16));
+ __DSPRegs[20 + 1] = (u16)((__DSPRegs[20 + 1] & ~0xffe0) | (u16)(length & 0xffff));
+
+ __ARWaitForDMA();
+
+ __ARClearInterrupt();
+}
+
+static void __ARChecksize(void) {
+
+ u8 test_data_pad[0x20 + 31];
+ u8 dummy_data_pad[0x20 + 31];
+ u8 buffer_pad[0x20 + 31];
+
+ u8 save_pad_1[0x20 + 31];
+ u8 save_pad_2[0x20 + 31];
+ u8 save_pad_3[0x20 + 31];
+ u8 save_pad_4[0x20 + 31];
+ u8 save_pad_5[0x20 + 31];
+
+ u32* test_data;
+ u32* dummy_data;
+ u32* buffer;
+ u32* save1;
+ u32* save2;
+ u32* save3;
+ u32* save4;
+ u32* save5;
+
+ u16 ARAM_mode = 0;
+ u32 ARAM_size = 0;
+
+ u32 i;
+
+ while (!(__DSPRegs[11] & 1))
+ ;
+
+ ARAM_mode = 3;
+ ARAM_size = __AR_InternalSize = 0x1000000;
+ __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x00000007 | 0x00000038)) | 0x20 | 2 | 1);
+
+ test_data = (u32*)(RoundUP32((u32)(test_data_pad)));
+ dummy_data = (u32*)(RoundUP32((u32)(dummy_data_pad)));
+ buffer = (u32*)(RoundUP32((u32)(buffer_pad)));
+
+ save1 = (u32*)(RoundUP32((u32)(save_pad_1)));
+ save2 = (u32*)(RoundUP32((u32)(save_pad_2)));
+ save3 = (u32*)(RoundUP32((u32)(save_pad_3)));
+ save4 = (u32*)(RoundUP32((u32)(save_pad_4)));
+ save5 = (u32*)(RoundUP32((u32)(save_pad_5)));
+
+ for (i = 0; i < 8; i++) {
+ *(test_data + i) = 0xdeadbeef;
+ *(dummy_data + i) = 0xbad0bad0;
+ }
+
+ DCFlushRange((void*)test_data, 0x20);
+ DCFlushRange((void*)dummy_data, 0x20);
+
+ __AR_ExpansionSize = 0;
+
+ DCInvalidateRange((void*)save1, 0x20);
+ __ARReadDMA((u32)save1, ARAM_size + 0, 0x20);
+ PPCSync();
+
+ __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
+
+ memset((void*)buffer, 0, 0x20);
+ DCFlushRange((void*)buffer, 0x20);
+
+ __ARReadDMA((u32)buffer, ARAM_size + 0x0000000, 0x20);
+ PPCSync();
+
+ if (buffer[0] == test_data[0]) {
+
+ DCInvalidateRange((void*)save2, 0x20);
+ __ARReadDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
+ PPCSync();
+
+ DCInvalidateRange((void*)save3, 0x20);
+ __ARReadDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
+ PPCSync();
+
+ DCInvalidateRange((void*)save4, 0x20);
+ __ARReadDMA((u32)save4, ARAM_size + 0x0000200, 0x20);
+ PPCSync();
+
+ DCInvalidateRange((void*)save5, 0x20);
+ __ARReadDMA((u32)save5, ARAM_size + 0x0400000, 0x20);
+ PPCSync();
+
+ __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0200000, 0x20);
+
+ __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
+
+ memset((void*)buffer, 0, 0x20);
+ DCFlushRange((void*)buffer, 0x20);
+
+ __ARReadDMA((u32)buffer, ARAM_size + 0x0200000, 0x20);
+ PPCSync();
+
+ if (buffer[0] == test_data[0]) {
+ __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
+
+ ARAM_mode |= 0 << 1;
+ ARAM_size += 0x0200000;
+ __AR_ExpansionSize = 0x0200000;
+ } else {
+ __ARWriteDMA((u32)dummy_data, ARAM_size + 0x1000000, 0x20);
+
+ __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
+
+ memset((void*)buffer, 0, 0x20);
+ DCFlushRange((void*)buffer, 0x20);
+
+ __ARReadDMA((u32)buffer, ARAM_size + 0x1000000, 0x20);
+ PPCSync();
+
+ if (buffer[0] == test_data[0]) {
+ __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
+ __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
+
+ ARAM_mode |= 4 << 1;
+ ARAM_size += 0x0400000;
+ __AR_ExpansionSize = 0x0400000;
+ } else {
+ __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0000200, 0x20);
+
+ __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
+
+ memset((void*)buffer, 0, 0x20);
+ DCFlushRange((void*)buffer, 0x20);
+
+ __ARReadDMA((u32)buffer, ARAM_size + 0x0000200, 0x20);
+ PPCSync();
+
+ if (buffer[0] == test_data[0]) {
+ __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
+ __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
+ __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
+
+ ARAM_mode |= 8 << 1;
+ ARAM_size += 0x0800000;
+ __AR_ExpansionSize = 0x0800000;
+ } else {
+ __ARWriteDMA((u32)dummy_data, ARAM_size + 0x0400000, 0x20);
+
+ __ARWriteDMA((u32)test_data, ARAM_size + 0x0000000, 0x20);
+
+ memset((void*)buffer, 0, 0x20);
+ DCFlushRange((void*)buffer, 0x20);
+
+ __ARReadDMA((u32)buffer, ARAM_size + 0x0400000, 0x20);
+ PPCSync();
+
+ if (buffer[0] == test_data[0]) {
+ __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
+ __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
+ __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
+ __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20);
+
+ ARAM_mode |= 12 << 1;
+ ARAM_size += 0x1000000;
+ __AR_ExpansionSize = 0x1000000;
+ } else {
+ __ARWriteDMA((u32)save1, ARAM_size + 0x0000000, 0x20);
+ __ARWriteDMA((u32)save2, ARAM_size + 0x0200000, 0x20);
+ __ARWriteDMA((u32)save3, ARAM_size + 0x1000000, 0x20);
+ __ARWriteDMA((u32)save4, ARAM_size + 0x0000200, 0x20);
+ __ARWriteDMA((u32)save5, ARAM_size + 0x0400000, 0x20);
+
+ ARAM_mode |= 16 << 1;
+ ARAM_size += 0x2000000;
+ __AR_ExpansionSize = 0x2000000;
+ }
+ }
+ }
+ }
+ __DSPRegs[9] = (u16)((__DSPRegs[9] & ~(0x07 | 0x38)) | ARAM_mode);
+ }
+
+ *(u32*)OSPhysicalToUncached(0x00D0) = ARAM_size;
+
+ __AR_Size = ARAM_size;
+}
diff --git a/src/Dolphin/ar/arq.c b/src/Dolphin/ar/arq.c
new file mode 100644
index 0000000..d157463
--- /dev/null
+++ b/src/Dolphin/ar/arq.c
@@ -0,0 +1,170 @@
+#include "dolphin/arq.h"
+#include "dolphin/os.h"
+
+const char* __ARQVersion = "<< Dolphin SDK - ARQ\trelease build: Sep 5 2002 05:34:29 (0x2301) >>";
+static ARQRequest* __ARQRequestQueueHi;
+static ARQRequest* __ARQRequestTailHi;
+static ARQRequest* __ARQRequestQueueLo;
+static ARQRequest* __ARQRequestTailLo;
+static ARQRequest* __ARQRequestPendingHi;
+static ARQRequest* __ARQRequestPendingLo;
+static ARQCallback __ARQCallbackHi;
+static ARQCallback __ARQCallbackLo;
+static u32 __ARQChunkSize;
+
+static volatile BOOL __ARQ_init_flag = FALSE;
+
+void __ARQPopTaskQueueHi(void);
+void __ARQServiceQueueLo(void);
+void __ARQCallbackHack(void);
+void __ARQInterruptServiceRoutine(void);
+void __ARQInitTempQueue(void);
+void __ARQPushTempQueue(ARQRequest* task);
+
+void __ARQPopTaskQueueHi(void) {
+
+ if (__ARQRequestQueueHi) {
+ if (__ARQRequestQueueHi->type == ARQ_TYPE_MRAM_TO_ARAM) {
+ ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->source, __ARQRequestQueueHi->dest,
+ __ARQRequestQueueHi->length);
+ } else {
+ ARStartDMA(__ARQRequestQueueHi->type, __ARQRequestQueueHi->dest, __ARQRequestQueueHi->source,
+ __ARQRequestQueueHi->length);
+ }
+
+ __ARQCallbackHi = __ARQRequestQueueHi->callback;
+
+ __ARQRequestPendingHi = __ARQRequestQueueHi;
+
+ __ARQRequestQueueHi = __ARQRequestQueueHi->next;
+ }
+}
+
+void __ARQServiceQueueLo(void) {
+
+ if ((__ARQRequestPendingLo == NULL) && (__ARQRequestQueueLo)) {
+ __ARQRequestPendingLo = __ARQRequestQueueLo;
+
+ __ARQRequestQueueLo = __ARQRequestQueueLo->next;
+ }
+
+ if (__ARQRequestPendingLo) {
+ if (__ARQRequestPendingLo->length <= __ARQChunkSize) {
+ if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM)
+ ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source,
+ __ARQRequestPendingLo->dest, __ARQRequestPendingLo->length);
+ else
+ ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest,
+ __ARQRequestPendingLo->source, __ARQRequestPendingLo->length);
+
+ __ARQCallbackLo = __ARQRequestPendingLo->callback;
+ } else {
+ if (__ARQRequestPendingLo->type == ARQ_TYPE_MRAM_TO_ARAM)
+ ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->source,
+ __ARQRequestPendingLo->dest, __ARQChunkSize);
+ else
+ ARStartDMA(__ARQRequestPendingLo->type, __ARQRequestPendingLo->dest,
+ __ARQRequestPendingLo->source, __ARQChunkSize);
+ }
+
+ __ARQRequestPendingLo->length -= __ARQChunkSize;
+ __ARQRequestPendingLo->source += __ARQChunkSize;
+ __ARQRequestPendingLo->dest += __ARQChunkSize;
+ }
+}
+void __ARQCallbackHack(void) { return; }
+
+void __ARQInterruptServiceRoutine(void) {
+
+ if (__ARQCallbackHi) {
+ (*__ARQCallbackHi)((u32)__ARQRequestPendingHi);
+ __ARQRequestPendingHi = NULL;
+ __ARQCallbackHi = NULL;
+ }
+
+ else if (__ARQCallbackLo) {
+ (*__ARQCallbackLo)((u32)__ARQRequestPendingLo);
+ __ARQRequestPendingLo = NULL;
+ __ARQCallbackLo = NULL;
+ }
+
+ __ARQPopTaskQueueHi();
+
+ if (__ARQRequestPendingHi == NULL)
+ __ARQServiceQueueLo();
+}
+
+void ARQInit(void) {
+
+ if (TRUE == __ARQ_init_flag) {
+ return;
+ }
+
+ OSRegisterVersion(__ARQVersion);
+ __ARQRequestQueueHi = __ARQRequestQueueLo = NULL;
+ __ARQChunkSize = ARQ_CHUNK_SIZE_DEFAULT;
+ ARRegisterDMACallback(&__ARQInterruptServiceRoutine);
+ __ARQRequestPendingHi = NULL;
+ __ARQRequestPendingLo = NULL;
+ __ARQCallbackHi = NULL;
+ __ARQCallbackLo = NULL;
+ __ARQ_init_flag = TRUE;
+}
+
+void ARQPostRequest(ARQRequest* request, u32 owner, u32 type, u32 priority, u32 source, u32 dest,
+ u32 length, ARQCallback callback) {
+
+ BOOL enabled;
+
+ request->next = NULL;
+ request->owner = owner;
+ request->type = type;
+ request->source = source;
+ request->dest = dest;
+ request->length = length;
+
+ if (callback) {
+ request->callback = callback;
+ } else {
+ request->callback = (ARQCallback)&__ARQCallbackHack;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ switch (priority) {
+ case ARQ_PRIORITY_LOW:
+
+ if (__ARQRequestQueueLo) {
+ __ARQRequestTailLo->next = request;
+ } else {
+ __ARQRequestQueueLo = request;
+ }
+ __ARQRequestTailLo = request;
+
+ break;
+
+ case ARQ_PRIORITY_HIGH:
+
+ if (__ARQRequestQueueHi) {
+ __ARQRequestTailHi->next = request;
+ } else {
+ __ARQRequestQueueHi = request;
+ }
+
+ __ARQRequestTailHi = request;
+
+ break;
+ }
+
+ if ((__ARQRequestPendingHi == NULL) && (__ARQRequestPendingLo == NULL)) {
+ __ARQPopTaskQueueHi();
+
+ if (__ARQRequestPendingHi == NULL) {
+ __ARQServiceQueueLo();
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+}
+
+u32 ARQGetChunkSize(void) { return __ARQChunkSize; }
diff --git a/src/Dolphin/card/CARDBios.c b/src/Dolphin/card/CARDBios.c
new file mode 100644
index 0000000..0a1fb45
--- /dev/null
+++ b/src/Dolphin/card/CARDBios.c
@@ -0,0 +1,775 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+const char* __CARDVersion =
+ "<< Dolphin SDK - CARD\trelease build: Sep 5 2002 05:35:20 (0x2301) >>";
+
+CARDControl __CARDBlock[2];
+DVDDiskID __CARDDiskNone;
+
+static u16 __CARDEncode;
+
+s32 __CARDReadStatus(s32 chan, u8* status);
+s32 __CARDClearStatus(s32 chan);
+void __CARDSetDiskID(const DVDDiskID* id);
+static s32 Retry(s32 chan);
+
+BOOL OnReset(BOOL f);
+static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127};
+
+void __CARDDefaultApiCallback(s32 chan, s32 result) {}
+
+void __CARDExtHandler(s32 chan, OSContext* context) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ if (card->attached) {
+ card->attached = FALSE;
+ EXISetExiCallback(chan, 0);
+ OSCancelAlarm(&card->alarm);
+ callback = card->exiCallback;
+
+ if (callback) {
+ card->exiCallback = 0;
+ callback(chan, CARD_RESULT_NOCARD);
+ }
+
+ if (card->result != CARD_RESULT_BUSY) {
+ card->result = CARD_RESULT_NOCARD;
+ }
+
+ callback = card->extCallback;
+ if (callback && CARD_MAX_MOUNT_STEP <= card->mountStep) {
+ card->extCallback = 0;
+ callback(chan, CARD_RESULT_NOCARD);
+ }
+ }
+}
+
+void __CARDExiHandler(s32 chan, OSContext* context) {
+ CARDControl* card;
+ CARDCallback callback;
+ u8 status;
+ s32 result;
+
+ card = &__CARDBlock[chan];
+
+ OSCancelAlarm(&card->alarm);
+
+ if (!card->attached) {
+ return;
+ }
+
+ if (!EXILock(chan, 0, 0)) {
+ result = CARD_RESULT_FATAL_ERROR;
+ goto fatal;
+ }
+
+ if ((result = __CARDReadStatus(chan, &status)) < 0 || (result = __CARDClearStatus(chan)) < 0) {
+ goto error;
+ }
+
+ if ((result = (status & 0x18) ? CARD_RESULT_IOERROR : CARD_RESULT_READY) == CARD_RESULT_IOERROR &&
+ --card->retry > 0) {
+ result = Retry(chan);
+ if (result >= 0) {
+ return;
+ }
+ goto fatal;
+ }
+
+error:
+ EXIUnlock(chan);
+
+fatal:
+ callback = card->exiCallback;
+ if (callback) {
+ card->exiCallback = 0;
+ callback(chan, result);
+ }
+}
+
+void __CARDTxHandler(s32 chan, OSContext* context) {
+ CARDControl* card;
+ CARDCallback callback;
+ BOOL err;
+
+ card = &__CARDBlock[chan];
+ err = !EXIDeselect(chan);
+ EXIUnlock(chan);
+ callback = card->txCallback;
+ if (callback) {
+ card->txCallback = 0;
+ callback(chan, (!err && EXIProbe(chan)) ? CARD_RESULT_READY : CARD_RESULT_NOCARD);
+ }
+}
+
+void __CARDUnlockedHandler(s32 chan, OSContext* context) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ callback = card->unlockCallback;
+ if (callback) {
+ card->unlockCallback = 0;
+ callback(chan, EXIProbe(chan) ? CARD_RESULT_UNLOCKED : CARD_RESULT_NOCARD);
+ }
+}
+
+s32 __CARDEnableInterrupt(s32 chan, BOOL enable) {
+ BOOL err;
+ u32 cmd;
+
+ if (!EXISelect(chan, 0, 4)) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ cmd = enable ? 0x81010000 : 0x81000000;
+ err = FALSE;
+ err |= !EXIImm(chan, &cmd, 2, 1, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIDeselect(chan);
+ return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
+}
+
+s32 __CARDReadStatus(s32 chan, u8* status) {
+ BOOL err;
+ u32 cmd;
+
+ if (!EXISelect(chan, 0, 4)) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ cmd = 0x83000000;
+ err = FALSE;
+ err |= !EXIImm(chan, &cmd, 2, 1, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIImm(chan, status, 1, 0, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIDeselect(chan);
+ return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
+}
+
+s32 __CARDClearStatus(s32 chan) {
+ BOOL err;
+ u32 cmd;
+
+ if (!EXISelect(chan, 0, 4)) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ cmd = 0x89000000;
+ err = FALSE;
+ err |= !EXIImm(chan, &cmd, 1, 1, 0);
+ err |= !EXISync(chan);
+ err |= !EXIDeselect(chan);
+
+ return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
+}
+
+static void TimeoutHandler(OSAlarm* alarm, OSContext* context) {
+ s32 chan;
+ CARDControl* card;
+ CARDCallback callback;
+ for (chan = 0; chan < 2; ++chan) {
+ card = &__CARDBlock[chan];
+ if (alarm == &card->alarm) {
+ break;
+ }
+ }
+
+ if (!card->attached) {
+ return;
+ }
+
+ EXISetExiCallback(chan, NULL);
+ callback = card->exiCallback;
+ if (callback) {
+ card->exiCallback = 0;
+ callback(chan, CARD_RESULT_IOERROR);
+ }
+}
+
+static void SetupTimeoutAlarm(CARDControl* card) {
+ OSCancelAlarm(&card->alarm);
+ switch (card->cmd[0]) {
+ case 0xF2:
+ OSSetAlarm(&card->alarm, OSMillisecondsToTicks(100), TimeoutHandler);
+ break;
+ case 0xF3:
+ break;
+ case 0xF4:
+ case 0xF1:
+ OSSetAlarm(&card->alarm, OSSecondsToTicks((OSTime)2) * (card->sectorSize / 0x2000),
+ TimeoutHandler);
+ break;
+ }
+}
+
+static s32 Retry(s32 chan) {
+ CARDControl* card;
+ card = &__CARDBlock[chan];
+
+ if (!EXISelect(chan, 0, 4)) {
+ EXIUnlock(chan);
+ return CARD_RESULT_NOCARD;
+ }
+
+ SetupTimeoutAlarm(card);
+
+ if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) {
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ return CARD_RESULT_NOCARD;
+ }
+
+ if (card->cmd[0] == 0x52 &&
+ !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency, 1)) {
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ return CARD_RESULT_NOCARD;
+ }
+
+ if (card->mode == 0xffffffff) {
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ return CARD_RESULT_READY;
+ }
+
+ if (!EXIDma(chan, card->buffer, (s32)((card->cmd[0] == 0x52) ? 512 : 128), card->mode,
+ __CARDTxHandler)) {
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ return CARD_RESULT_NOCARD;
+ }
+
+ return CARD_RESULT_READY;
+}
+
+static void UnlockedCallback(s32 chan, s32 result) {
+ CARDCallback callback;
+ CARDControl* card;
+
+ card = &__CARDBlock[chan];
+ if (result >= 0) {
+ card->unlockCallback = UnlockedCallback;
+ if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
+ result = CARD_RESULT_READY;
+ } else {
+ card->unlockCallback = 0;
+ result = Retry(chan);
+ }
+ }
+
+ if (result < 0) {
+ switch (card->cmd[0]) {
+ case 0x52:
+ callback = card->txCallback;
+ if (callback) {
+ card->txCallback = 0;
+ callback(chan, result);
+ }
+
+ break;
+ case 0xF2:
+ case 0xF4:
+ case 0xF1:
+ callback = card->exiCallback;
+ if (callback) {
+ card->exiCallback = 0;
+ callback(chan, result);
+ }
+ break;
+ }
+ }
+}
+
+static s32 __CARDStart(s32 chan, CARDCallback txCallback, CARDCallback exiCallback) {
+ BOOL enabled;
+ CARDControl* card;
+ s32 result;
+
+ enabled = OSDisableInterrupts();
+
+ card = &__CARDBlock[chan];
+ if (!card->attached) {
+ result = CARD_RESULT_NOCARD;
+ } else {
+
+ if (txCallback) {
+ card->txCallback = txCallback;
+ }
+ if (exiCallback) {
+ card->exiCallback = exiCallback;
+ }
+ card->unlockCallback = UnlockedCallback;
+ if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
+ result = CARD_RESULT_BUSY;
+ } else {
+ card->unlockCallback = 0;
+
+ if (!EXISelect(chan, 0, 4)) {
+ EXIUnlock(chan);
+ result = CARD_RESULT_NOCARD;
+ } else {
+ SetupTimeoutAlarm(card);
+ result = CARD_RESULT_READY;
+ }
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+ return result;
+}
+
+#define AD1(x) ((u8)(((x) >> 17) & 0x7f))
+#define AD1EX(x) ((u8)(AD1(x) | 0x80));
+#define AD2(x) ((u8)(((x) >> 9) & 0xff))
+#define AD3(x) ((u8)(((x) >> 7) & 0x03))
+#define BA(x) ((u8)((x)&0x7f))
+
+s32 __CARDReadSegment(s32 chan, CARDCallback callback) {
+ CARDControl* card;
+ s32 result;
+
+ card = &__CARDBlock[chan];
+ card->cmd[0] = 0x52;
+ card->cmd[1] = AD1(card->addr);
+ card->cmd[2] = AD2(card->addr);
+ card->cmd[3] = AD3(card->addr);
+ card->cmd[4] = BA(card->addr);
+ card->cmdlen = 5;
+ card->mode = 0;
+ card->retry = 0;
+
+ result = __CARDStart(chan, callback, 0);
+ if (result == CARD_RESULT_BUSY) {
+ result = CARD_RESULT_READY;
+ } else if (result >= 0) {
+ if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) ||
+ !EXIImmEx(chan, (u8*)card->workArea + sizeof(CARDID), card->latency,
+ 1) || // XXX use DMA if possible
+ !EXIDma(chan, card->buffer, 512, card->mode, __CARDTxHandler)) {
+ card->txCallback = 0;
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ result = CARD_RESULT_NOCARD;
+ } else {
+ result = CARD_RESULT_READY;
+ }
+ }
+ return result;
+}
+
+s32 __CARDWritePage(s32 chan, CARDCallback callback) {
+ CARDControl* card;
+ s32 result;
+
+ card = &__CARDBlock[chan];
+ card->cmd[0] = 0xF2;
+ card->cmd[1] = AD1(card->addr);
+ card->cmd[2] = AD2(card->addr);
+ card->cmd[3] = AD3(card->addr);
+ card->cmd[4] = BA(card->addr);
+ card->cmdlen = 5;
+ card->mode = 1;
+ card->retry = 3;
+
+ result = __CARDStart(chan, 0, callback);
+ if (result == CARD_RESULT_BUSY) {
+ result = CARD_RESULT_READY;
+ } else if (result >= 0) {
+ if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1) ||
+ !EXIDma(chan, card->buffer, 128, card->mode, __CARDTxHandler)) {
+ card->exiCallback = 0;
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ result = CARD_RESULT_NOCARD;
+ } else {
+ result = CARD_RESULT_READY;
+ }
+ }
+ return result;
+}
+
+#ifdef FULL_FRANK
+/* TODO: Needs frank fix for disconnected stack epilogue */
+s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) {
+ CARDControl* card;
+ s32 result;
+
+ card = &__CARDBlock[chan];
+ card->cmd[0] = 0xF1;
+ card->cmd[1] = AD1(addr);
+ card->cmd[2] = AD2(addr);
+ card->cmdlen = 3;
+ card->mode = -1;
+ card->retry = 3;
+
+ result = __CARDStart(chan, 0, callback);
+
+ if (result == CARD_RESULT_BUSY) {
+ result = CARD_RESULT_READY;
+ } else if (result >= 0) {
+ if (!EXIImmEx(chan, card->cmd, card->cmdlen, 1)) {
+ card->exiCallback = NULL;
+ result = CARD_RESULT_NOCARD;
+ } else {
+ result = CARD_RESULT_READY;
+ }
+
+ EXIDeselect(chan);
+ EXIUnlock(chan);
+ }
+ return result;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm s32 __CARDEraseSector(s32 chan, u32 addr, CARDCallback callback) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x28(r1)
+ stw r31, 0x24(r1)
+ stw r30, 0x20(r1)
+ stw r29, 0x1c(r1)
+ addi r29, r3, 0
+ mulli r6, r29, 0x110
+ lis r3, __CARDBlock@ha
+ addi r0, r3, __CARDBlock@l
+ add r31, r0, r6
+ li r0, 0xf1
+ stb r0, 0x94(r31)
+ rlwinm r3, r4, 0xf, 0x19, 0x1f
+ rlwinm r0, r4, 0x17, 0x18, 0x1f
+ stb r3, 0x95(r31)
+ li r6, 3
+ addi r3, r29, 0
+ stb r0, 0x96(r31)
+ li r0, -1
+ li r4, 0
+ stw r6, 0xa0(r31)
+ stw r0, 0xa4(r31)
+ stw r6, 0xa8(r31)
+ bl __CARDStart
+ addi r30, r3, 0
+ cmpwi r30, -1
+ bne lbl_803B8C4C
+ li r30, 0
+ b lbl_803B8C94
+lbl_803B8C4C:
+ cmpwi r30, 0
+ blt lbl_803B8C94
+ lwz r5, 0xa0(r31)
+ addi r3, r29, 0
+ addi r4, r31, 0x94
+ li r6, 1
+ bl EXIImmEx
+ cmpwi r3, 0
+ bne lbl_803B8C80
+ li r0, 0
+ stw r0, 0xcc(r31)
+ li r30, -3
+ b lbl_803B8C84
+lbl_803B8C80:
+ li r30, 0
+lbl_803B8C84:
+ mr r3, r29
+ bl EXIDeselect
+ mr r3, r29
+ bl EXIUnlock
+lbl_803B8C94:
+ mr r3, r30
+ lwz r0, 0x2c(r1)
+ lwz r31, 0x24(r1)
+ lwz r30, 0x20(r1)
+ lwz r29, 0x1c(r1)
+ addi r1, r1, 0x28
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+void CARDInit(void) {
+ int chan;
+
+ if (__CARDBlock[0].diskID && __CARDBlock[1].diskID) {
+ return;
+ }
+
+ __CARDEncode = OSGetFontEncode();
+
+ OSRegisterVersion(__CARDVersion);
+
+ DSPInit();
+ OSInitAlarm();
+
+ for (chan = 0; chan < 2; ++chan) {
+ CARDControl* card = &__CARDBlock[chan];
+
+ card->result = CARD_RESULT_NOCARD;
+ OSInitThreadQueue(&card->threadQueue);
+ OSCreateAlarm(&card->alarm);
+ }
+ __CARDSetDiskID((DVDDiskID*)OSPhysicalToCached(0x0));
+
+ OSRegisterResetFunction(&ResetFunctionInfo);
+}
+
+u16 __CARDGetFontEncode() { return __CARDEncode; }
+
+void __CARDSetDiskID(const DVDDiskID* id) {
+ __CARDBlock[0].diskID = id ? id : &__CARDDiskNone;
+ __CARDBlock[1].diskID = id ? id : &__CARDDiskNone;
+}
+
+s32 __CARDGetControlBlock(s32 chan, CARDControl** pcard) {
+ BOOL enabled;
+ s32 result;
+ CARDControl* card;
+
+ card = &__CARDBlock[chan];
+ if (chan < 0 || chan >= 2 || card->diskID == NULL) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+
+ enabled = OSDisableInterrupts();
+ if (!card->attached) {
+ result = CARD_RESULT_NOCARD;
+ } else if (card->result == CARD_RESULT_BUSY) {
+ result = CARD_RESULT_BUSY;
+ } else {
+ card->result = CARD_RESULT_BUSY;
+ result = CARD_RESULT_READY;
+ card->apiCallback = 0;
+ *pcard = card;
+ }
+ OSRestoreInterrupts(enabled);
+ return result;
+}
+
+#ifdef FULL_FRANK
+/* TODO: Needs frank fix for disconnected stack epilogue */
+s32 __CARDPutControlBlock(CARDControl* card, s32 result) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if (card->attached) {
+ card->result = result;
+ } else if (card->result == CARD_RESULT_BUSY) {
+ card->result = result;
+ }
+ OSRestoreInterrupts(enabled);
+ return result;
+}
+#else
+#pragma push
+/* clang-format off */
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm s32 __CARDPutControlBlock(CARDControl* card, s32 result) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ addi r31, r4, 0
+ stw r30, 0x10(r1)
+ addi r30, r3, 0
+ bl OSDisableInterrupts
+ lwz r0, 0(r30)
+ cmpwi r0, 0
+ beq lbl_803B8E8C
+ stw r31, 4(r30)
+ b lbl_803B8E9C
+lbl_803B8E8C:
+ lwz r0, 4(r30)
+ cmpwi r0, -1
+ bne lbl_803B8E9C
+ stw r31, 4(r30)
+lbl_803B8E9C:
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+s32 CARDGetResultCode(s32 chan) {
+ CARDControl* card;
+ if (chan < 0 || chan >= 2) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ card = &__CARDBlock[chan];
+ return card->result;
+}
+
+#ifdef FULL_FRANK
+s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) {
+ CARDControl* card;
+ s32 result;
+ u16* fat;
+ CARDDir* dir;
+ CARDDir* ent;
+ u16 fileNo;
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ fat = __CARDGetFatBlock(card);
+ dir = __CARDGetDirBlock(card);
+ if (fat == 0 || dir == 0) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+
+ if (byteNotUsed) {
+ *byteNotUsed = (s32)(card->sectorSize * fat[CARD_FAT_FREEBLOCKS]);
+ }
+
+ if (filesNotUsed) {
+ *filesNotUsed = 0;
+ for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
+ ent = &dir[fileNo];
+ if (ent->fileName[0] == 0xff) {
+ ++*filesNotUsed;
+ }
+ }
+ }
+
+ return __CARDPutControlBlock(card, CARD_RESULT_READY);
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm s32 CARDFreeBlocks(s32 chan, s32* byteNotUsed, s32* filesNotUsed) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x30(r1)
+ stw r31, 0x2c(r1)
+ addi r31, r5, 0
+ stw r30, 0x28(r1)
+ stw r29, 0x24(r1)
+ addi r29, r4, 0
+ addi r4, r1, 0x18
+ bl __CARDGetControlBlock
+ cmpwi r3, 0
+ bge lbl_803B8F20
+ b lbl_803B9020
+lbl_803B8F20:
+ lwz r3, 0x18(r1)
+ bl __CARDGetFatBlock
+ mr r30, r3
+ lwz r3, 0x18(r1)
+ bl __CARDGetDirBlock
+ cmplwi r30, 0
+ beq lbl_803B8F44
+ cmplwi r3, 0
+ bne lbl_803B8F84
+lbl_803B8F44:
+ lwz r30, 0x18(r1)
+ bl OSDisableInterrupts
+ lwz r0, 0(r30)
+ cmpwi r0, 0
+ beq lbl_803B8F64
+ li r0, -6
+ stw r0, 4(r30)
+ b lbl_803B8F78
+lbl_803B8F64:
+ lwz r0, 4(r30)
+ cmpwi r0, -1
+ bne lbl_803B8F78
+ li r0, -6
+ stw r0, 4(r30)
+lbl_803B8F78:
+ bl OSRestoreInterrupts
+ li r3, -6
+ b lbl_803B9020
+lbl_803B8F84:
+ cmplwi r29, 0
+ beq lbl_803B8FA0
+ lwz r4, 0x18(r1)
+ lhz r0, 6(r30)
+ lwz r4, 0xc(r4)
+ mullw r0, r4, r0
+ stw r0, 0(r29)
+lbl_803B8FA0:
+ cmplwi r31, 0
+ beq lbl_803B8FE4
+ li r0, 0
+ stw r0, 0(r31)
+ li r5, 0
+ b lbl_803B8FD8
+lbl_803B8FB8:
+ lbz r0, 8(r3)
+ cmplwi r0, 0xff
+ bne lbl_803B8FD0
+ lwz r4, 0(r31)
+ addi r0, r4, 1
+ stw r0, 0(r31)
+lbl_803B8FD0:
+ addi r3, r3, 0x40
+ addi r5, r5, 1
+lbl_803B8FD8:
+ clrlwi r0, r5, 0x10
+ cmplwi r0, 0x7f
+ blt lbl_803B8FB8
+lbl_803B8FE4:
+ lwz r30, 0x18(r1)
+ bl OSDisableInterrupts
+ lwz r0, 0(r30)
+ cmpwi r0, 0
+ beq lbl_803B9004
+ li r0, 0
+ stw r0, 4(r30)
+ b lbl_803B9018
+lbl_803B9004:
+ lwz r0, 4(r30)
+ cmpwi r0, -1
+ bne lbl_803B9018
+ li r0, 0
+ stw r0, 4(r30)
+lbl_803B9018:
+ bl OSRestoreInterrupts
+ li r3, 0
+lbl_803B9020:
+ lwz r0, 0x34(r1)
+ lwz r31, 0x2c(r1)
+ lwz r30, 0x28(r1)
+ lwz r29, 0x24(r1)
+ addi r1, r1, 0x30
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+static BOOL OnReset(BOOL f) {
+ if (!f) {
+ if (CARDUnmount(0) == CARD_RESULT_BUSY || CARDUnmount(1) == CARD_RESULT_BUSY) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/Dolphin/card/CARDBlock.c b/src/Dolphin/card/CARDBlock.c
new file mode 100644
index 0000000..b6305f1
--- /dev/null
+++ b/src/Dolphin/card/CARDBlock.c
@@ -0,0 +1,159 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+u16* __CARDGetFatBlock(CARDControl* card) { return card->currentFat; }
+
+static void WriteCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+ u16* fat;
+ u16* fatBack;
+
+ card = &__CARDBlock[chan];
+
+ if (result >= 0) {
+ fat = (u16*)((u8*)card->workArea + 0x6000);
+ fatBack = (u16*)((u8*)card->workArea + 0x8000);
+
+ if (card->currentFat == fat) {
+ card->currentFat = fatBack;
+ memcpy(fatBack, fat, 0x2000);
+ } else {
+ card->currentFat = fat;
+ memcpy(fat, fatBack, 0x2000);
+ }
+ }
+
+ if (card->apiCallback == NULL) {
+ __CARDPutControlBlock(card, result);
+ }
+
+ callback = card->eraseCallback;
+ if (callback) {
+ card->eraseCallback = NULL;
+ callback(chan, result);
+ }
+}
+
+static void EraseCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+ u32 temp[2]; /* this compiler sucks */
+ u16* fat;
+ u32 addr;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ fat = __CARDGetFatBlock(card);
+ addr = ((u32)fat - (u32)card->workArea) / CARD_SYSTEM_BLOCK_SIZE * card->sectorSize;
+ result = __CARDWrite(chan, addr, CARD_SYSTEM_BLOCK_SIZE, fat, WriteCallback);
+ if (result < 0) {
+ goto error;
+ }
+
+ return;
+
+error:
+ if (card->apiCallback == NULL) {
+ __CARDPutControlBlock(card, result);
+ }
+ callback = card->eraseCallback;
+ if (callback) {
+ card->eraseCallback = NULL;
+ callback(chan, result);
+ }
+}
+
+s32 __CARDAllocBlock(s32 chan, u32 cBlock, CARDCallback callback) {
+ CARDControl* card;
+ u16* fat;
+ u16 iBlock;
+ u16 startBlock;
+ u16 prevBlock;
+ u16 count;
+
+ card = &__CARDBlock[chan];
+ if (!card->attached) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ fat = __CARDGetFatBlock(card);
+ if (fat[3] < cBlock) {
+ return CARD_RESULT_INSSPACE;
+ }
+
+ fat[3] -= cBlock;
+ startBlock = 0xFFFF;
+ iBlock = fat[4];
+ count = 0;
+ while (0 < cBlock) {
+ if (card->cBlock - 5 < ++count) {
+ return CARD_RESULT_BROKEN;
+ }
+
+ iBlock++;
+ if (!CARDIsValidBlockNo(card, iBlock)) {
+ iBlock = 5;
+ }
+
+ if (fat[iBlock] == 0x0000u) {
+ if (startBlock == 0xFFFF) {
+ startBlock = iBlock;
+ } else {
+ fat[prevBlock] = iBlock;
+ }
+ prevBlock = iBlock;
+ fat[iBlock] = 0xFFFF;
+ --cBlock;
+ }
+ }
+ fat[4] = iBlock;
+ card->startBlock = startBlock;
+
+ return __CARDUpdateFatBlock(chan, fat, callback);
+}
+
+s32 __CARDFreeBlock(s32 chan, u16 nBlock, CARDCallback callback) {
+ CARDControl* card;
+ u16* fat;
+ u16 nextBlock;
+
+ card = card = &__CARDBlock[chan];
+ if (!card->attached) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ fat = __CARDGetFatBlock(card);
+ while (nBlock != 0xFFFF) {
+ if (!CARDIsValidBlockNo(card, nBlock)) {
+ return CARD_RESULT_BROKEN;
+ }
+
+ nextBlock = fat[nBlock];
+ fat[nBlock] = 0;
+ nBlock = nextBlock;
+ ++fat[3];
+ }
+
+ return __CARDUpdateFatBlock(chan, fat, callback);
+}
+
+s32 __CARDUpdateFatBlock(s32 chan, u16* fat, CARDCallback callback) {
+ CARDControl* card;
+
+ card = &__CARDBlock[chan];
+ ++fat[2];
+ __CARDCheckSum(fat + 2, 0x1FFC, fat, fat + 1);
+ DCStoreRange(fat, 0x2000);
+ card->eraseCallback = callback;
+
+ return __CARDEraseSector(chan, (((u32)fat - (u32)card->workArea) / 8192u) * card->sectorSize,
+ EraseCallback);
+}
diff --git a/src/Dolphin/card/CARDCheck.c b/src/Dolphin/card/CARDCheck.c
new file mode 100644
index 0000000..2253d55
--- /dev/null
+++ b/src/Dolphin/card/CARDCheck.c
@@ -0,0 +1,688 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+#include <dolphin/OSRtcPriv.h>
+
+#include "string.h"
+
+#define __CARDGetDirCheck(dir) ((CARDDirCheck*)&(dir)[CARD_MAX_FILE])
+
+void __CARDCheckSum(void* ptr, int length, u16* checksum, u16* checksumInv) {
+ u16* p;
+ int i;
+
+ length /= sizeof(u16);
+ *checksum = *checksumInv = 0;
+ for (i = 0, p = ptr; i < length; i++, p++) {
+ *checksum += *p;
+ *checksumInv += ~*p;
+ }
+ if (*checksum == 0xffff) {
+ *checksum = 0;
+ }
+ if (*checksumInv == 0xffff) {
+ *checksumInv = 0;
+ }
+}
+
+static s32 VerifyID(CARDControl* card) {
+ CARDID* id;
+ u16 checksum;
+ u16 checksumInv;
+ OSSramEx* sramEx;
+ OSTime rand;
+ int i;
+
+ id = card->workArea;
+
+ if (id->deviceID != 0 || id->size != card->size) {
+ return CARD_RESULT_BROKEN;
+ }
+
+ __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &checksum, &checksumInv);
+ if (id->checkSum != checksum || id->checkSumInv != checksumInv) {
+ return CARD_RESULT_BROKEN;
+ }
+
+ rand = *(OSTime*)&id->serial[12];
+ sramEx = __OSLockSramEx();
+
+ for (i = 0; i < 12; i++) {
+ rand = (rand * 1103515245 + 12345) >> 16;
+ if (id->serial[i] != (u8)(sramEx->flashID[card - __CARDBlock][i] + rand)) {
+ __OSUnlockSramEx(FALSE);
+ return CARD_RESULT_BROKEN;
+ }
+ rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF;
+ }
+
+ __OSUnlockSramEx(FALSE);
+ if (id->encode != __CARDGetFontEncode()) {
+ return CARD_RESULT_ENCODING;
+ }
+
+ return CARD_RESULT_READY;
+}
+
+#ifdef FULL_FRANK
+static s32 VerifyDir(CARDControl* card, int* outCurrent) {
+ CARDDir* dir[2];
+ CARDDirCheck* check[2];
+ u16 checkSum;
+ u16 checkSumInv;
+ int i;
+ int errors;
+ int current;
+
+ current = errors = 0;
+ for (i = 0; i < 2; i++) {
+ dir[i] = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE);
+ check[i] = __CARDGetDirCheck(dir[i]);
+ __CARDCheckSum(dir[i], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum, &checkSumInv);
+ if (check[i]->checkSum != checkSum || check[i]->checkSumInv != checkSumInv) {
+ ++errors;
+ current = i;
+ card->currentDir = 0;
+ }
+ }
+
+ if (0 == errors) {
+ if (card->currentDir == 0) {
+ if ((check[0]->checkCode - check[1]->checkCode) < 0) {
+ current = 0;
+ } else {
+ current = 1;
+ }
+ card->currentDir = dir[current];
+ memcpy(dir[current], dir[current ^ 1], CARD_SYSTEM_BLOCK_SIZE);
+ } else {
+ current = (card->currentDir == dir[0]) ? 0 : 1;
+ }
+ }
+ if (outCurrent) {
+ *outCurrent = current;
+ }
+ return errors;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+static asm s32 VerifyDir(CARDControl* card, int* outCurrent) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x38(r1)
+ stw r31, 0x34(r1)
+ addi r7, r1, 0x1c
+ addi r8, r1, 0x14
+ stw r30, 0x30(r1)
+ li r31, 0
+ li r30, 0
+ stw r29, 0x2c(r1)
+ addi r29, r4, 0
+ li r4, 0
+lbl_803BB038:
+ addi r0, r4, 1
+ lwz r5, 0x80(r3)
+ slwi r0, r0, 0xd
+ add r0, r5, r0
+ stw r0, 0(r7)
+ li r6, 0x1ffc
+ srawi r6, r6, 1
+ lwz r5, 0(r7)
+ addze. r6, r6
+ li r11, 0
+ addi r0, r5, 0x1fc0
+ stw r0, 0(r8)
+ li r10, 0
+ lwz r5, 0(r7)
+ ble lbl_803BB12C
+ rlwinm. r0, r6, 0x1d, 3, 0x1f
+ mtctr r0
+ beq lbl_803BB110
+lbl_803BB080:
+ lhz r9, 0(r5)
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 2(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 4(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 6(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 8(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 0xa(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 0xc(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 0xe(r5)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ add r11, r11, r0
+ addi r5, r5, 0x10
+ bdnz lbl_803BB080
+ andi. r6, r6, 7
+ beq lbl_803BB12C
+lbl_803BB110:
+ mtctr r6
+lbl_803BB114:
+ lhz r9, 0(r5)
+ addi r5, r5, 2
+ nor r0, r9, r9
+ add r10, r10, r9
+ add r11, r11, r0
+ bdnz lbl_803BB114
+lbl_803BB12C:
+ clrlwi r0, r10, 0x10
+ cmplwi r0, 0xffff
+ bne lbl_803BB13C
+ li r10, 0
+lbl_803BB13C:
+ clrlwi r0, r11, 0x10
+ cmplwi r0, 0xffff
+ bne lbl_803BB14C
+ li r11, 0
+lbl_803BB14C:
+ lwz r6, 0(r8)
+ clrlwi r5, r10, 0x10
+ lhz r0, 0x3c(r6)
+ cmplw r5, r0
+ bne lbl_803BB170
+ lhz r0, 0x3e(r6)
+ clrlwi r5, r11, 0x10
+ cmplw r5, r0
+ beq lbl_803BB180
+lbl_803BB170:
+ li r0, 0
+ stw r0, 0x84(r3)
+ addi r30, r4, 0
+ addi r31, r31, 1
+lbl_803BB180:
+ addi r4, r4, 1
+ cmpwi r4, 2
+ addi r7, r7, 4
+ addi r8, r8, 4
+ blt lbl_803BB038
+ cmpwi r31, 0
+ bne lbl_803BB21C
+ lwz r4, 0x84(r3)
+ cmplwi r4, 0
+ bne lbl_803BB200
+ lwz r5, 0x18(r1)
+ lwz r4, 0x14(r1)
+ lha r5, 0x3a(r5)
+ lha r0, 0x3a(r4)
+ subf. r0, r5, r0
+ bge lbl_803BB1C8
+ li r30, 0
+ b lbl_803BB1CC
+lbl_803BB1C8:
+ li r30, 1
+lbl_803BB1CC:
+ slwi r0, r30, 2
+ addi r6, r1, 0x1c
+ add r6, r6, r0
+ lwz r4, 0(r6)
+ xori r0, r30, 1
+ slwi r0, r0, 2
+ stw r4, 0x84(r3)
+ addi r4, r1, 0x1c
+ li r5, 0x2000
+ lwz r3, 0(r6)
+ lwzx r4, r4, r0
+ bl memcpy
+ b lbl_803BB21C
+lbl_803BB200:
+ lwz r0, 0x1c(r1)
+ cmplw r4, r0
+ bne lbl_803BB214
+ li r0, 0
+ b lbl_803BB218
+lbl_803BB214:
+ li r0, 1
+lbl_803BB218:
+ mr r30, r0
+lbl_803BB21C:
+ cmplwi r29, 0
+ beq lbl_803BB228
+ stw r30, 0(r29)
+lbl_803BB228:
+ mr r3, r31
+ lwz r0, 0x3c(r1)
+ lwz r31, 0x34(r1)
+ lwz r30, 0x30(r1)
+ lwz r29, 0x2c(r1)
+ addi r1, r1, 0x38
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+#ifdef FULL_FRANK
+static s32 VerifyFAT(CARDControl* card, int* outCurrent) {
+ u16* fat[2];
+ u16* fatp;
+ u16 nBlock;
+ u16 cFree;
+ int i;
+ u16 checkSum;
+ u16 checkSumInv;
+ int errors;
+ int current;
+
+ current = errors = 0;
+ for (i = 0; i < 2; i++) {
+ fatp = fat[i] = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE);
+
+ __CARDCheckSum(&fatp[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &checkSum,
+ &checkSumInv);
+ if (fatp[CARD_FAT_CHECKSUM] != checkSum || fatp[CARD_FAT_CHECKSUMINV] != checkSumInv) {
+ ++errors;
+ current = i;
+ card->currentFat = 0;
+ continue;
+ }
+
+ cFree = 0;
+ for (nBlock = CARD_NUM_SYSTEM_BLOCK; nBlock < card->cBlock; nBlock++) {
+ if (fatp[nBlock] == CARD_FAT_AVAIL) {
+ cFree++;
+ }
+ }
+ if (cFree != fatp[CARD_FAT_FREEBLOCKS]) {
+ ++errors;
+ current = i;
+ card->currentFat = 0;
+ continue;
+ }
+ }
+
+ if (0 == errors) {
+ if (card->currentFat == 0) {
+ if (((s16)fat[0][CARD_FAT_CHECKCODE] - (s16)fat[1][CARD_FAT_CHECKCODE]) < 0) {
+ current = 0;
+ } else {
+ current = 1;
+ }
+ card->currentFat = fat[current];
+ memcpy(fat[current], fat[current ^ 1], CARD_SYSTEM_BLOCK_SIZE);
+ } else {
+ current = (card->currentFat == fat[0]) ? 0 : 1;
+ }
+ }
+ if (outCurrent) {
+ *outCurrent = current;
+ }
+ return errors;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+
+static asm s32 VerifyFAT(CARDControl* card, int* outCurrent) {
+ nofralloc
+ mflr r0
+ li r5, 0
+ stw r0, 4(r1)
+ stwu r1, -0x28(r1)
+ stw r31, 0x24(r1)
+ li r31, 0
+ stw r30, 0x20(r1)
+ li r30, 0
+ stw r29, 0x1c(r1)
+ addi r29, r4, 0
+ addi r4, r1, 0x10
+lbl_803BB274:
+ li r8, 0x1ffc
+ lwz r6, 0x80(r3)
+ addi r0, r5, 3
+ srawi r8, r8, 1
+ slwi r0, r0, 0xd
+ add r7, r6, r0
+ addze. r8, r8
+ stw r7, 0(r4)
+ addi r6, r7, 4
+ li r11, 0
+ li r10, 0
+ ble lbl_803BB35C
+ rlwinm. r0, r8, 0x1d, 3, 0x1f
+ mtctr r0
+ beq lbl_803BB340
+lbl_803BB2B0:
+ lhz r9, 0(r6)
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 2(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 4(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 6(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 8(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 0xa(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 0xc(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ lhz r9, 0xe(r6)
+ add r11, r11, r0
+ nor r0, r9, r9
+ add r10, r10, r9
+ add r11, r11, r0
+ addi r6, r6, 0x10
+ bdnz lbl_803BB2B0
+ andi. r8, r8, 7
+ beq lbl_803BB35C
+lbl_803BB340:
+ mtctr r8
+lbl_803BB344:
+ lhz r9, 0(r6)
+ addi r6, r6, 2
+ nor r0, r9, r9
+ add r10, r10, r9
+ add r11, r11, r0
+ bdnz lbl_803BB344
+lbl_803BB35C:
+ clrlwi r0, r10, 0x10
+ cmplwi r0, 0xffff
+ bne lbl_803BB36C
+ li r10, 0
+lbl_803BB36C:
+ clrlwi r0, r11, 0x10
+ cmplwi r0, 0xffff
+ bne lbl_803BB37C
+ li r11, 0
+lbl_803BB37C:
+ lhz r6, 0(r7)
+ clrlwi r0, r10, 0x10
+ cmplw r6, r0
+ bne lbl_803BB39C
+ lhz r6, 2(r7)
+ clrlwi r0, r11, 0x10
+ cmplw r6, r0
+ beq lbl_803BB3B0
+lbl_803BB39C:
+ li r0, 0
+ stw r0, 0x88(r3)
+ addi r30, r5, 0
+ addi r31, r31, 1
+ b lbl_803BB408
+lbl_803BB3B0:
+ lhz r8, 0x10(r3)
+ addi r6, r7, 0xa
+ li r10, 0
+ li r9, 5
+ b lbl_803BB3DC
+lbl_803BB3C4:
+ lhz r0, 0(r6)
+ cmplwi r0, 0
+ bne lbl_803BB3D4
+ addi r10, r10, 1
+lbl_803BB3D4:
+ addi r6, r6, 2
+ addi r9, r9, 1
+lbl_803BB3DC:
+ clrlwi r0, r9, 0x10
+ cmplw r0, r8
+ blt lbl_803BB3C4
+ lhz r0, 6(r7)
+ clrlwi r6, r10, 0x10
+ cmplw r6, r0
+ beq lbl_803BB408
+ li r0, 0
+ stw r0, 0x88(r3)
+ addi r30, r5, 0
+ addi r31, r31, 1
+lbl_803BB408:
+ addi r5, r5, 1
+ cmpwi r5, 2
+ addi r4, r4, 4
+ blt lbl_803BB274
+ cmpwi r31, 0
+ bne lbl_803BB4A0
+ lwz r4, 0x88(r3)
+ cmplwi r4, 0
+ bne lbl_803BB484
+ lwz r5, 0x14(r1)
+ lwz r4, 0x10(r1)
+ lha r5, 4(r5)
+ lha r0, 4(r4)
+ subf. r0, r5, r0
+ bge lbl_803BB44C
+ li r30, 0
+ b lbl_803BB450
+lbl_803BB44C:
+ li r30, 1
+lbl_803BB450:
+ slwi r0, r30, 2
+ addi r6, r1, 0x10
+ add r6, r6, r0
+ lwz r4, 0(r6)
+ xori r0, r30, 1
+ slwi r0, r0, 2
+ stw r4, 0x88(r3)
+ addi r4, r1, 0x10
+ li r5, 0x2000
+ lwz r3, 0(r6)
+ lwzx r4, r4, r0
+ bl memcpy
+ b lbl_803BB4A0
+lbl_803BB484:
+ lwz r0, 0x10(r1)
+ cmplw r4, r0
+ bne lbl_803BB498
+ li r0, 0
+ b lbl_803BB49C
+lbl_803BB498:
+ li r0, 1
+lbl_803BB49C:
+ mr r30, r0
+lbl_803BB4A0:
+ cmplwi r29, 0
+ beq lbl_803BB4AC
+ stw r30, 0(r29)
+lbl_803BB4AC:
+ mr r3, r31
+ lwz r0, 0x2c(r1)
+ lwz r31, 0x24(r1)
+ lwz r30, 0x20(r1)
+ lwz r29, 0x1c(r1)
+ addi r1, r1, 0x28
+ mtlr r0
+ blr
+}
+
+/* clang-format on */
+#pragma pop
+#endif
+
+s32 __CARDVerify(CARDControl* card) {
+ s32 result;
+ int errors;
+
+ result = VerifyID(card);
+ if (result < 0) {
+ return result;
+ }
+
+ errors = VerifyDir(card, NULL);
+ errors += VerifyFAT(card, NULL);
+ switch (errors) {
+ case 0:
+ return CARD_RESULT_READY;
+ case 1:
+ return CARD_RESULT_BROKEN;
+ default:
+ return CARD_RESULT_BROKEN;
+ }
+}
+
+s32 CARDCheckExAsync(s32 chan, s32* xferBytes, CARDCallback callback) {
+ CARDControl* card;
+ CARDDir* dir[2];
+ u16* fat[2];
+ u16* map;
+ s32 result;
+ int errors;
+ int currentFat;
+ int currentDir;
+ s32 fileNo;
+ u16 iBlock;
+ u16 cBlock;
+ u16 cFree;
+ BOOL updateFat = FALSE;
+ BOOL updateDir = FALSE;
+ BOOL updateOrphan = FALSE;
+
+ if (xferBytes) {
+ *xferBytes = 0;
+ }
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ result = VerifyID(card);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+
+ errors = VerifyDir(card, &currentDir);
+ errors += VerifyFAT(card, &currentFat);
+ if (1 < errors) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+
+ dir[0] = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE);
+ dir[1] = (CARDDir*)((u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE);
+ fat[0] = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE);
+ fat[1] = (u16*)((u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE);
+
+ switch (errors) {
+ case 0:
+ break;
+ case 1:
+ if (!card->currentDir) {
+ card->currentDir = dir[currentDir];
+ memcpy(dir[currentDir], dir[currentDir ^ 1], CARD_SYSTEM_BLOCK_SIZE);
+ updateDir = TRUE;
+ } else {
+ card->currentFat = fat[currentFat];
+ memcpy(fat[currentFat], fat[currentFat ^ 1], CARD_SYSTEM_BLOCK_SIZE);
+ updateFat = TRUE;
+ }
+ break;
+ }
+
+ map = fat[currentFat ^ 1];
+ memset(map, 0, CARD_SYSTEM_BLOCK_SIZE);
+
+ for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
+ CARDDir* ent;
+
+ ent = &card->currentDir[fileNo];
+ if (ent->gameName[0] == 0xff) {
+ continue;
+ }
+
+ for (iBlock = ent->startBlock, cBlock = 0; iBlock != 0xFFFF && cBlock < ent->length;
+ iBlock = card->currentFat[iBlock], ++cBlock) {
+ if (!CARDIsValidBlockNo(card, iBlock) || 1 < ++map[iBlock]) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+ }
+ if (cBlock != ent->length || iBlock != 0xFFFF) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+ }
+
+ cFree = 0;
+ for (iBlock = CARD_NUM_SYSTEM_BLOCK; iBlock < card->cBlock; iBlock++) {
+ u16 nextBlock;
+
+ nextBlock = card->currentFat[iBlock];
+ if (map[iBlock] == 0) {
+ if (nextBlock != CARD_FAT_AVAIL) {
+ card->currentFat[iBlock] = CARD_FAT_AVAIL;
+ updateOrphan = TRUE;
+ }
+ cFree++;
+ } else if (!CARDIsValidBlockNo(card, nextBlock) && nextBlock != 0xFFFF) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+ }
+ if (cFree != card->currentFat[CARD_FAT_FREEBLOCKS]) {
+ card->currentFat[CARD_FAT_FREEBLOCKS] = cFree;
+ updateOrphan = TRUE;
+ }
+ if (updateOrphan) {
+ __CARDCheckSum(&card->currentFat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32),
+ &card->currentFat[CARD_FAT_CHECKSUM], &card->currentFat[CARD_FAT_CHECKSUMINV]);
+ }
+
+ memcpy(fat[currentFat ^ 1], fat[currentFat], CARD_SYSTEM_BLOCK_SIZE);
+
+ if (updateDir) {
+ if (xferBytes) {
+ *xferBytes = CARD_SYSTEM_BLOCK_SIZE;
+ }
+ return __CARDUpdateDir(chan, callback);
+ }
+
+ if (updateFat | updateOrphan) {
+ if (xferBytes) {
+ *xferBytes = CARD_SYSTEM_BLOCK_SIZE;
+ }
+ return __CARDUpdateFatBlock(chan, card->currentFat, callback);
+ }
+
+ __CARDPutControlBlock(card, CARD_RESULT_READY);
+ if (callback) {
+ BOOL enabled = OSDisableInterrupts();
+ callback(chan, CARD_RESULT_READY);
+ OSRestoreInterrupts(enabled);
+ }
+ return CARD_RESULT_READY;
+}
+
+s32 CARDCheckAsync(s32 chan, CARDCallback callback) {
+ s32 xferBytes;
+
+ return CARDCheckExAsync(chan, &xferBytes, callback);
+}
diff --git a/src/Dolphin/card/CARDCreate.c b/src/Dolphin/card/CARDCreate.c
new file mode 100644
index 0000000..6802b91
--- /dev/null
+++ b/src/Dolphin/card/CARDCreate.c
@@ -0,0 +1,115 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+static void CreateCallbackFat(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ if (result < 0) {
+ goto error;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[card->freeNo];
+ memcpy(ent->gameName, card->diskID->gameName, sizeof(ent->gameName));
+ memcpy(ent->company, card->diskID->company, sizeof(ent->company));
+ ent->permission = CARD_ATTR_PUBLIC;
+ ent->copyTimes = 0;
+ ent->startBlock = card->startBlock;
+
+ ent->bannerFormat = 0;
+ ent->iconAddr = 0xffffffff;
+ ent->iconFormat = 0;
+ ent->iconSpeed = 0;
+ ent->commentAddr = 0xffffffff;
+
+ CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST);
+
+ card->fileInfo->offset = 0;
+ card->fileInfo->iBlock = ent->startBlock;
+
+ ent->time = (u32)OSTicksToSeconds(OSGetTime());
+ result = __CARDUpdateDir(chan, callback);
+ if (result < 0) {
+ goto error;
+ }
+ return;
+
+error:
+ __CARDPutControlBlock(card, result);
+ if (callback) {
+ callback(chan, result);
+ }
+}
+
+s32 CARDCreateAsync(s32 chan, const char* fileName, u32 size, CARDFileInfo* fileInfo,
+ CARDCallback callback) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+ u16 fileNo;
+ u16 freeNo;
+ u16* fat;
+
+ if (strlen(fileName) > (u32)CARD_FILENAME_MAX) {
+ return CARD_RESULT_NAMETOOLONG;
+ }
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ if (size <= 0 || (size % card->sectorSize) != 0) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+
+ freeNo = (u16)-1;
+ dir = __CARDGetDirBlock(card);
+ for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
+ ent = &dir[fileNo];
+ if (ent->gameName[0] == 0xff) {
+ if (freeNo == (u16)-1) {
+ freeNo = fileNo;
+ }
+ } else if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) == 0 &&
+ memcmp(ent->company, card->diskID->company, sizeof(ent->company)) == 0 &&
+ __CARDCompareFileName(ent, fileName)) {
+ return __CARDPutControlBlock(card, CARD_RESULT_EXIST);
+ }
+ }
+ if (freeNo == (u16)-1) {
+ return __CARDPutControlBlock(card, CARD_RESULT_NOENT);
+ }
+
+ fat = __CARDGetFatBlock(card);
+ if (card->sectorSize * fat[CARD_FAT_FREEBLOCKS] < size) {
+ return __CARDPutControlBlock(card, CARD_RESULT_INSSPACE);
+ }
+
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+ card->freeNo = freeNo;
+ ent = &dir[freeNo];
+ ent->length = (u16)(size / card->sectorSize);
+ strncpy(ent->fileName, fileName, CARD_FILENAME_MAX);
+
+ card->fileInfo = fileInfo;
+ fileInfo->chan = chan;
+ fileInfo->fileNo = freeNo;
+
+ result = __CARDAllocBlock(chan, size / card->sectorSize, CreateCallbackFat);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
diff --git a/src/Dolphin/card/CARDDelete.c b/src/Dolphin/card/CARDDelete.c
new file mode 100644
index 0000000..f715751
--- /dev/null
+++ b/src/Dolphin/card/CARDDelete.c
@@ -0,0 +1,97 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+static void DeleteCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+
+ if (result < 0) {
+ goto error;
+ }
+
+ result = __CARDFreeBlock(chan, card->startBlock, callback);
+ if (result < 0) {
+ goto error;
+ }
+ return;
+
+error:
+ __CARDPutControlBlock(card, result);
+ if (callback) {
+ callback(chan, result);
+ }
+}
+
+s32 CARDFastDeleteAsync(s32 chan, s32 fileNo, CARDCallback callback) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+
+ if (fileNo < 0 || CARD_MAX_FILE <= fileNo) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileNo];
+ result = __CARDAccess(card, ent);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+ if (__CARDIsOpened(card, fileNo)) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BUSY);
+ }
+ card->startBlock = ent->startBlock;
+ memset(ent, 0xff, sizeof(CARDDir));
+
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+ result = __CARDUpdateDir(chan, DeleteCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
+
+s32 CARDDeleteAsync(s32 chan, const char* fileName, CARDCallback callback) {
+ CARDControl* card;
+ s32 fileNo;
+ s32 result;
+ CARDDir* dir;
+ CARDDir* ent;
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+ result = __CARDGetFileNo(card, fileName, &fileNo);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+ if (__CARDIsOpened(card, fileNo)) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BUSY);
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileNo];
+ card->startBlock = ent->startBlock;
+ memset(ent, 0xff, sizeof(CARDDir));
+
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+ result = __CARDUpdateDir(chan, DeleteCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
diff --git a/src/Dolphin/card/CARDDir.c b/src/Dolphin/card/CARDDir.c
new file mode 100644
index 0000000..1daecf8
--- /dev/null
+++ b/src/Dolphin/card/CARDDir.c
@@ -0,0 +1,92 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+CARDDir* __CARDGetDirBlock(CARDControl* card) { return card->currentDir; }
+
+static void WriteCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ if (0 <= result) {
+ CARDDir* dir0 = (CARDDir*)((u8*)card->workArea + 0x2000);
+ CARDDir* dir1 = (CARDDir*)((u8*)card->workArea + 0x4000);
+
+ if (card->currentDir == dir0) {
+ card->currentDir = dir1;
+ memcpy(dir1, dir0, 0x2000);
+ } else {
+ card->currentDir = dir0;
+ memcpy(dir0, dir1, 0x2000);
+ }
+ }
+
+error:
+ if (card->apiCallback == 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ callback = card->eraseCallback;
+ if (callback) {
+ card->eraseCallback = 0;
+ callback(chan, result);
+ }
+}
+
+static void EraseCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+ CARDDir* dir;
+ u32 tmp[2];
+ u32 addr;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize;
+ result = __CARDWrite(chan, addr, 0x2000, dir, WriteCallback);
+ if (result < 0) {
+ goto error;
+ }
+
+ return;
+
+error:
+ if (card->apiCallback == 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ callback = card->eraseCallback;
+ if (callback) {
+ card->eraseCallback = 0;
+ callback(chan, result);
+ }
+}
+
+s32 __CARDUpdateDir(s32 chan, CARDCallback callback) {
+ CARDControl* card;
+ CARDDirCheck* check;
+ u32 tmp[2];
+ u32 addr;
+ CARDDir* dir;
+
+ card = &__CARDBlock[chan];
+ if (!card->attached) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ check = __CARDGetDirCheck(dir);
+ ++check->checkCode;
+ __CARDCheckSum(dir, 0x2000 - sizeof(u32), &check->checkSum, &check->checkSumInv);
+ DCStoreRange(dir, 0x2000);
+
+ card->eraseCallback = callback;
+ addr = ((u32)dir - (u32)card->workArea) / 0x2000 * card->sectorSize;
+ return __CARDEraseSector(chan, addr, EraseCallback);
+}
diff --git a/src/Dolphin/card/CARDFormat.c b/src/Dolphin/card/CARDFormat.c
new file mode 100644
index 0000000..ebfff8b
--- /dev/null
+++ b/src/Dolphin/card/CARDFormat.c
@@ -0,0 +1,127 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+#include <dolphin/OSRtcPriv.h>
+#include <dolphin/vi.h>
+
+static void FormatCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ ++card->formatStep;
+ if (card->formatStep < CARD_NUM_SYSTEM_BLOCK) {
+ result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback);
+ if (0 <= result) {
+ return;
+ }
+ } else if (card->formatStep < 2 * CARD_NUM_SYSTEM_BLOCK) {
+ int step = card->formatStep - CARD_NUM_SYSTEM_BLOCK;
+ result = __CARDWrite(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE,
+ (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), FormatCallback);
+ if (result >= 0) {
+ return;
+ }
+ } else {
+ card->currentDir = (CARDDir*)((u8*)card->workArea + (1 + 0) * CARD_SYSTEM_BLOCK_SIZE);
+ memcpy(card->currentDir, (u8*)card->workArea + (1 + 1) * CARD_SYSTEM_BLOCK_SIZE,
+ CARD_SYSTEM_BLOCK_SIZE);
+ card->currentFat = (u16*)((u8*)card->workArea + (3 + 0) * CARD_SYSTEM_BLOCK_SIZE);
+ memcpy(card->currentFat, (u8*)card->workArea + (3 + 1) * CARD_SYSTEM_BLOCK_SIZE,
+ CARD_SYSTEM_BLOCK_SIZE);
+ }
+
+error:
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ __CARDPutControlBlock(card, result);
+ callback(chan, result);
+}
+
+s32 __CARDFormatRegionAsync(s32 chan, u16 encode, CARDCallback callback) {
+ CARDControl* card;
+ CARDID* id;
+ CARDDir* dir;
+ u16* fat;
+ s16 i;
+ s32 result;
+ OSSram* sram;
+ OSSramEx* sramEx;
+ u16 viDTVStatus;
+ OSTime time;
+ OSTime rand;
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ id = (CARDID*)card->workArea;
+ memset(id, 0xff, CARD_SYSTEM_BLOCK_SIZE);
+ viDTVStatus = __VIRegs[55];
+
+ id->encode = encode;
+
+ sram = __OSLockSram();
+ *(u32*)&id->serial[20] = sram->counterBias;
+ *(u32*)&id->serial[24] = sram->language;
+ __OSUnlockSram(FALSE);
+
+ rand = time = OSGetTime();
+
+ sramEx = __OSLockSramEx();
+ for (i = 0; i < 12; i++) {
+ rand = (rand * 1103515245 + 12345) >> 16;
+ id->serial[i] = (u8)(sramEx->flashID[chan][i] + rand);
+ rand = ((rand * 1103515245 + 12345) >> 16) & 0x7FFF;
+ }
+ __OSUnlockSramEx(FALSE);
+
+ *(u32*)&id->serial[28] = viDTVStatus;
+ *(OSTime*)&id->serial[12] = time;
+
+ id->deviceID = 0;
+ id->size = card->size;
+ __CARDCheckSum(id, sizeof(CARDID) - sizeof(u32), &id->checkSum, &id->checkSumInv);
+
+ for (i = 0; i < 2; i++) {
+ CARDDirCheck* check;
+
+ dir = (CARDDir*)((u8*)card->workArea + (1 + i) * CARD_SYSTEM_BLOCK_SIZE);
+ memset(dir, 0xff, CARD_SYSTEM_BLOCK_SIZE);
+ check = __CARDGetDirCheck(dir);
+ check->checkCode = i;
+ __CARDCheckSum(dir, CARD_SYSTEM_BLOCK_SIZE - sizeof(u32), &check->checkSum,
+ &check->checkSumInv);
+ }
+ for (i = 0; i < 2; i++) {
+ fat = (u16*)((u8*)card->workArea + (3 + i) * CARD_SYSTEM_BLOCK_SIZE);
+ memset(fat, 0x00, CARD_SYSTEM_BLOCK_SIZE);
+ fat[CARD_FAT_CHECKCODE] = (u16)i;
+ fat[CARD_FAT_FREEBLOCKS] = (u16)(card->cBlock - CARD_NUM_SYSTEM_BLOCK);
+ fat[CARD_FAT_LASTSLOT] = CARD_NUM_SYSTEM_BLOCK - 1;
+ __CARDCheckSum(&fat[CARD_FAT_CHECKCODE], CARD_SYSTEM_BLOCK_SIZE - sizeof(u32),
+ &fat[CARD_FAT_CHECKSUM], &fat[CARD_FAT_CHECKSUMINV]);
+ }
+
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+ DCStoreRange(card->workArea, CARD_WORKAREA_SIZE);
+
+ card->formatStep = 0;
+ result = __CARDEraseSector(chan, (u32)card->sectorSize * card->formatStep, FormatCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
+
+s32 CARDFormatAsync(s32 chan, CARDCallback callback) {
+ return __CARDFormatRegionAsync(chan, __CARDGetFontEncode(), callback);
+}
diff --git a/src/Dolphin/card/CARDMount.c b/src/Dolphin/card/CARDMount.c
new file mode 100644
index 0000000..fd361e9
--- /dev/null
+++ b/src/Dolphin/card/CARDMount.c
@@ -0,0 +1,354 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+#include <dolphin/OSRtcPriv.h>
+
+u8 GameChoice : (OS_BASE_CACHED | 0x000030E3);
+
+static u32 SectorSizeTable[8] = {
+ 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024, 256 * 1024, 0, 0,
+};
+
+static u32 LatencyTable[8] = {
+ 4, 8, 16, 32, 64, 128, 256, 512,
+};
+
+void __CARDMountCallback(s32 chan, s32 result);
+static void DoUnmount(s32 chan, s32 result);
+
+static BOOL IsCard(u32 id) {
+ u32 size;
+ s32 sectorSize;
+ if (id & (0xFFFF0000) && (id != 0x80000004 || __CARDVendorID == 0xFFFF)) {
+ return FALSE;
+ }
+
+ if ((id & 3) != 0) {
+ return FALSE;
+ }
+
+ size = id & 0xfc;
+ switch (size) {
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+
+ sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
+ if (sectorSize == 0) {
+ return FALSE;
+ }
+
+ if ((size * 1024 * 1024 / 8) / sectorSize < 8) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+s32 CARDProbeEx(s32 chan, s32* memSize, s32* sectorSize) {
+ u32 id;
+ CARDControl* card;
+ BOOL enabled;
+ s32 result;
+ int probe;
+
+ if (chan < 0 || 2 <= chan) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+
+ if (GameChoice & 0x80) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ card = &__CARDBlock[chan];
+ enabled = OSDisableInterrupts();
+
+ probe = EXIProbeEx(chan);
+ if (probe == -1) {
+ result = CARD_RESULT_NOCARD;
+ } else if (probe == 0) {
+ result = CARD_RESULT_BUSY;
+ } else if (card->attached) {
+ if (card->mountStep < 1) {
+ result = CARD_RESULT_BUSY;
+ } else {
+ if (memSize) {
+ *memSize = card->size;
+ }
+ if (sectorSize) {
+ *sectorSize = card->sectorSize;
+ }
+ result = CARD_RESULT_READY;
+ }
+ } else if ((EXIGetState(chan) & 8)) {
+ result = CARD_RESULT_WRONGDEVICE;
+ } else if (!EXIGetID(chan, 0, &id)) {
+ result = CARD_RESULT_BUSY;
+ } else if (IsCard(id)) {
+ if (memSize) {
+ *memSize = (s32)(id & 0xfc);
+ }
+ if (sectorSize) {
+ *sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
+ }
+ result = CARD_RESULT_READY;
+ } else {
+ result = CARD_RESULT_WRONGDEVICE;
+ }
+
+ OSRestoreInterrupts(enabled);
+ return result;
+}
+
+static s32 DoMount(s32 chan) {
+ CARDControl* card;
+ u32 id;
+ u8 status;
+ s32 result;
+ OSSramEx* sram;
+ int i;
+ u8 checkSum;
+ int step;
+
+ card = &__CARDBlock[chan];
+
+ if (card->mountStep == 0) {
+ if (EXIGetID(chan, 0, &id) == 0) {
+ result = CARD_RESULT_NOCARD;
+ } else if (IsCard(id)) {
+ result = CARD_RESULT_READY;
+ } else {
+ result = CARD_RESULT_WRONGDEVICE;
+ }
+ if (result < 0) {
+ goto error;
+ }
+
+ card->cid = id;
+
+ card->size = (u16)(id & 0xFC);
+ card->sectorSize = SectorSizeTable[(id & 0x00003800) >> 11];
+ card->cBlock = (u16)((card->size * 1024 * 1024 / 8) / card->sectorSize);
+ card->latency = LatencyTable[(id & 0x00000700) >> 8];
+
+ result = __CARDClearStatus(chan);
+ if (result < 0) {
+ goto error;
+ }
+ result = __CARDReadStatus(chan, &status);
+ if (result < 0) {
+ goto error;
+ }
+
+ if (!EXIProbe(chan)) {
+ result = CARD_RESULT_NOCARD;
+ goto error;
+ }
+
+ if (!(status & 0x40)) {
+ result = __CARDUnlock(chan, card->id);
+ if (result < 0) {
+ goto error;
+ }
+
+ checkSum = 0;
+ sram = __OSLockSramEx();
+ for (i = 0; i < 12; i++) {
+ sram->flashID[chan][i] = card->id[i];
+ checkSum += card->id[i];
+ }
+ sram->flashIDCheckSum[chan] = (u8)~checkSum;
+ __OSUnlockSramEx(TRUE);
+
+ return result;
+ } else {
+ card->mountStep = 1;
+
+ checkSum = 0;
+ sram = __OSLockSramEx();
+ for (i = 0; i < 12; i++) {
+ checkSum += sram->flashID[chan][i];
+ }
+ __OSUnlockSramEx(FALSE);
+ if (sram->flashIDCheckSum[chan] != (u8)~checkSum) {
+ result = CARD_RESULT_IOERROR;
+ goto error;
+ }
+ }
+ }
+
+ if (card->mountStep == 1) {
+ if (card->cid == 0x80000004) {
+ u16 vendorID;
+
+ sram = __OSLockSramEx();
+ vendorID = *(u16*)sram->flashID[chan];
+ __OSUnlockSramEx(FALSE);
+
+ if (__CARDVendorID == 0xffff || vendorID != __CARDVendorID) {
+ result = CARD_RESULT_WRONGDEVICE;
+ goto error;
+ }
+ }
+
+ card->mountStep = 2;
+
+ result = __CARDEnableInterrupt(chan, TRUE);
+ if (result < 0) {
+ goto error;
+ }
+
+ EXISetExiCallback(chan, __CARDExiHandler);
+ EXIUnlock(chan);
+ DCInvalidateRange(card->workArea, CARD_WORKAREA_SIZE);
+ }
+
+ step = card->mountStep - 2;
+ result = __CARDRead(chan, (u32)card->sectorSize * step, CARD_SYSTEM_BLOCK_SIZE,
+ (u8*)card->workArea + (CARD_SYSTEM_BLOCK_SIZE * step), __CARDMountCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+
+error:
+ EXIUnlock(chan);
+ DoUnmount(chan, result);
+ return result;
+}
+
+void __CARDMountCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+
+ switch (result) {
+ case CARD_RESULT_READY:
+ if (++card->mountStep < CARD_MAX_MOUNT_STEP) {
+ result = DoMount(chan);
+ if (0 <= result) {
+ return;
+ }
+ } else {
+ result = __CARDVerify(card);
+ }
+ break;
+ case CARD_RESULT_UNLOCKED:
+ card->unlockCallback = __CARDMountCallback;
+ if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
+ return;
+ }
+ card->unlockCallback = 0;
+
+ result = DoMount(chan);
+ if (0 <= result) {
+ return;
+ }
+ break;
+ case CARD_RESULT_IOERROR:
+ case CARD_RESULT_NOCARD:
+ DoUnmount(chan, result);
+ break;
+ }
+
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ __CARDPutControlBlock(card, result);
+ callback(chan, result);
+}
+
+s32 CARDMountAsync(s32 chan, void* workArea, CARDCallback detachCallback,
+ CARDCallback attachCallback) {
+ CARDControl* card;
+ BOOL enabled;
+
+ if (chan < 0 || 2 <= chan) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ if (GameChoice & 0x80) {
+ return CARD_RESULT_NOCARD;
+ }
+ card = &__CARDBlock[chan];
+
+ enabled = OSDisableInterrupts();
+ if (card->result == CARD_RESULT_BUSY) {
+ OSRestoreInterrupts(enabled);
+ return CARD_RESULT_BUSY;
+ }
+
+ if (!card->attached && (EXIGetState(chan) & 0x08)) {
+ OSRestoreInterrupts(enabled);
+ return CARD_RESULT_WRONGDEVICE;
+ }
+
+ card->result = CARD_RESULT_BUSY;
+ card->workArea = workArea;
+ card->extCallback = detachCallback;
+ card->apiCallback = attachCallback ? attachCallback : __CARDDefaultApiCallback;
+ card->exiCallback = 0;
+
+ if (!card->attached && !EXIAttach(chan, __CARDExtHandler)) {
+ card->result = CARD_RESULT_NOCARD;
+ OSRestoreInterrupts(enabled);
+ return CARD_RESULT_NOCARD;
+ }
+
+ card->mountStep = 0;
+ card->attached = TRUE;
+ EXISetExiCallback(chan, 0);
+ OSCancelAlarm(&card->alarm);
+
+ card->currentDir = 0;
+ card->currentFat = 0;
+
+ OSRestoreInterrupts(enabled);
+
+ card->unlockCallback = __CARDMountCallback;
+ if (!EXILock(chan, 0, __CARDUnlockedHandler)) {
+ return CARD_RESULT_READY;
+ }
+ card->unlockCallback = 0;
+
+ return DoMount(chan);
+}
+
+static void DoUnmount(s32 chan, s32 result) {
+ CARDControl* card;
+ BOOL enabled;
+
+ card = &__CARDBlock[chan];
+ enabled = OSDisableInterrupts();
+ if (card->attached) {
+ EXISetExiCallback(chan, 0);
+ EXIDetach(chan);
+ OSCancelAlarm(&card->alarm);
+ card->attached = FALSE;
+ card->result = result;
+ card->mountStep = 0;
+ }
+ OSRestoreInterrupts(enabled);
+}
+
+s32 CARDUnmount(s32 chan) {
+ CARDControl* card;
+ s32 result;
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+ DoUnmount(chan, CARD_RESULT_NOCARD);
+ return CARD_RESULT_READY;
+}
diff --git a/src/Dolphin/card/CARDNet.c b/src/Dolphin/card/CARDNet.c
new file mode 100644
index 0000000..828dbad
--- /dev/null
+++ b/src/Dolphin/card/CARDNet.c
@@ -0,0 +1,33 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+u16 __CARDVendorID = 0xffff;
+
+s32 CARDGetSerialNo(s32 chan, u64* serialNo) {
+ CARDControl* card;
+ CARDID* id;
+ int i;
+ u64 code;
+ s32 result;
+
+ if (!(0 <= chan && chan < 2)) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ id = (CARDID*)card->workArea;
+ for (code = 0, i = 0; i < sizeof(id->serial) / sizeof(u64); ++i) {
+ code ^= *(u64*)&id->serial[sizeof(u64) * i];
+ }
+ *serialNo = code;
+
+ return __CARDPutControlBlock(card, CARD_RESULT_READY);
+}
diff --git a/src/Dolphin/card/CARDOpen.c b/src/Dolphin/card/CARDOpen.c
new file mode 100644
index 0000000..60234bf
--- /dev/null
+++ b/src/Dolphin/card/CARDOpen.c
@@ -0,0 +1,123 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+BOOL __CARDCompareFileName(CARDDir* ent, const char* fileName) {
+ char* entName;
+ char c1;
+ char c2;
+ int n;
+
+ entName = (char*)ent->fileName;
+ n = CARD_FILENAME_MAX;
+ while (0 <= --n) {
+ if ((c1 = *entName++) != (c2 = *fileName++)) {
+ return FALSE;
+ } else if (c2 == '\0') {
+ return TRUE;
+ }
+ }
+
+ if (*fileName == '\0') {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+s32 __CARDAccess(CARDControl* card, CARDDir* ent) {
+ if (ent->gameName[0] == 0xFF) {
+ return CARD_RESULT_NOFILE;
+ }
+
+ if (card->diskID == &__CARDDiskNone || (memcmp(ent->gameName, card->diskID->gameName, 4) == 0 &&
+ memcmp(ent->company, card->diskID->company, 2) == 0)) {
+ return CARD_RESULT_READY;
+ }
+
+ return CARD_RESULT_NOPERM;
+}
+
+BOOL __CARDIsWritable(CARDDir* ent) {
+ if (ent->gameName[0] == 0xFF) {
+ return CARD_RESULT_NOFILE;
+ }
+
+ if ((ent->permission & CARD_ATTR_PUBLIC) != 0) {
+ return CARD_RESULT_READY;
+ }
+
+ return CARD_RESULT_NOPERM;
+}
+
+s32 __CARDGetFileNo(CARDControl* card, const char* fileName, s32* pfileNo) {
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 fileNo;
+ s32 result;
+
+ if (!card->attached) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
+ ent = &dir[fileNo];
+ result = __CARDAccess(card, ent);
+ if (result < 0) {
+ continue;
+ }
+ if (__CARDCompareFileName(ent, fileName)) {
+ *pfileNo = fileNo;
+ return CARD_RESULT_READY;
+ }
+ }
+
+ return CARD_RESULT_NOFILE;
+}
+
+s32 CARDOpen(s32 chan, const char* fileName, CARDFileInfo* fileInfo) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+ s32 fileNo;
+
+ fileInfo->chan = -1;
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+ result = __CARDGetFileNo(card, fileName, &fileNo);
+ if (0 <= result) {
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileNo];
+ if (!CARDIsValidBlockNo(card, ent->startBlock)) {
+ result = CARD_RESULT_BROKEN;
+ } else {
+ fileInfo->chan = chan;
+ fileInfo->fileNo = fileNo;
+ fileInfo->offset = 0;
+ fileInfo->iBlock = ent->startBlock;
+ }
+ }
+ return __CARDPutControlBlock(card, result);
+}
+
+s32 CARDClose(CARDFileInfo* fileInfo) {
+ CARDControl* card;
+ s32 result;
+
+ result = __CARDGetControlBlock(fileInfo->chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ fileInfo->chan = -1;
+ return __CARDPutControlBlock(card, CARD_RESULT_READY);
+}
+
+BOOL __CARDIsOpened(CARDControl* card, s32 fileNo) { return FALSE; }
diff --git a/src/Dolphin/card/CARDRdwr.c b/src/Dolphin/card/CARDRdwr.c
new file mode 100644
index 0000000..2f41be7
--- /dev/null
+++ b/src/Dolphin/card/CARDRdwr.c
@@ -0,0 +1,104 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+static void BlockReadCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ card->xferred += CARD_SEG_SIZE;
+
+ card->addr += CARD_SEG_SIZE;
+ (u8*)card->buffer += CARD_SEG_SIZE;
+ if (--card->repeat <= 0) {
+ goto error;
+ }
+
+ result = __CARDReadSegment(chan, BlockReadCallback);
+ if (result < 0) {
+ goto error;
+ }
+ return;
+
+error:
+ if (card->apiCallback == 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ callback = card->xferCallback;
+ if (callback) {
+ card->xferCallback = 0;
+ callback(chan, result);
+ }
+}
+
+s32 __CARDRead(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) {
+ CARDControl* card;
+ card = &__CARDBlock[chan];
+ if (!card->attached) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ card->xferCallback = callback;
+ card->repeat = (int)(length / CARD_SEG_SIZE);
+ card->addr = addr;
+ card->buffer = dst;
+
+ return __CARDReadSegment(chan, BlockReadCallback);
+}
+
+static void BlockWriteCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ card->xferred += CARD_PAGE_SIZE;
+
+ card->addr += CARD_PAGE_SIZE;
+ (u8*)card->buffer += CARD_PAGE_SIZE;
+ if (--card->repeat <= 0) {
+ goto error;
+ }
+
+ result = __CARDWritePage(chan, BlockWriteCallback);
+ if (result < 0) {
+ goto error;
+ }
+ return;
+
+error:
+ if (card->apiCallback == 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ callback = card->xferCallback;
+ if (callback) {
+ card->xferCallback = 0;
+ callback(chan, result);
+ }
+}
+
+s32 __CARDWrite(s32 chan, u32 addr, s32 length, void* dst, CARDCallback callback) {
+ CARDControl* card;
+ card = &__CARDBlock[chan];
+ if (!card->attached) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ card->xferCallback = callback;
+ card->repeat = (int)(length / CARD_PAGE_SIZE);
+ card->addr = addr;
+ card->buffer = dst;
+
+ return __CARDWritePage(chan, BlockWriteCallback);
+}
diff --git a/src/Dolphin/card/CARDRead.c b/src/Dolphin/card/CARDRead.c
new file mode 100644
index 0000000..ffffc5f
--- /dev/null
+++ b/src/Dolphin/card/CARDRead.c
@@ -0,0 +1,141 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+s32 __CARDSeek(CARDFileInfo* fileInfo, s32 length, s32 offset, CARDControl** pcard) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+ u16* fat;
+
+ result = __CARDGetControlBlock(fileInfo->chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ if (!CARDIsValidBlockNo(card, fileInfo->iBlock) ||
+ card->cBlock * card->sectorSize <= fileInfo->offset) {
+ return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR);
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileInfo->fileNo];
+ if (ent->length * card->sectorSize <= offset ||
+ ent->length * card->sectorSize < offset + length) {
+ return __CARDPutControlBlock(card, CARD_RESULT_LIMIT);
+ }
+
+ card->fileInfo = fileInfo;
+ fileInfo->length = length;
+ if (offset < fileInfo->offset) {
+ fileInfo->offset = 0;
+ fileInfo->iBlock = ent->startBlock;
+ if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+ }
+ fat = __CARDGetFatBlock(card);
+ while (fileInfo->offset < TRUNC(offset, card->sectorSize)) {
+ fileInfo->offset += card->sectorSize;
+ fileInfo->iBlock = fat[fileInfo->iBlock];
+ if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
+ return __CARDPutControlBlock(card, CARD_RESULT_BROKEN);
+ }
+ }
+
+ fileInfo->offset = offset;
+
+ *pcard = card;
+ return CARD_RESULT_READY;
+}
+
+static void ReadCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+ u16* fat;
+ CARDFileInfo* fileInfo;
+ s32 length;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ fileInfo = card->fileInfo;
+ if (fileInfo->length < 0) {
+ result = CARD_RESULT_CANCELED;
+ goto error;
+ }
+
+ length = (s32)TRUNC(fileInfo->offset + card->sectorSize, card->sectorSize) - fileInfo->offset;
+ fileInfo->length -= length;
+ if (fileInfo->length <= 0) {
+ goto error;
+ }
+
+ fat = __CARDGetFatBlock(card);
+ fileInfo->offset += length;
+ fileInfo->iBlock = fat[fileInfo->iBlock];
+ if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
+ result = CARD_RESULT_BROKEN;
+ goto error;
+ }
+
+ result = __CARDRead(chan, card->sectorSize * (u32)fileInfo->iBlock,
+ (fileInfo->length < card->sectorSize) ? fileInfo->length : card->sectorSize,
+ card->buffer, ReadCallback);
+ if (result < 0) {
+ goto error;
+ }
+
+ return;
+
+error:
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ __CARDPutControlBlock(card, result);
+ callback(chan, result);
+}
+
+s32 CARDReadAsync(CARDFileInfo* fileInfo, void* buf, s32 length, s32 offset,
+ CARDCallback callback) {
+ CARDControl* card;
+ s32 result;
+ CARDDir* dir;
+ CARDDir* ent;
+
+ if (OFFSET(offset, CARD_SEG_SIZE) != 0 || OFFSET(length, CARD_SEG_SIZE) != 0) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ result = __CARDSeek(fileInfo, length, offset, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileInfo->fileNo];
+ result = __CARDAccess(card, ent);
+ if (result == CARD_RESULT_NOPERM) {
+ result = __CARDIsWritable(ent);
+ }
+
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+
+ DCInvalidateRange(buf, (u32)length);
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+
+ offset = (s32)OFFSET(fileInfo->offset, card->sectorSize);
+ length = (length < card->sectorSize - offset) ? length : card->sectorSize - offset;
+ result = __CARDRead(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock + offset, length,
+ buf, ReadCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
diff --git a/src/Dolphin/card/CARDRename.c b/src/Dolphin/card/CARDRename.c
new file mode 100644
index 0000000..83d1c8a
--- /dev/null
+++ b/src/Dolphin/card/CARDRename.c
@@ -0,0 +1,70 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+s32 CARDRenameAsync(s32 chan, const char* old, const char* new, CARDCallback callback) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+ int fileNo;
+ int newNo;
+ int oldNo;
+
+ if (*old == 0xff || *new == 0xff || *old == 0x00 || *new == 0x00) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ if (CARD_FILENAME_MAX < (u32)strlen(old) || CARD_FILENAME_MAX < (u32)strlen(new)) {
+ return CARD_RESULT_NAMETOOLONG;
+ }
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ newNo = oldNo = -1;
+ dir = __CARDGetDirBlock(card);
+ for (fileNo = 0; fileNo < CARD_MAX_FILE; fileNo++) {
+ ent = &dir[fileNo];
+ if (ent->gameName[0] == 0xff) {
+ continue;
+ }
+
+ if (memcmp(ent->gameName, card->diskID->gameName, sizeof(ent->gameName)) != 0 ||
+ memcmp(ent->company, card->diskID->company, sizeof(ent->company)) != 0) {
+ continue;
+ }
+
+ if (__CARDCompareFileName(ent, old)) {
+ oldNo = fileNo;
+ }
+ if (__CARDCompareFileName(ent, new)) {
+ newNo = fileNo;
+ }
+ }
+
+ if (oldNo == -1) {
+ return __CARDPutControlBlock(card, CARD_RESULT_NOFILE);
+ }
+ if (newNo != -1) {
+ return __CARDPutControlBlock(card, CARD_RESULT_EXIST);
+ }
+
+ ent = &dir[oldNo];
+ result = __CARDAccess(card, ent);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+
+ strncpy((char*)ent->fileName, new, CARD_FILENAME_MAX);
+
+ ent->time = (u32)OSTicksToSeconds(OSGetTime());
+ result = __CARDUpdateDir(chan, callback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
diff --git a/src/Dolphin/card/CARDStat.c b/src/Dolphin/card/CARDStat.c
new file mode 100644
index 0000000..152d535
--- /dev/null
+++ b/src/Dolphin/card/CARDStat.c
@@ -0,0 +1,144 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+static void UpdateIconOffsets(CARDDir* ent, CARDStat* stat) {
+ u32 offset;
+ BOOL iconTlut;
+ int i;
+
+ offset = ent->iconAddr;
+ if (offset == 0xffffffff) {
+ stat->bannerFormat = 0;
+ stat->iconFormat = 0;
+ stat->iconSpeed = 0;
+ offset = 0;
+ }
+
+ iconTlut = FALSE;
+ switch (CARDGetBannerFormat(ent)) {
+ case CARD_STAT_BANNER_C8:
+ stat->offsetBanner = offset;
+ offset += CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT;
+ stat->offsetBannerTlut = offset;
+ offset += 2 * 256;
+ break;
+ case CARD_STAT_BANNER_RGB5A3:
+ stat->offsetBanner = offset;
+ offset += 2 * CARD_BANNER_WIDTH * CARD_BANNER_HEIGHT;
+ stat->offsetBannerTlut = 0xffffffff;
+ break;
+ default:
+ stat->offsetBanner = 0xffffffff;
+ stat->offsetBannerTlut = 0xffffffff;
+ break;
+ }
+ for (i = 0; i < CARD_ICON_MAX; ++i) {
+ switch (CARDGetIconFormat(ent, i)) {
+ case CARD_STAT_ICON_C8:
+ stat->offsetIcon[i] = offset;
+ offset += CARD_ICON_WIDTH * CARD_ICON_HEIGHT;
+ iconTlut = TRUE;
+ break;
+ case CARD_STAT_ICON_RGB5A3:
+ stat->offsetIcon[i] = offset;
+ offset += 2 * CARD_ICON_WIDTH * CARD_ICON_HEIGHT;
+ break;
+ default:
+ stat->offsetIcon[i] = 0xffffffff;
+ break;
+ }
+ }
+ if (iconTlut) {
+ stat->offsetIconTlut = offset;
+ offset += 2 * 256;
+ } else {
+ stat->offsetIconTlut = 0xffffffff;
+ }
+ stat->offsetData = offset;
+}
+
+s32 CARDGetStatus(s32 chan, s32 fileNo, CARDStat* stat) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+
+ if (fileNo < 0 || CARD_MAX_FILE <= fileNo) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileNo];
+ result = __CARDAccess(card, ent);
+ if (result == CARD_RESULT_NOPERM) {
+ result = __CARDIsWritable(ent);
+ }
+
+ if (result >= 0) {
+ memcpy(stat->gameName, ent->gameName, sizeof(stat->gameName));
+ memcpy(stat->company, ent->company, sizeof(stat->company));
+ stat->length = (u32)ent->length * card->sectorSize;
+ memcpy(stat->fileName, ent->fileName, CARD_FILENAME_MAX);
+ stat->time = ent->time;
+
+ stat->bannerFormat = ent->bannerFormat;
+ stat->iconAddr = ent->iconAddr;
+ stat->iconFormat = ent->iconFormat;
+ stat->iconSpeed = ent->iconSpeed;
+ stat->commentAddr = ent->commentAddr;
+
+ UpdateIconOffsets(ent, stat);
+ }
+ return __CARDPutControlBlock(card, result);
+}
+
+s32 CARDSetStatusAsync(s32 chan, s32 fileNo, CARDStat* stat, CARDCallback callback) {
+ CARDControl* card;
+ CARDDir* dir;
+ CARDDir* ent;
+ s32 result;
+
+ if (fileNo < 0 || CARD_MAX_FILE <= fileNo ||
+ (stat->iconAddr != 0xffffffff && CARD_READ_SIZE <= stat->iconAddr) ||
+ (stat->commentAddr != 0xffffffff &&
+ CARD_SYSTEM_BLOCK_SIZE - CARD_COMMENT_SIZE < stat->commentAddr % CARD_SYSTEM_BLOCK_SIZE)) {
+ return CARD_RESULT_FATAL_ERROR;
+ }
+ result = __CARDGetControlBlock(chan, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileNo];
+ result = __CARDAccess(card, ent);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+
+ ent->bannerFormat = stat->bannerFormat;
+ ent->iconAddr = stat->iconAddr;
+ ent->iconFormat = stat->iconFormat;
+ ent->iconSpeed = stat->iconSpeed;
+ ent->commentAddr = stat->commentAddr;
+ UpdateIconOffsets(ent, stat);
+
+ if (ent->iconAddr == 0xffffffff) {
+ CARDSetIconSpeed(ent, 0, CARD_STAT_SPEED_FAST);
+ }
+
+ ent->time = (u32)OSTicksToSeconds(OSGetTime());
+ result = __CARDUpdateDir(chan, callback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
diff --git a/src/Dolphin/card/CARDUnlock.c b/src/Dolphin/card/CARDUnlock.c
new file mode 100644
index 0000000..ebe8300
--- /dev/null
+++ b/src/Dolphin/card/CARDUnlock.c
@@ -0,0 +1,396 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+static void InitCallback(void* task);
+static void DoneCallback(void* task);
+
+static u8 CardData[] ATTRIBUTE_ALIGN(32) = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0xFF, 0x00, 0x21,
+ 0x13, 0x06, 0x12, 0x03, 0x12, 0x04, 0x13, 0x05, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x88, 0xFF, 0xFF,
+ 0x00, 0x89, 0xFF, 0xFF, 0x00, 0x8A, 0xFF, 0xFF, 0x00, 0x8B, 0xFF, 0xFF, 0x8F, 0x00, 0x02, 0xBF,
+ 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x00, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF,
+ 0x00, 0x8E, 0x25, 0xFF, 0x03, 0x80, 0xFF, 0x00, 0x02, 0x94, 0x00, 0x27, 0x02, 0xBF, 0x00, 0x8E,
+ 0x1F, 0xDF, 0x24, 0xFF, 0x02, 0x40, 0x0F, 0xFF, 0x00, 0x98, 0x04, 0x00, 0x00, 0x9A, 0x00, 0x10,
+ 0x00, 0x99, 0x00, 0x00, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x94, 0x02, 0xBF, 0x86, 0x44, 0x02, 0xBF,
+ 0x00, 0x88, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD, 0x00, 0x03, 0x16, 0xFB, 0x00, 0x01, 0x8F, 0x00,
+ 0x02, 0xBF, 0x00, 0x8E, 0x03, 0x80, 0xCD, 0xD1, 0x02, 0x94, 0x00, 0x48, 0x27, 0xFF, 0x03, 0x80,
+ 0x00, 0x01, 0x02, 0x95, 0x00, 0x5A, 0x03, 0x80, 0x00, 0x02, 0x02, 0x95, 0x80, 0x00, 0x02, 0x9F,
+ 0x00, 0x48, 0x00, 0x21, 0x8E, 0x00, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E,
+ 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x25, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC5, 0xFF, 0xFF,
+ 0x03, 0x40, 0x0F, 0xFF, 0x1C, 0x9F, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC7, 0xFF, 0xFF, 0x02, 0xBF,
+ 0x00, 0x8E, 0x00, 0xC6, 0xFF, 0xFF, 0x02, 0xBF, 0x00, 0x8E, 0x00, 0xC0, 0xFF, 0xFF, 0x02, 0xBF,
+ 0x00, 0x8E, 0x20, 0xFF, 0x03, 0x40, 0x0F, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x00, 0x8E, 0x21, 0xFF,
+ 0x02, 0xBF, 0x00, 0x8E, 0x23, 0xFF, 0x12, 0x05, 0x12, 0x06, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21,
+ 0x27, 0xFC, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x00, 0x88, 0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0,
+ 0x80, 0x00, 0x02, 0x9C, 0x00, 0x8E, 0x02, 0xDF, 0x2E, 0xCE, 0x2C, 0xCF, 0x00, 0xF8, 0xFF, 0xCD,
+ 0x00, 0xF9, 0xFF, 0xC9, 0x00, 0xFA, 0xFF, 0xCB, 0x26, 0xC9, 0x02, 0xC0, 0x00, 0x04, 0x02, 0x9D,
+ 0x00, 0x9C, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+typedef struct DecodeParameters {
+ u8* inputAddr;
+ u32 inputLength;
+ u32 aramAddr;
+ u8* outputAddr;
+} DecodeParameters;
+
+static unsigned long int next = 1;
+
+static int CARDRand(void) {
+ next = next * 1103515245 + 12345;
+ return (int)((unsigned int)(next / 65536) % 32768);
+}
+
+static void CARDSrand(unsigned int seed) { next = seed; }
+
+static u32 GetInitVal(void) {
+ u32 tmp;
+ u32 tick;
+
+ tick = OSGetTick();
+ CARDSrand(tick);
+ tmp = 0x7fec8000;
+ tmp |= CARDRand();
+ tmp &= 0xfffff000;
+ return tmp;
+}
+
+static u32 exnor_1st(u32 data, u32 rshift) {
+ u32 wk;
+ u32 w;
+ u32 i;
+
+ w = data;
+ for (i = 0; i < rshift; i++) {
+ wk = ~(w ^ (w >> 7) ^ (w >> 15) ^ (w >> 23));
+ w = (w >> 1) | ((wk << 30) & 0x40000000);
+ }
+ return w;
+}
+
+static u32 exnor(u32 data, u32 lshift) {
+ u32 wk;
+ u32 w;
+ u32 i;
+
+ w = data;
+ for (i = 0; i < lshift; i++) {
+ // 1bit Left Shift
+ wk = ~(w ^ (w << 7) ^ (w << 15) ^ (w << 23));
+ w = (w << 1) | ((wk >> 30) & 0x00000002);
+ // printf("i=%d, w=%8x\n", i, w);
+ }
+ return w;
+}
+
+static u32 bitrev(u32 data) {
+ u32 wk;
+ u32 i;
+ u32 k = 0;
+ u32 j = 1;
+
+ wk = 0;
+ for (i = 0; i < 32; i++) {
+ if (i > 15) {
+ if (i == 31) {
+ wk |= (((data & (0x01 << 31)) >> 31) & 0x01);
+ } else {
+ wk |= ((data & (0x01 << i)) >> j);
+ j += 2;
+ }
+ } else {
+ wk |= ((data & (0x01 << i)) << (31 - i - k));
+ k++;
+ }
+ }
+ return wk;
+}
+
+#define SEC_AD1(x) ((u8)(((x) >> 29) & 0x03))
+#define SEC_AD2(x) ((u8)(((x) >> 21) & 0xff))
+#define SEC_AD3(x) ((u8)(((x) >> 19) & 0x03))
+#define SEC_BA(x) ((u8)(((x) >> 12) & 0x7f))
+
+static s32 ReadArrayUnlock(s32 chan, u32 data, void* rbuf, s32 rlen, s32 mode) {
+ CARDControl* card;
+ BOOL err;
+ u8 cmd[5];
+
+ card = &__CARDBlock[chan];
+ if (!EXISelect(chan, 0, 4)) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ data &= 0xfffff000;
+ memset(cmd, 0, 5);
+ cmd[0] = 0x52;
+ if (mode == 0) {
+ cmd[1] = SEC_AD1(data);
+ cmd[2] = SEC_AD2(data);
+ cmd[3] = SEC_AD3(data);
+ cmd[4] = SEC_BA(data);
+ } else {
+ cmd[1] = (u8)((data & 0xff000000) >> 24);
+ cmd[2] = (u8)((data & 0x00ff0000) >> 16);
+ }
+
+ err = FALSE;
+ err |= !EXIImmEx(chan, cmd, 5, 1);
+ err |= !EXIImmEx(chan, (u8*)card->workArea + (u32)sizeof(CARDID), card->latency, 1);
+ err |= !EXIImmEx(chan, rbuf, rlen, 0);
+ err |= !EXIDeselect(chan);
+
+ return err ? CARD_RESULT_NOCARD : CARD_RESULT_READY;
+}
+
+// Calculate Dummy Read Length, 4-32Bytes
+static s32 DummyLen(void) {
+ u32 tick;
+ u32 wk;
+ s32 tmp;
+ u32 max;
+
+ wk = 1;
+ max = 0;
+ tick = OSGetTick();
+ CARDSrand(tick);
+
+ tmp = CARDRand();
+ tmp &= 0x0000001f;
+ tmp += 1;
+ while ((tmp < 4) && (max < 10)) {
+ tick = OSGetTick();
+ tmp = (s32)(tick << wk);
+ wk++;
+ if (wk > 16) {
+ wk = 1;
+ }
+ CARDSrand((u32)tmp);
+ tmp = CARDRand();
+ tmp &= 0x0000001f;
+ tmp += 1;
+ max++;
+ }
+ if (tmp < 4) {
+ tmp = 4;
+ }
+
+ return tmp;
+}
+
+s32 __CARDUnlock(s32 chan, u8 flashID[12]) {
+ u32 init_val;
+ u32 data;
+
+ s32 dummy;
+ s32 rlen;
+ u32 rshift;
+
+ u8 fsts;
+ u32 wk, wk1;
+ u32 Ans1 = 0;
+ u32 Ans2 = 0;
+ u32* dp;
+ u8 rbuf[64];
+ u32 para1A = 0;
+ u32 para1B = 0;
+ u32 para2A = 0;
+ u32 para2B = 0;
+
+ CARDControl* card;
+ DSPTaskInfo* task;
+ DecodeParameters* param;
+ u8* input;
+ u8* output;
+
+ card = &__CARDBlock[chan];
+ task = &card->task;
+ param = (DecodeParameters*)card->workArea;
+ input = (u8*)((u8*)param + sizeof(DecodeParameters));
+ input = (u8*)OSRoundUp32B(input);
+ output = input + 32;
+
+ fsts = 0;
+ init_val = GetInitVal();
+
+ dummy = DummyLen();
+ rlen = dummy;
+ if (ReadArrayUnlock(chan, init_val, rbuf, rlen, 0) < 0) {
+ return CARD_RESULT_NOCARD;
+ }
+
+ rshift = (u32)(dummy * 8 + 1);
+ wk = exnor_1st(init_val, rshift);
+ wk1 = ~(wk ^ (wk >> 7) ^ (wk >> 15) ^ (wk >> 23));
+ card->scramble = (wk | ((wk1 << 31) & 0x80000000));
+ card->scramble = bitrev(card->scramble);
+ dummy = DummyLen();
+ rlen = 20 + dummy;
+ data = 0;
+ if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
+ return CARD_RESULT_NOCARD;
+ }
+ dp = (u32*)rbuf;
+ para1A = *dp++;
+ para1B = *dp++;
+ Ans1 = *dp++;
+ para2A = *dp++;
+ para2B = *dp++;
+ para1A = (para1A ^ card->scramble);
+ rshift = 32;
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+ para1B = (para1B ^ card->scramble);
+ rshift = 32;
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+ Ans1 ^= card->scramble;
+ rshift = 32;
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+ para2A = (para2A ^ card->scramble);
+ rshift = 32;
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+ para2B = (para2B ^ card->scramble);
+ rshift = (u32)(dummy * 8);
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+ rshift = 32 + 1;
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+
+ *(u32*)&input[0] = para2A;
+ *(u32*)&input[4] = para2B;
+
+ param->inputAddr = input;
+ param->inputLength = 8;
+ param->outputAddr = output;
+ param->aramAddr = 0;
+
+ DCFlushRange(input, 8);
+ DCInvalidateRange(output, 4);
+ DCFlushRange(param, sizeof(DecodeParameters));
+
+ task->priority = 255;
+ task->iram_mmem_addr = (u16*)OSPhysicalToCached(CardData);
+ task->iram_length = 0x160;
+ task->iram_addr = 0;
+ task->dsp_init_vector = 0x10;
+ task->init_cb = InitCallback;
+ task->res_cb = NULL;
+ task->done_cb = DoneCallback;
+ task->req_cb = NULL;
+ DSPAddTask(task);
+
+ dp = (u32*)flashID;
+ *dp++ = para1A;
+ *dp++ = para1B;
+ *dp = Ans1;
+
+ return CARD_RESULT_READY;
+}
+
+static void InitCallback(void* _task) {
+ s32 chan;
+ CARDControl* card;
+ DSPTaskInfo* task;
+ DecodeParameters* param;
+
+ task = _task;
+ for (chan = 0; chan < 2; ++chan) {
+ card = &__CARDBlock[chan];
+ if ((DSPTaskInfo*)&card->task == task) {
+ break;
+ }
+ }
+ param = (DecodeParameters*)card->workArea;
+
+ DSPSendMailToDSP(0xff000000);
+ while (DSPCheckMailToDSP())
+ ;
+
+ DSPSendMailToDSP((u32)param);
+ while (DSPCheckMailToDSP())
+ ;
+}
+
+static void DoneCallback(void* _task) {
+ u8 rbuf[64];
+ u32 data;
+ s32 dummy;
+ s32 rlen;
+ u32 rshift;
+
+ u8 unk;
+ u32 wk, wk1;
+ u32 Ans2;
+
+ s32 chan;
+ CARDControl* card;
+ s32 result;
+ DSPTaskInfo* task;
+ DecodeParameters* param;
+
+ u8* input;
+ u8* output;
+ task = _task;
+ for (chan = 0; chan < 2; ++chan) {
+ card = &__CARDBlock[chan];
+ if ((DSPTaskInfo*)&card->task == task) {
+ break;
+ }
+ }
+
+ param = (DecodeParameters*)card->workArea;
+ input = (u8*)((u8*)param + sizeof(DecodeParameters));
+ input = (u8*)OSRoundUp32B(input);
+ output = input + 32;
+
+ Ans2 = *(u32*)output;
+ dummy = DummyLen();
+ rlen = dummy;
+ data = ((Ans2 ^ card->scramble) & 0xffff0000);
+ if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
+ EXIUnlock(chan);
+ __CARDMountCallback(chan, CARD_RESULT_NOCARD);
+ return;
+ }
+
+ rshift = (u32)((dummy + 4 + card->latency) * 8 + 1);
+ wk = exnor(card->scramble, rshift);
+ wk1 = ~(wk ^ (wk << 7) ^ (wk << 15) ^ (wk << 23));
+ card->scramble = (wk | ((wk1 >> 31) & 0x00000001));
+
+ dummy = DummyLen();
+ rlen = dummy;
+ data = (((Ans2 << 16) ^ card->scramble) & 0xffff0000);
+ if (ReadArrayUnlock(chan, data, rbuf, rlen, 1) < 0) {
+ EXIUnlock(chan);
+ __CARDMountCallback(chan, CARD_RESULT_NOCARD);
+ return;
+ }
+ result = __CARDReadStatus(chan, &unk);
+ if (!EXIProbe(chan)) {
+ EXIUnlock(chan);
+ __CARDMountCallback(chan, CARD_RESULT_NOCARD);
+ return;
+ }
+ if (result == CARD_RESULT_READY && !(unk & 0x40)) {
+ EXIUnlock(chan);
+ result = CARD_RESULT_IOERROR;
+ }
+ __CARDMountCallback(chan, result);
+}
diff --git a/src/Dolphin/card/CARDWrite.c b/src/Dolphin/card/CARDWrite.c
new file mode 100644
index 0000000..69a11b3
--- /dev/null
+++ b/src/Dolphin/card/CARDWrite.c
@@ -0,0 +1,117 @@
+#include <dolphin/card.h>
+#include <dolphin/dsp.h>
+#include <dolphin/dvd.h>
+#include <dolphin/os.h>
+
+#include <dolphin/CARDPriv.h>
+
+static void EraseCallback(s32 chan, s32 result);
+
+static void WriteCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+ u16* fat;
+ CARDDir* dir;
+ CARDDir* ent;
+ CARDFileInfo* fileInfo;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ fileInfo = card->fileInfo;
+ if (fileInfo->length < 0) {
+ result = CARD_RESULT_CANCELED;
+ goto error;
+ }
+
+ fileInfo->length -= card->sectorSize;
+ if (fileInfo->length <= 0) {
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileInfo->fileNo];
+ ent->time = (u32)OSTicksToSeconds(OSGetTime());
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ result = __CARDUpdateDir(chan, callback);
+ } else {
+ fat = __CARDGetFatBlock(card);
+ fileInfo->offset += card->sectorSize;
+ fileInfo->iBlock = fat[fileInfo->iBlock];
+ if (!CARDIsValidBlockNo(card, fileInfo->iBlock)) {
+ result = CARD_RESULT_BROKEN;
+ goto error;
+ }
+ result = __CARDEraseSector(chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback);
+ }
+
+ if (result < 0) {
+ goto error;
+ }
+ return;
+
+error:
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ __CARDPutControlBlock(card, result);
+ callback(chan, result);
+}
+
+static void EraseCallback(s32 chan, s32 result) {
+ CARDControl* card;
+ CARDCallback callback;
+ CARDFileInfo* fileInfo;
+
+ card = &__CARDBlock[chan];
+ if (result < 0) {
+ goto error;
+ }
+
+ fileInfo = card->fileInfo;
+ result = __CARDWrite(chan, card->sectorSize * (u32)fileInfo->iBlock, card->sectorSize,
+ card->buffer, WriteCallback);
+ if (result < 0) {
+ goto error;
+ }
+ return;
+
+error:
+ callback = card->apiCallback;
+ card->apiCallback = 0;
+ __CARDPutControlBlock(card, result);
+ callback(chan, result);
+}
+
+s32 CARDWriteAsync(CARDFileInfo* fileInfo, const void* buf, s32 length, s32 offset,
+ CARDCallback callback) {
+ CARDControl* card;
+ s32 result;
+ CARDDir* dir;
+ CARDDir* ent;
+
+ result = __CARDSeek(fileInfo, length, offset, &card);
+ if (result < 0) {
+ return result;
+ }
+
+ if (OFFSET(offset, card->sectorSize) != 0 || OFFSET(length, card->sectorSize) != 0) {
+ return __CARDPutControlBlock(card, CARD_RESULT_FATAL_ERROR);
+ }
+
+ dir = __CARDGetDirBlock(card);
+ ent = &dir[fileInfo->fileNo];
+ result = __CARDAccess(card, ent);
+ if (result < 0) {
+ return __CARDPutControlBlock(card, result);
+ }
+
+ DCStoreRange((void*)buf, (u32)length);
+ card->apiCallback = callback ? callback : __CARDDefaultApiCallback;
+ card->buffer = (void*)buf;
+ result =
+ __CARDEraseSector(fileInfo->chan, card->sectorSize * (u32)fileInfo->iBlock, EraseCallback);
+ if (result < 0) {
+ __CARDPutControlBlock(card, result);
+ }
+ return result;
+}
diff --git a/src/Dolphin/db.c b/src/Dolphin/db.c
new file mode 100644
index 0000000..bcf8534
--- /dev/null
+++ b/src/Dolphin/db.c
@@ -0,0 +1,43 @@
+#include <dolphin/db.h>
+#include <dolphin/os.h>
+
+DBInterface* __DBInterface = NULL;
+int DBVerbose;
+
+extern void __DBExceptionStart();
+extern void __DBExceptionEnd();
+extern void __DBExceptionSetNumber();
+
+void DBInit(void) {
+ __DBInterface = (DBInterface*)OSPhysicalToCached(OS_DBINTERFACE_ADDR);
+ __DBInterface->ExceptionDestination = (void (*)())OSCachedToPhysical(__DBExceptionDestination);
+ DBVerbose = TRUE;
+}
+
+void __DBExceptionDestinationAux(void) {
+ u32* contextAddr = (void*)0x00C0;
+ OSContext* context = (OSContext*)OSPhysicalToCached(*contextAddr);
+
+ OSReport("DBExceptionDestination\n");
+ OSDumpContext(context);
+ PPCHalt();
+}
+
+/* clang-format off */
+asm void __DBExceptionDestination(void) {
+ nofralloc
+ mfmsr r3
+ ori r3, r3, 0x10|0x20
+ mtmsr r3
+
+ b __DBExceptionDestinationAux
+}
+/* clang-format on */
+
+BOOL __DBIsExceptionMarked(__OSException exception) {
+ u32 mask = 1 << exception;
+
+ return (BOOL)(__DBInterface->exceptionMask & mask);
+}
+
+void DBPrintf(char* format, ...) {}
diff --git a/src/Dolphin/dsp/dsp.c b/src/Dolphin/dsp/dsp.c
new file mode 100644
index 0000000..cab7a39
--- /dev/null
+++ b/src/Dolphin/dsp/dsp.c
@@ -0,0 +1,145 @@
+#include "dolphin/dsp.h"
+#include "dolphin/os.h"
+
+#include "dolphin/dsp_regs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const char* __DSPVersion =
+ "<< Dolphin SDK - DSP\trelease build: Sep 5 2002 05:35:13 (0x2301) >>";
+
+static s32 __DSP_init_flag = 0;
+extern DSPTaskInfo* __DSP_tmp_task;
+extern DSPTaskInfo* __DSP_last_task;
+extern DSPTaskInfo* __DSP_first_task;
+extern DSPTaskInfo* __DSP_curr_task;
+
+extern void __DSPHandler(__OSInterrupt, OSContext*);
+extern void __DSP_debug_printf(const char* fmt, ...);
+extern void __DSP_boot_task(DSPTaskInfo* task);
+
+u32 DSPCheckMailToDSP(void) { return (__DSPRegs[0] >> 0xF) & 1; }
+
+u32 DSPCheckMailFromDSP(void) { return (__DSPRegs[2] >> 0xF) & 1; }
+
+u32 DSPReadMailFromDSP() {
+ u16 reg1;
+ u16 reg2;
+ reg1 = __DSPRegs[2];
+ reg2 = __DSPRegs[3];
+ return reg1 << 16 | reg2;
+}
+
+void DSPSendMailToDSP(u32 mail) {
+ __DSPRegs[0] = mail >> 16;
+ __DSPRegs[1] = mail;
+}
+
+void DSPInit(void) {
+ u32 oldInt;
+ u16 reg;
+ __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Sep 5 2002", "05:35:13");
+
+ if (__DSP_init_flag == 1) {
+ return;
+ }
+ OSRegisterVersion(__DSPVersion);
+ oldInt = OSDisableInterrupts();
+ __OSSetInterruptHandler(7, __DSPHandler);
+ __OSUnmaskInterrupts(0x1000000);
+ reg = __DSPRegs[5];
+ reg = (reg & ~0xA8) | 0x800;
+ __DSPRegs[5] = reg;
+ reg = __DSPRegs[5];
+ reg = reg & ~0xAC;
+ __DSPRegs[5] = reg;
+ __DSP_tmp_task = 0;
+ __DSP_curr_task = 0;
+ __DSP_last_task = 0;
+ __DSP_first_task = 0;
+ __DSP_init_flag = 1;
+ OSRestoreInterrupts(oldInt);
+}
+
+void DSPReset(void) {
+ u16 reg;
+ u32 oldInt;
+ oldInt = OSDisableInterrupts();
+ reg = __DSPRegs[5];
+ __DSPRegs[5] = (reg & ~0xA8) | 0x801;
+ __DSP_init_flag = 0;
+ OSRestoreInterrupts(oldInt);
+}
+
+void DSPHalt(void) {
+ u16 reg;
+ u32 oldInt;
+ oldInt = OSDisableInterrupts();
+ reg = __DSPRegs[5];
+ __DSPRegs[5] = (reg & ~0xA8) | 4;
+ OSRestoreInterrupts(oldInt);
+}
+
+u32 DSPGetDMAStatus(void) { return __DSPRegs[5] & 0x200; }
+
+#ifdef FULL_FRANK
+DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
+ u32 oldInt;
+ oldInt = OSDisableInterrupts();
+ __DSP_insert_task(task);
+ task->state = 0;
+ task->flags = 1;
+ OSRestoreInterrupts(oldInt);
+ if (task == __DSP_first_task) {
+ __DSP_boot_task(task);
+ }
+
+ return task;
+}
+#else
+#pragma push
+#include "__ppc_eabi_linker.h"
+/* clang-format off */
+#pragma optimization_level 0
+#pragma optimizewithasm off
+extern void __DSP_insert_task(DSPTaskInfo* task);
+asm DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ bl OSDisableInterrupts
+ addi r31, r3, 0
+ addi r3, r30, 0
+ bl __DSP_insert_task
+ li r0, 0
+ stw r0, 0(r30)
+ li r0, 1
+ addi r3, r31, 0
+ stw r0, 8(r30)
+ bl OSRestoreInterrupts
+ lwz r0, __DSP_first_task
+ cmplw r30, r0
+ bne lbl_8036FBB4
+ mr r3, r30
+ bl __DSP_boot_task
+lbl_8036FBB4:
+ mr r3, r30
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+#endif
+/* clang-format on */
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/Dolphin/dsp/dsp_debug.c b/src/Dolphin/dsp/dsp_debug.c
new file mode 100644
index 0000000..22455a3
--- /dev/null
+++ b/src/Dolphin/dsp/dsp_debug.c
@@ -0,0 +1,5 @@
+#include "types.h"
+
+void __DSP_debug_printf(const char* fmt, ...) {
+ // UNUSED(fmt);
+}
diff --git a/src/Dolphin/dsp/dsp_task.c b/src/Dolphin/dsp/dsp_task.c
new file mode 100644
index 0000000..2fe7f15
--- /dev/null
+++ b/src/Dolphin/dsp/dsp_task.c
@@ -0,0 +1,389 @@
+#include "dolphin/dsp.h"
+#include "dolphin/dsp_regs.h"
+
+DSPTaskInfo* __DSP_curr_task;
+DSPTaskInfo* __DSP_first_task;
+DSPTaskInfo* __DSP_last_task;
+DSPTaskInfo* __DSP_tmp_task;
+DSPTaskInfo* __DSP_rude_task;
+
+BOOL __DSP_rude_task_pending;
+
+void __DSPHandler(__OSInterrupt, OSContext* context) {
+ DSPTaskInfo* tmp_task;
+ OSContext exceptionContext;
+ u16 tmp;
+ u32 mail;
+
+ tmp = __DSPRegs[5];
+ tmp = (u16)(tmp & ~0x28) | 0x80;
+ __DSPRegs[5] = tmp;
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(&exceptionContext);
+
+ while (!DSPCheckMailFromDSP())
+ ;
+ mail = DSPReadMailFromDSP();
+
+ if ((__DSP_curr_task->flags & DSP_TASK_FLAG_CANCEL) && (mail == 0xDCD10002)) {
+ mail = 0xDCD10003;
+ }
+
+ switch (mail) {
+ case 0xDCD10000:
+ __DSP_curr_task->state = DSP_TASK_STATE_RUN;
+
+ if (__DSP_curr_task->init_cb) {
+ (*(__DSP_curr_task->init_cb))((void*)(__DSP_curr_task));
+ }
+ break;
+ case 0xDCD10001:
+ __DSP_curr_task->state = DSP_TASK_STATE_RUN;
+ if (__DSP_curr_task->res_cb) {
+ (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task));
+ }
+ break;
+ case 0xDCD10002:
+ if (__DSP_rude_task_pending) {
+
+ if (__DSP_curr_task == __DSP_rude_task) {
+ DSPSendMailToDSP(0xCDD10003);
+ while (DSPCheckMailToDSP()) {
+ }
+
+ __DSP_rude_task = NULL;
+ __DSP_rude_task_pending = FALSE;
+
+ if (__DSP_curr_task->res_cb) {
+ (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task));
+ }
+
+ break;
+ } else {
+ DSPSendMailToDSP(0xCDD10001);
+ while (DSPCheckMailToDSP())
+ ;
+ __DSP_exec_task(__DSP_curr_task, __DSP_rude_task);
+
+ __DSP_curr_task->state = DSP_TASK_STATE_YIELD;
+ __DSP_curr_task = __DSP_rude_task;
+
+ __DSP_rude_task = NULL;
+ __DSP_rude_task_pending = FALSE;
+
+ break;
+ }
+ }
+
+ if (__DSP_curr_task->next == NULL) {
+
+ if (__DSP_curr_task == __DSP_first_task) {
+
+ DSPSendMailToDSP(0xCDD10003);
+ while (DSPCheckMailToDSP())
+ ;
+
+ if (__DSP_curr_task->res_cb) {
+ (*(__DSP_curr_task->res_cb))((void*)(__DSP_curr_task));
+ }
+
+ } else {
+ DSPSendMailToDSP(0xCDD10001);
+ while (DSPCheckMailToDSP()) {
+ }
+
+ __DSP_exec_task(__DSP_curr_task, __DSP_first_task);
+
+ __DSP_curr_task->state = DSP_TASK_STATE_YIELD;
+ __DSP_curr_task = __DSP_first_task;
+ }
+
+ } else {
+
+ DSPSendMailToDSP(0xCDD10001);
+ while (DSPCheckMailToDSP()) {
+ }
+
+ __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next);
+
+ __DSP_curr_task->state = DSP_TASK_STATE_YIELD;
+ __DSP_curr_task = __DSP_curr_task->next;
+ }
+ break;
+ case 0xDCD10003:
+ if (__DSP_rude_task_pending) {
+
+ if (__DSP_curr_task->done_cb) {
+ (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task));
+ }
+
+ DSPSendMailToDSP(0xCDD10001);
+ while (DSPCheckMailToDSP())
+ ;
+
+ __DSP_exec_task(NULL, __DSP_rude_task);
+
+ __DSP_remove_task(__DSP_curr_task);
+ __DSP_curr_task = __DSP_rude_task;
+
+ __DSP_rude_task = NULL;
+ __DSP_rude_task_pending = FALSE;
+
+ break;
+ }
+
+ if (__DSP_curr_task->next == NULL) {
+
+ if (__DSP_curr_task == __DSP_first_task) {
+
+ if (__DSP_curr_task->done_cb) {
+ (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task));
+ }
+
+ DSPSendMailToDSP(0xCDD10002);
+ while (DSPCheckMailToDSP())
+ ;
+
+ __DSP_curr_task->state = DSP_TASK_STATE_DONE;
+
+ __DSP_remove_task(__DSP_curr_task);
+
+ } else {
+
+ if (__DSP_curr_task->done_cb) {
+ (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task));
+ }
+
+ DSPSendMailToDSP(0xCDD10001);
+ while (DSPCheckMailToDSP())
+ ;
+
+ __DSP_curr_task->state = DSP_TASK_STATE_DONE;
+ __DSP_exec_task(NULL, __DSP_first_task);
+
+ __DSP_curr_task = __DSP_first_task;
+ __DSP_remove_task(__DSP_last_task);
+ }
+
+ } else {
+ if (__DSP_curr_task->done_cb) {
+ (*(__DSP_curr_task->done_cb))((void*)(__DSP_curr_task));
+ }
+ DSPSendMailToDSP(0xCDD10001);
+ while (DSPCheckMailToDSP())
+ ;
+
+ __DSP_curr_task->state = DSP_TASK_STATE_DONE;
+ __DSP_exec_task(NULL, __DSP_curr_task->next);
+
+ __DSP_curr_task = __DSP_curr_task->next;
+ __DSP_remove_task(__DSP_curr_task->prev);
+ }
+ break;
+
+ case 0xDCD10004:
+
+ if (__DSP_curr_task->req_cb) {
+ (*(__DSP_curr_task->req_cb))((void*)(__DSP_curr_task));
+ }
+ break;
+ default:
+ break;
+ }
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(context);
+}
+
+void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next) {
+ if (curr) {
+ DSPSendMailToDSP((u32)(curr->dram_mmem_addr));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(curr->dram_length));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(curr->dram_addr));
+ while (DSPCheckMailToDSP())
+ ;
+ } else {
+
+ DSPSendMailToDSP((u32)(0));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(0));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(0));
+ while (DSPCheckMailToDSP())
+ ;
+ }
+
+ DSPSendMailToDSP((u32)(next->iram_mmem_addr));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(next->iram_length));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(next->iram_addr));
+ while (DSPCheckMailToDSP())
+ ;
+
+ if (DSP_TASK_STATE_INIT == next->state) {
+ DSPSendMailToDSP((u32)(next->dsp_init_vector));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(0));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(0));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(0));
+ while (DSPCheckMailToDSP())
+ ;
+ } else {
+ DSPSendMailToDSP((u32)(next->dsp_resume_vector));
+ while (DSPCheckMailToDSP())
+ ;
+ DSPSendMailToDSP((u32)(next->dram_mmem_addr));
+ while (DSPCheckMailToDSP())
+ ;
+
+ DSPSendMailToDSP((u32)(next->dram_length));
+ while (DSPCheckMailToDSP())
+ ;
+
+ DSPSendMailToDSP((u32)(next->dram_addr));
+ while (DSPCheckMailToDSP())
+ ;
+ }
+}
+
+
+#define MSG_BASE 0x80F30000
+void __DSP_boot_task(DSPTaskInfo* task) {
+
+ volatile u32 mail;
+
+ while (!DSPCheckMailFromDSP())
+ ;
+
+ mail = DSPReadMailFromDSP();
+
+ DSPSendMailToDSP(MSG_BASE | 0xA001);
+ while (DSPCheckMailToDSP()) {
+ }
+ DSPSendMailToDSP((u32)(task->iram_mmem_addr));
+ while (DSPCheckMailToDSP()) {
+ }
+
+ DSPSendMailToDSP(MSG_BASE | 0xC002);
+ while (DSPCheckMailToDSP()) {
+ }
+ DSPSendMailToDSP((u32)(task->iram_addr & 0xffff));
+ while (DSPCheckMailToDSP()) {
+ }
+
+ DSPSendMailToDSP(MSG_BASE | 0xA002);
+ while (DSPCheckMailToDSP()) {
+ }
+ DSPSendMailToDSP(task->iram_length);
+ while (DSPCheckMailToDSP()) {
+ }
+
+ DSPSendMailToDSP(MSG_BASE | 0xB002);
+ while (DSPCheckMailToDSP()) {
+ }
+ DSPSendMailToDSP(0x00000000);
+ while (DSPCheckMailToDSP()) {
+ }
+
+ DSPSendMailToDSP(MSG_BASE | 0xD001);
+ while (DSPCheckMailToDSP()) {
+ }
+ DSPSendMailToDSP((u32)(0xffff & task->dsp_init_vector));
+ while (DSPCheckMailToDSP()) {
+ }
+
+ __DSP_debug_printf("DSP is booting task: 0x%08X\n", task);
+ __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)(task->iram_mmem_addr));
+ __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", (u32)(task->iram_addr));
+ __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", (u32)(task->iram_length));
+ __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", (u32)(task->dram_length));
+ __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", (u32)(task->dsp_init_vector));
+}
+
+void __DSP_insert_task(DSPTaskInfo* task) {
+
+ DSPTaskInfo* temp;
+
+ if (__DSP_first_task == NULL) {
+ __DSP_first_task = __DSP_last_task = __DSP_curr_task = task;
+ task->next = task->prev = NULL;
+ } else {
+ temp = __DSP_first_task;
+
+ while (temp) {
+ if (task->priority < temp->priority) {
+ task->prev = temp->prev;
+ temp->prev = task;
+ task->next = temp;
+ if (task->prev == NULL) {
+ __DSP_first_task = task;
+ } else {
+ (task->prev)->next = task;
+ }
+ break;
+ }
+ temp = temp->next;
+ }
+
+ if (temp == NULL) {
+ __DSP_last_task->next = task;
+ task->next = NULL;
+ task->prev = __DSP_last_task;
+ __DSP_last_task = task;
+ }
+ }
+}
+
+void __DSP_add_task(DSPTaskInfo* task) {
+ if (__DSP_last_task == NULL) {
+ __DSP_first_task = __DSP_last_task = __DSP_curr_task = task;
+ task->next = task->prev = NULL;
+ } else {
+ __DSP_last_task->next = task;
+ task->next = NULL;
+ task->prev = __DSP_last_task;
+ __DSP_last_task = task;
+ }
+
+ task->state = DSP_TASK_STATE_INIT;
+
+ __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", task);
+}
+
+void __DSP_remove_task(DSPTaskInfo* task) {
+
+ task->flags = DSP_TASK_FLAG_CLEARALL;
+ task->state = DSP_TASK_STATE_DONE;
+
+ if (__DSP_first_task == task) {
+ if (task->next) {
+ __DSP_first_task = (task->next);
+ task->next->prev = NULL;
+ } else {
+ __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL;
+ }
+ } else if (__DSP_last_task == task) {
+ __DSP_last_task = (task->prev);
+ task->prev->next = NULL;
+ __DSP_curr_task = __DSP_first_task;
+
+ } else {
+ __DSP_curr_task = task->next;
+ task->prev->next = task->next;
+ task->next->prev = task->prev;
+ }
+}
diff --git a/src/Dolphin/dtk.c b/src/Dolphin/dtk.c
new file mode 100644
index 0000000..b59a850
--- /dev/null
+++ b/src/Dolphin/dtk.c
@@ -0,0 +1,357 @@
+#include <dolphin/ai.h>
+#include <dolphin/dtk.h>
+
+static DVDCommandBlock __block_for_run_callback;
+static DVDCommandBlock __block_for_prep_callback;
+static DVDCommandBlock __block_for_stream_status;
+static DVDCommandBlock __block_for_ais_isr;
+static DVDCommandBlock __block_for_flushtracks;
+static DVDCommandBlock __block_for_set_state;
+static DVDCommandBlock __block_for_next_track;
+
+static DTKTrack* __DTKCurrentTrack;
+static DTKTrack* __DTKPlayListHead;
+static DTKTrack* __DTKPlayListTail;
+static vu32 __DTKState;
+static vu32 __DTKTempState;
+static vu32 __DTKRepeatMode;
+static vu32 __DTKPosition;
+static vu32 __DTKInterruptFrequency;
+static vu8 __DTKVolumeL;
+static vu8 __DTKVolumeR;
+static volatile u32 __DTKShutdownFlag;
+static volatile u32 __DTKTrackEnded;
+static DTKFlushCallback __DTKFlushCallback;
+
+static void __DTKStartAi() {
+ AISetStreamVolLeft(__DTKVolumeL);
+ AISetStreamVolRight(__DTKVolumeR);
+ AIResetStreamSampleCount();
+ AISetStreamTrigger(__DTKInterruptFrequency);
+ AISetStreamPlayState(1);
+}
+
+static void __DTKStopAi() {
+ AISetStreamVolLeft(0);
+ AISetStreamVolRight(0);
+ AISetStreamPlayState(0);
+}
+
+static void __DTKCheckUserCallback(DTKTrack* track, u32 event) {
+ if (track == NULL) {
+ return;
+ }
+
+ if (track->callback != NULL && (track->eventMask & event) != 0) {
+ track->callback(track->eventMask & event);
+ }
+}
+
+static void __DTKForward() {
+ BOOL enabled;
+ enabled = OSDisableInterrupts();
+ if (__DTKCurrentTrack != NULL && __DTKCurrentTrack->next != nullptr) {
+ __DTKCurrentTrack = __DTKCurrentTrack->next;
+ }
+
+ OSRestoreInterrupts(enabled);
+}
+
+static void __DTKBackward() {
+ BOOL enabled;
+ enabled = OSDisableInterrupts();
+ if (__DTKCurrentTrack != NULL && __DTKCurrentTrack->prev != nullptr) {
+ __DTKCurrentTrack = __DTKCurrentTrack->prev;
+ }
+
+ OSRestoreInterrupts(enabled);
+}
+
+static void __DTKCallbackForStreamStatus(s32 result, DVDCommandBlock* block) {
+ if ((u8)result) {
+ return;
+ }
+ __DTKTrackEnded = TRUE;
+ __DTKPosition = 0;
+}
+
+static void __DTKCallbackForRun(s32 result, DVDFileInfo* fileInfo) {
+ __DTKStartAi();
+ DVDStopStreamAtEndAsync(&__block_for_run_callback, NULL);
+ __DTKState = 1;
+ __DTKCheckUserCallback(__DTKCurrentTrack, 1);
+}
+
+static void __DTKCallbackForPreparePaused(s32 result, DVDFileInfo* fileInfo) {
+ __DTKStopAi();
+ DVDStopStreamAtEndAsync(&__block_for_prep_callback, NULL);
+ __DTKState = 2;
+ __DTKCheckUserCallback(__DTKCurrentTrack, 32);
+}
+
+static void __DTKPrepareCurrentTrack(DVDCallback callback) {
+ DVDPrepareStreamAsync(&__DTKCurrentTrack->dvdFileInfo, 0, 0, callback);
+}
+static void __DTKCallbackForPlaylist(s32 result, DVDCommandBlock* block) {
+ __DTKPosition = result;
+
+ if (__DTKTrackEnded != FALSE) {
+ __DTKTrackEnded = FALSE;
+ __DTKCheckUserCallback(__DTKCurrentTrack, 16);
+ __DTKState = 3;
+ switch (__DTKRepeatMode) {
+ case 0:
+ if (__DTKCurrentTrack == NULL) {
+ break;
+ }
+
+ if (__DTKCurrentTrack->next != NULL) {
+ __DTKCurrentTrack = __DTKCurrentTrack->next;
+ __DTKStopAi();
+ __DTKPrepareCurrentTrack(__DTKCallbackForRun);
+ } else {
+ __DTKCurrentTrack = __DTKPlayListHead;
+ __DTKStopAi();
+ __DTKState = 0;
+ }
+ break;
+ case 1: {
+ if (__DTKCurrentTrack == NULL) {
+ break;
+ }
+ if (__DTKCurrentTrack->next != NULL) {
+ __DTKCurrentTrack = __DTKCurrentTrack->next;
+ __DTKStopAi();
+ __DTKPrepareCurrentTrack(__DTKCallbackForRun);
+ } else {
+ __DTKCurrentTrack = __DTKPlayListHead;
+ __DTKStopAi();
+ __DTKPrepareCurrentTrack(__DTKCallbackForRun);
+ }
+ break;
+ }
+ case 2: {
+ if (__DTKCurrentTrack == NULL) {
+ break;
+ }
+
+ __DTKStopAi();
+ __DTKPrepareCurrentTrack(__DTKCallbackForRun);
+ break;
+ }
+ }
+ return;
+ }
+
+ DVDGetStreamErrorStatusAsync(&__block_for_stream_status, __DTKCallbackForStreamStatus);
+}
+
+static void __DTKCallbackForAIInterrupt(u32 result) {
+ AISetStreamTrigger(result + __DTKInterruptFrequency);
+
+ if (__DTKCurrentTrack != NULL) {
+ DVDGetStreamPlayAddrAsync(&__block_for_ais_isr, __DTKCallbackForPlaylist);
+ }
+}
+
+static void __DTKCallbackForFlush(s32 result, DVDCommandBlock* block) {
+ DTKTrack* iter;
+ AISetStreamPlayState(0);
+
+ for (iter = __DTKPlayListHead; iter != NULL; iter = iter->next) {
+ DVDClose(&iter->dvdFileInfo);
+ }
+
+ __DTKPlayListHead = NULL;
+ __DTKPlayListTail = NULL;
+ __DTKCurrentTrack = NULL;
+ __DTKState = 0;
+ if (__DTKFlushCallback != NULL) {
+ __DTKFlushCallback();
+ __DTKFlushCallback = NULL;
+ }
+
+ __DTKState = 0;
+ __DTKShutdownFlag = 0;
+}
+
+static void __DTKCallbackForStop() {
+ __DTKCheckUserCallback(__DTKCurrentTrack, 2);
+ __DTKState = 0;
+}
+
+static void __DTKCallbackForNextTrack() {
+ AISetStreamPlayState(0);
+ __DTKForward();
+ __DTKState = 0;
+ DTKSetState(__DTKTempState);
+}
+
+static void __DTKCallbackForPrevTrack() {
+ AISetStreamPlayState(0);
+ __DTKBackward();
+ __DTKState = 0;
+ DTKSetState(__DTKTempState);
+}
+
+void DTKInit() {
+ __DTKCurrentTrack = NULL;
+ __DTKPlayListHead = NULL;
+ __DTKPlayListTail = NULL;
+ __DTKState = 0;
+ __DTKRepeatMode = 0;
+ __DTKPosition = 0;
+ __DTKInterruptFrequency = 48000;
+ __DTKVolumeL = 255;
+ __DTKVolumeR = 255;
+ AISetStreamVolLeft(0);
+ AISetStreamVolRight(0);
+ AIRegisterStreamCallback(__DTKCallbackForAIInterrupt);
+ AIResetStreamSampleCount();
+ AISetStreamPlayState(0);
+}
+
+u32 DTKQueueTrack(char* fileName, DTKTrack* track, u32 eventMask, DTKCallback callback) {
+ BOOL enabled;
+ u32 prepareTrack = FALSE;
+ if (DVDOpen(fileName, &track->dvdFileInfo) == 0) {
+ return 1;
+ }
+
+ enabled = OSDisableInterrupts();
+ track->fileName = fileName;
+ track->eventMask = eventMask;
+ track->callback = callback;
+
+ if (__DTKPlayListHead == NULL) {
+ __DTKPlayListHead = track;
+ __DTKPlayListTail = track;
+ track->prev = NULL;
+ track->next = NULL;
+ if (__DTKState == 1) {
+ prepareTrack = TRUE;
+ }
+ } else {
+ __DTKPlayListTail->next = track;
+ track->prev = __DTKPlayListTail;
+ __DTKPlayListTail = track;
+ track->next = NULL;
+ }
+
+ if (__DTKCurrentTrack == NULL) {
+ __DTKCurrentTrack = track;
+ }
+
+ OSRestoreInterrupts(enabled);
+ __DTKCheckUserCallback(track, 8);
+ if (prepareTrack != 0) {
+ __DTKState = 3;
+ __DTKPrepareCurrentTrack(__DTKCallbackForRun);
+ }
+
+ return 0;
+}
+
+void DTKFlushTracks(DTKFlushCallback callback) {
+ u32 oldState;
+ if (__DTKState != 3) {
+ oldState = __DTKState;
+ __DTKState = 3;
+ __DTKFlushCallback = callback;
+ if (oldState == 1) {
+ DVDCancelStreamAsync(&__block_for_flushtracks, __DTKCallbackForFlush);
+ } else {
+ __DTKCallbackForFlush(0, NULL);
+ }
+ }
+}
+
+void DTKSetSampleRate(u32 rate) {}
+
+void DTKSetRepeatMode(u32 repeat) { __DTKRepeatMode = repeat; }
+
+void DTKSetState(u32 state) {
+ if (__DTKState == state || __DTKState == 3) {
+ return;
+ }
+ switch (state) {
+ case 0: {
+ if (__DTKCurrentTrack == NULL) {
+ break;
+ }
+
+ __DTKState = 3;
+ AISetStreamVolLeft(0);
+ AISetStreamVolRight(0);
+ AISetStreamPlayState(0);
+ DVDCancelStreamAsync(&__block_for_set_state, __DTKCallbackForStop);
+ break;
+ }
+ case 1: {
+ if (__DTKState == 2) {
+ __DTKStartAi();
+ __DTKState = 1;
+ if (__DTKCurrentTrack != NULL) {
+ __DTKCheckUserCallback(__DTKCurrentTrack, 1);
+ }
+ } else if (__DTKCurrentTrack != NULL) {
+ __DTKState = 3;
+ __DTKPrepareCurrentTrack(__DTKCallbackForRun);
+
+ } else {
+ __DTKState = 1;
+ }
+
+ __DTKTrackEnded = 0;
+ break;
+ }
+ case 4: {
+ if (__DTKState != 0) {
+ break;
+ }
+
+ if (__DTKCurrentTrack != NULL) {
+ __DTKState = 3;
+ __DTKPrepareCurrentTrack(__DTKCallbackForPreparePaused);
+ }
+
+ __DTKTrackEnded = FALSE;
+ break;
+ }
+ case 2: {
+ AISetStreamPlayState(0);
+ if (__DTKState == 1) {
+ __DTKState = 2;
+ }
+ __DTKCheckUserCallback(__DTKCurrentTrack, 4);
+ break;
+ }
+ }
+}
+
+void DTKNextTrack() {
+ if (__DTKState != 3 && __DTKCurrentTrack != NULL) {
+ __DTKTempState = __DTKState;
+ __DTKState = 3;
+ if (__DTKTempState == 1) {
+ AISetStreamVolLeft(0);
+ AISetStreamVolRight(0);
+ DVDCancelStreamAsync(&__block_for_next_track, __DTKCallbackForNextTrack);
+
+ } else {
+ __DTKForward();
+ __DTKState = __DTKTempState;
+ }
+ }
+}
+
+u32 DTKGetState() { return __DTKState; }
+
+void DTKSetVolume(u8 left, u8 right) {
+ __DTKVolumeL = left;
+ __DTKVolumeR = right;
+ if (__DTKState == 1) {
+ AISetStreamVolLeft(left);
+ AISetStreamVolRight(right);
+ }
+}
diff --git a/src/Dolphin/dvd/dvd.c b/src/Dolphin/dvd/dvd.c
new file mode 100644
index 0000000..65c67f6
--- /dev/null
+++ b/src/Dolphin/dvd/dvd.c
@@ -0,0 +1,1389 @@
+#include <dolphin/DVDPriv.h>
+#include <dolphin/dvd.h>
+#include <dolphin/dvd_regs.h>
+#include <dolphin/os.h>
+#include <dolphin/os/OSBootInfo.h>
+
+const char* __DVDVersion = "<< Dolphin SDK - DVD\trelease build: Sep 5 2002 05:34:06 (0x2301) >>";
+
+typedef void (*stateFunc)(DVDCommandBlock* block);
+stateFunc LastState;
+
+extern OSThreadQueue __DVDThreadQueue;
+
+static DVDBB2 BB2 ATTRIBUTE_ALIGN(32);
+static DVDDiskID CurrDiskID ATTRIBUTE_ALIGN(32);
+static DVDCommandBlock* executing;
+static DVDDiskID* IDShouldBe;
+static OSBootInfo* bootInfo;
+static BOOL autoInvalidation = TRUE;
+static volatile BOOL PauseFlag = FALSE;
+static volatile BOOL PausingFlag = FALSE;
+static volatile BOOL AutoFinishing = FALSE;
+static volatile BOOL FatalErrorFlag = FALSE;
+static vu32 CurrCommand;
+static vu32 Canceling = FALSE;
+static DVDCBCallback CancelCallback;
+static vu32 ResumeFromHere = 0;
+static vu32 CancelLastError;
+static vu32 LastError;
+static vs32 NumInternalRetry = 0;
+static volatile BOOL ResetRequired;
+static volatile BOOL CancelAllSyncComplete = FALSE;
+static volatile BOOL FirstTimeInBootrom = FALSE;
+
+static DVDCommandBlock DummyCommandBlock;
+static OSAlarm ResetAlarm;
+
+static BOOL DVDInitialized = FALSE;
+
+/* States */
+static void stateReadingFST();
+static void stateTimeout();
+static void stateGettingError();
+static void stateGoToRetry();
+static void stateCheckID();
+static void stateCheckID3();
+static void stateCheckID2a();
+static void stateCheckID2();
+static void stateCoverClosed();
+static void stateCoverClosed_CMD();
+static void stateCoverOpen();
+static void stateMotorStopped();
+static void stateReady();
+static void stateBusy();
+
+/* Callbacks */
+static void cbForStateReadingFST(u32 intType);
+static void cbForStateError(u32 intType);
+static void cbForStateGettingError(u32 intType);
+static void cbForUnrecoveredError(u32 intType);
+static void cbForUnrecoveredErrorRetry(u32 intType);
+static void cbForStateGoToRetry(u32 intType);
+static void cbForStateCheckID2a(u32 intType);
+static void cbForStateCheckID1(u32 intType);
+static void cbForStateCheckID2(u32 intType);
+static void cbForStateCheckID3(u32 intType);
+static void cbForStateCoverClosed(u32 intType);
+static void cbForStateMotorStopped(u32 intType);
+static void cbForStateBusy(u32 intType);
+static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block);
+static void cbForCancelSync(s32 result, DVDCommandBlock* block);
+static void cbForCancelAllSync(s32 result, DVDCommandBlock* block);
+
+static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb);
+
+static DVDOptionalCommandChecker checkOptionalCommand = defaultOptionalCommandChecker;
+
+extern void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context);
+
+static void defaultOptionalCommandChecker(DVDCommandBlock* block, DVDLowCallback cb) {}
+
+void DVDInit() {
+ if (DVDInitialized) {
+ return;
+ }
+
+ OSRegisterVersion(__DVDVersion);
+ DVDInitialized = TRUE;
+ __DVDFSInit();
+ __DVDClearWaitingQueue();
+ __DVDInitWA();
+ bootInfo = (OSBootInfo*)OSPhysicalToCached(0x0000);
+ IDShouldBe = &(bootInfo->DVDDiskID);
+ __OSSetInterruptHandler(21, __DVDInterruptHandler);
+ __OSUnmaskInterrupts(0x400);
+ OSInitThreadQueue(&__DVDThreadQueue);
+ __DIRegs[0] = 0x2a;
+ __DIRegs[1] = 0;
+ if (bootInfo->magic == 0xE5207C22) {
+ OSReport("load fst\n");
+ __fstLoad();
+ } else if (bootInfo->magic != 0xD15EA5E) {
+ FirstTimeInBootrom = TRUE;
+ }
+}
+
+static void stateReadingFST() {
+ LastState = (stateFunc)stateReadingFST;
+
+ if (bootInfo->FSTMaxLength < BB2.FSTLength) {
+ OSPanic("dvd.c", 630, "DVDChangeDisk(): FST in the new disc is too big. ");
+ }
+
+ DVDLowRead(bootInfo->FSTLocation, OSRoundUp32B(BB2.FSTLength), BB2.FSTPosition,
+ cbForStateReadingFST);
+}
+
+static void cbForStateReadingFST(u32 intType) {
+ DVDCommandBlock* finished;
+
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 1) {
+ NumInternalRetry = 0;
+ __DVDFSInit();
+ finished = executing;
+ executing = &DummyCommandBlock;
+ finished->state = 0;
+ if (finished->callback) {
+ (finished->callback)(0, finished);
+ }
+
+ stateReady();
+
+ } else {
+
+ stateGettingError();
+ }
+}
+
+inline static void stateError(u32 error) {
+ __DVDStoreErrorCode(error);
+ DVDLowStopMotor(cbForStateError);
+}
+
+static void cbForStateError(u32 intType) {
+ DVDCommandBlock* finished;
+
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ __DVDPrintFatalMessage();
+
+ FatalErrorFlag = TRUE;
+ finished = executing;
+ executing = &DummyCommandBlock;
+ if (finished->callback) {
+ (finished->callback)(-1, finished);
+ }
+
+ if (Canceling) {
+ Canceling = FALSE;
+ if (CancelCallback)
+ (CancelCallback)(0, finished);
+ }
+
+ stateReady();
+
+ return;
+}
+
+static void stateTimeout() {
+ __DVDStoreErrorCode(0x1234568);
+ DVDReset();
+ cbForStateError(0);
+}
+
+static void stateGettingError() { DVDLowRequestError(cbForStateGettingError); }
+
+static u32 CategorizeError(u32 error) {
+ if (error == 0x20400) {
+ LastError = error;
+ return 1;
+ }
+
+ error &= 0xffffff;
+
+ if ((error == 0x62800) || (error == 0x23a00) || (error == 0xb5a01)) {
+ return 0;
+ }
+
+ ++NumInternalRetry;
+ if (NumInternalRetry == 2) {
+ if (error == LastError) {
+ LastError = error;
+ return 1;
+ } else {
+ LastError = error;
+ return 2;
+ }
+ } else {
+ LastError = error;
+
+ if ((error == 0x31100) || (executing->command == 5)) {
+ return 2;
+ } else {
+ return 3;
+ }
+ }
+}
+
+inline static BOOL CheckCancel(u32 resume) {
+ DVDCommandBlock* finished;
+
+ if (Canceling) {
+ ResumeFromHere = resume;
+ Canceling = FALSE;
+
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 10;
+ if (finished->callback)
+ (*finished->callback)(-3, finished);
+ if (CancelCallback)
+ (CancelCallback)(0, finished);
+ stateReady();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void cbForStateGettingError(u32 intType) {
+ u32 error;
+ u32 status;
+ u32 errorCategory;
+ u32 resume;
+
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 2) {
+ executing->state = -1;
+ stateError(0x1234567);
+ return;
+ }
+
+ error = __DIRegs[8];
+ status = error & 0xff000000;
+
+ errorCategory = CategorizeError(error);
+
+ if (errorCategory == 1) {
+ executing->state = -1;
+ stateError(error);
+ return;
+ }
+
+ if ((errorCategory == 2) || (errorCategory == 3)) {
+ resume = 0;
+ } else {
+ if (status == 0x01000000)
+ resume = 4;
+ else if (status == 0x02000000)
+ resume = 6;
+ else if (status == 0x03000000)
+ resume = 3;
+ else
+ resume = 5;
+ }
+
+ if (CheckCancel(resume))
+ return;
+
+ if (errorCategory == 2) {
+ __DVDStoreErrorCode(error);
+ stateGoToRetry();
+ return;
+ }
+
+ if (errorCategory == 3) {
+ if ((error & 0x00ffffff) == 0x00031100) {
+ DVDLowSeek(executing->offset, cbForUnrecoveredError);
+ } else {
+ LastState(executing);
+ }
+ return;
+ }
+
+ if (status == 0x01000000) {
+ executing->state = 5;
+ stateMotorStopped();
+ return;
+ } else if (status == 0x02000000) {
+ executing->state = 3;
+ stateCoverClosed();
+ return;
+ } else if (status == 0x03000000) {
+ executing->state = 4;
+ stateMotorStopped();
+ return;
+ } else {
+ executing->state = -1;
+ stateError(0x1234567);
+ return;
+ }
+}
+
+static void cbForUnrecoveredError(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 1) {
+ stateGoToRetry();
+ return;
+ }
+
+ DVDLowRequestError(cbForUnrecoveredErrorRetry);
+}
+
+static void cbForUnrecoveredErrorRetry(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+ executing->state = -1;
+
+ if (intType & 2) {
+ __DVDStoreErrorCode(0x1234567);
+ DVDLowStopMotor(cbForStateError);
+ return;
+ }
+
+ __DVDStoreErrorCode(__DIRegs[8]);
+ DVDLowStopMotor(cbForStateError);
+}
+
+static void stateGoToRetry() { DVDLowStopMotor(cbForStateGoToRetry); }
+
+static void cbForStateGoToRetry(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 2) {
+ executing->state = -1;
+ stateError(0x1234567);
+ return;
+ }
+
+ NumInternalRetry = 0;
+
+ if ((CurrCommand == 4) || (CurrCommand == 5) || (CurrCommand == 13) || (CurrCommand == 15)) {
+ ResetRequired = TRUE;
+ }
+
+ if (!CheckCancel(2)) {
+ executing->state = 11;
+ stateMotorStopped();
+ }
+}
+
+static void stateCheckID() {
+ switch (CurrCommand) {
+ case 3:
+ if (DVDCompareDiskID(&CurrDiskID, executing->id)) {
+ memcpy(IDShouldBe, &CurrDiskID, sizeof(DVDDiskID));
+
+ executing->state = 1;
+ DCInvalidateRange(&BB2, sizeof(DVDBB2));
+ LastState = stateCheckID2a;
+ stateCheckID2a(executing);
+ return;
+ } else {
+ DVDLowStopMotor(cbForStateCheckID1);
+ }
+ break;
+
+ default:
+ if (memcmp(&CurrDiskID, IDShouldBe, sizeof(DVDDiskID))) {
+ DVDLowStopMotor(cbForStateCheckID1);
+ } else {
+ LastState = stateCheckID3;
+ stateCheckID3(executing);
+ }
+ break;
+ }
+}
+
+static void stateCheckID3() {
+ DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID3);
+}
+
+static void stateCheckID2a() {
+ DVDLowAudioBufferConfig(IDShouldBe->streaming, 10, cbForStateCheckID2a);
+}
+
+static void cbForStateCheckID2a(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 1) {
+ NumInternalRetry = 0;
+ stateCheckID2(executing);
+ return;
+ }
+
+ DVDLowRequestError(cbForStateGettingError);
+}
+
+static void stateCheckID2() {
+ DVDLowRead(&BB2, OSRoundUp32B(sizeof(BB2)), 0x420, cbForStateCheckID2);
+}
+
+static void cbForStateCheckID1(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 2) {
+ executing->state = -1;
+ stateError(0x1234567);
+ return;
+ }
+
+ NumInternalRetry = 0;
+
+ if (!CheckCancel(1)) {
+ executing->state = 6;
+ stateMotorStopped();
+ }
+}
+
+static void cbForStateCheckID2(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 1) {
+
+ NumInternalRetry = 0;
+
+ stateReadingFST();
+
+ } else {
+
+ stateGettingError();
+ }
+}
+
+static void cbForStateCheckID3(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 1) {
+
+ NumInternalRetry = 0;
+
+ if (!CheckCancel(0)) {
+ executing->state = 1;
+ stateBusy(executing);
+ }
+ } else {
+ stateGettingError();
+ }
+}
+
+static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
+ DVDReset();
+ DCInvalidateRange(&CurrDiskID, sizeof(DVDDiskID));
+ LastState = stateCoverClosed_CMD;
+ stateCoverClosed_CMD(executing);
+}
+
+static void stateCoverClosed() {
+ DVDCommandBlock* finished;
+
+ switch (CurrCommand) {
+ case 5:
+ case 4:
+ case 13:
+ case 15:
+ __DVDClearWaitingQueue();
+ finished = executing;
+ executing = &DummyCommandBlock;
+ if (finished->callback) {
+ (finished->callback)(-4, finished);
+ }
+ stateReady();
+ break;
+
+ default:
+ DVDReset();
+ OSCreateAlarm(&ResetAlarm);
+ OSSetAlarm(&ResetAlarm, OSMillisecondsToTicks(1150), AlarmHandler);
+ break;
+ }
+}
+
+static void stateCoverClosed_CMD(DVDCommandBlock* block) {
+ DVDLowReadDiskID(&CurrDiskID, cbForStateCoverClosed);
+}
+
+static void cbForStateCoverClosed(u32 intType) {
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if (intType & 1) {
+ NumInternalRetry = 0;
+ stateCheckID();
+ } else {
+ stateGettingError();
+ }
+}
+
+static void stateMotorStopped(void) { DVDLowWaitCoverClose(cbForStateMotorStopped); }
+
+static void cbForStateMotorStopped(u32 intType) {
+ __DIRegs[1] = 0;
+ executing->state = 3;
+ stateCoverClosed();
+}
+
+static void stateReady() {
+ DVDCommandBlock* finished;
+
+ if (!__DVDCheckWaitingQueue()) {
+ executing = (DVDCommandBlock*)NULL;
+ return;
+ }
+
+ if (PauseFlag) {
+ PausingFlag = TRUE;
+ executing = (DVDCommandBlock*)NULL;
+ return;
+ }
+
+ executing = __DVDPopWaitingQueue();
+
+ if (FatalErrorFlag) {
+ executing->state = -1;
+ finished = executing;
+ executing = &DummyCommandBlock;
+ if (finished->callback) {
+ (finished->callback)(-1, finished);
+ }
+ stateReady();
+ return;
+ }
+
+ CurrCommand = executing->command;
+
+ if (ResumeFromHere) {
+ switch (ResumeFromHere) {
+ case 1:
+ executing->state = 1;
+ stateCoverClosed();
+ break;
+ case 2:
+ executing->state = 11;
+ stateMotorStopped();
+ break;
+
+ case 3:
+ executing->state = 4;
+ stateMotorStopped();
+ break;
+
+ case 4:
+ executing->state = 5;
+ stateMotorStopped();
+ break;
+ case 7:
+ case 6:
+ executing->state = 3;
+ stateCoverClosed();
+ break;
+
+ case 5:
+ executing->state = -1;
+ stateError(CancelLastError);
+ break;
+ }
+
+ ResumeFromHere = 0;
+ } else {
+ executing->state = 1;
+ stateBusy(executing);
+ }
+}
+
+#define MIN(a, b) (((a) > (b)) ? (b) : (a))
+static void stateBusy(DVDCommandBlock* block) {
+ DVDCommandBlock* finished;
+ LastState = stateBusy;
+ switch (block->command) {
+ case 5:
+ __DIRegs[1] = __DIRegs[1];
+ block->currTransferSize = sizeof(DVDDiskID);
+ DVDLowReadDiskID(block->addr, cbForStateBusy);
+ break;
+ case 1:
+ case 4:
+ if (!block->length) {
+ finished = executing;
+ executing = &DummyCommandBlock;
+ finished->state = 0;
+ if (finished->callback) {
+ finished->callback(0, finished);
+ }
+ stateReady();
+ } else {
+ __DIRegs[1] = __DIRegs[1];
+ block->currTransferSize = MIN(block->length - block->transferredSize, 0x80000);
+ DVDLowRead((void*)((u8*)block->addr + block->transferredSize), block->currTransferSize,
+ block->offset + block->transferredSize, cbForStateBusy);
+ }
+ break;
+ case 2:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowSeek(block->offset, cbForStateBusy);
+ break;
+ case 3:
+ DVDLowStopMotor(cbForStateBusy);
+ break;
+ case 15:
+ DVDLowStopMotor(cbForStateBusy);
+ break;
+ case 6:
+ __DIRegs[1] = __DIRegs[1];
+ if (AutoFinishing) {
+ executing->currTransferSize = 0;
+ DVDLowRequestAudioStatus(0, cbForStateBusy);
+ } else {
+ executing->currTransferSize = 1;
+ DVDLowAudioStream(0, block->length, block->offset, cbForStateBusy);
+ }
+ break;
+ case 7:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowAudioStream(0x10000, 0, 0, cbForStateBusy);
+ break;
+ case 8:
+ __DIRegs[1] = __DIRegs[1];
+ AutoFinishing = TRUE;
+ DVDLowAudioStream(0, 0, 0, cbForStateBusy);
+ break;
+ case 9:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowRequestAudioStatus(0, cbForStateBusy);
+ break;
+ case 10:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowRequestAudioStatus(0x10000, cbForStateBusy);
+ break;
+ case 11:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowRequestAudioStatus(0x20000, cbForStateBusy);
+ break;
+ case 12:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowRequestAudioStatus(0x30000, cbForStateBusy);
+ break;
+ case 13:
+ __DIRegs[1] = __DIRegs[1];
+ DVDLowAudioBufferConfig(block->offset, block->length, cbForStateBusy);
+ break;
+ case 14:
+ __DIRegs[1] = __DIRegs[1];
+ block->currTransferSize = sizeof(DVDDriveInfo);
+ DVDLowInquiry(block->addr, cbForStateBusy);
+ break;
+ default:
+ checkOptionalCommand(block, cbForStateBusy);
+ break;
+ }
+}
+
+static u32 ImmCommand[] = {0xffffffff, 0xffffffff, 0xffffffff};
+/* Somehow this got included even though the function is stripped? O.o */
+static char string_DVDChangeDiskAsyncMsg[] =
+ "DVDChangeDiskAsync(): You can't specify NULL to company name. \n";
+static u32 DmaCommand[] = {0xffffffff};
+
+inline static BOOL IsImmCommandWithResult(u32 command) {
+ u32 i;
+
+ if (command == 9 || command == 10 || command == 11 || command == 12) {
+ return TRUE;
+ }
+
+ for (i = 0; i < sizeof(ImmCommand) / sizeof(ImmCommand[0]); i++) {
+ if (command == ImmCommand[i])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+inline static BOOL IsDmaCommand(u32 command) {
+ u32 i;
+
+ if (command == 1 || command == 4 || command == 5 || command == 14)
+ return TRUE;
+
+ for (i = 0; i < sizeof(DmaCommand) / sizeof(DmaCommand[0]); i++) {
+ if (command == DmaCommand[i])
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void cbForStateBusy(u32 intType) {
+ DVDCommandBlock* finished;
+
+ if (intType == 16) {
+ executing->state = -1;
+ stateTimeout();
+ return;
+ }
+
+ if ((CurrCommand == 3) || (CurrCommand == 15)) {
+ if (intType & 2) {
+ executing->state = -1;
+ stateError(0x1234567);
+ return;
+ }
+
+ NumInternalRetry = 0;
+
+ if (CurrCommand == 15) {
+ ResetRequired = TRUE;
+ }
+
+ if (CheckCancel(7)) {
+ return;
+ }
+
+ executing->state = 7;
+ stateMotorStopped();
+ return;
+ }
+
+ if (IsDmaCommand(CurrCommand)) {
+ executing->transferredSize += executing->currTransferSize - __DIRegs[6];
+ }
+
+ if (intType & 8) {
+ Canceling = FALSE;
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 10;
+ if (finished->callback)
+ (*finished->callback)(-3, finished);
+ if (CancelCallback)
+ (CancelCallback)(0, finished);
+ stateReady();
+
+ return;
+ }
+
+ if (intType & 1) {
+ NumInternalRetry = 0;
+
+ if (CheckCancel(0))
+ return;
+
+ if (IsDmaCommand(CurrCommand)) {
+ if (executing->transferredSize != executing->length) {
+ stateBusy(executing);
+ return;
+ }
+
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 0;
+ if (finished->callback) {
+ (finished->callback)((s32)finished->transferredSize, finished);
+ }
+ stateReady();
+ } else if (IsImmCommandWithResult(CurrCommand)) {
+ s32 result;
+
+ if ((CurrCommand == 11) || (CurrCommand == 10)) {
+ result = (s32)(__DIRegs[8] << 2);
+ } else {
+ result = (s32)__DIRegs[8];
+ }
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 0;
+ if (finished->callback) {
+ (finished->callback)(result, finished);
+ }
+ stateReady();
+ } else if (CurrCommand == 6) {
+ if (executing->currTransferSize == 0) {
+ if (__DIRegs[8] & 1) {
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 9;
+ if (finished->callback) {
+ (finished->callback)(-2, finished);
+ }
+ stateReady();
+ } else {
+ AutoFinishing = FALSE;
+ executing->currTransferSize = 1;
+ DVDLowAudioStream(0, executing->length, executing->offset, cbForStateBusy);
+ }
+ } else {
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 0;
+ if (finished->callback) {
+ (finished->callback)(0, finished);
+ }
+ stateReady();
+ }
+ } else {
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 0;
+ if (finished->callback) {
+ (finished->callback)(0, finished);
+ }
+ stateReady();
+ }
+ } else {
+ if (CurrCommand == 14) {
+ executing->state = -1;
+ stateError(0x01234567);
+ return;
+ }
+
+ if ((CurrCommand == 1 || CurrCommand == 4 || CurrCommand == 5 || CurrCommand == 14) &&
+ (executing->transferredSize == executing->length)) {
+ if (CheckCancel(0)) {
+ return;
+ }
+ finished = executing;
+ executing = &DummyCommandBlock;
+
+ finished->state = 0;
+ if (finished->callback) {
+ (finished->callback)((s32)finished->transferredSize, finished);
+ }
+ stateReady();
+ return;
+ }
+
+ stateGettingError();
+ }
+}
+
+static BOOL issueCommand(s32 prio, DVDCommandBlock* block) {
+ BOOL level;
+ BOOL result;
+
+ if (autoInvalidation &&
+ (block->command == 1 || block->command == 4 || block->command == 5 || block->command == 14)) {
+ DCInvalidateRange(block->addr, block->length);
+ }
+
+ level = OSDisableInterrupts();
+
+ block->state = 2;
+ result = __DVDPushWaitingQueue(prio, block);
+
+ if ((executing == (DVDCommandBlock*)NULL) && (PauseFlag == FALSE)) {
+ stateReady();
+ }
+
+ OSRestoreInterrupts(level);
+
+ return result;
+}
+
+BOOL DVDReadAbsAsyncPrio(DVDCommandBlock* block, void* addr, s32 length, s32 offset,
+ DVDCBCallback callback, s32 prio) {
+ BOOL idle;
+ block->command = 1;
+ block->addr = addr;
+ block->length = length;
+ block->offset = offset;
+ block->transferredSize = 0;
+ block->callback = callback;
+
+ idle = issueCommand(prio, block);
+ return idle;
+}
+BOOL DVDReadAbsAsyncForBS(DVDCommandBlock* block, void* addr, s32 length, s32 offset,
+ DVDCBCallback callback) {
+ BOOL idle;
+ block->command = 4;
+ block->addr = addr;
+ block->length = length;
+ block->offset = offset;
+ block->transferredSize = 0;
+ block->callback = callback;
+
+ idle = issueCommand(2, block);
+ return idle;
+}
+BOOL DVDReadDiskID(DVDCommandBlock* block, DVDDiskID* diskID, DVDCBCallback callback) {
+ BOOL idle;
+ block->command = 5;
+ block->addr = diskID;
+ block->length = sizeof(DVDDiskID);
+ ;
+ block->offset = 0;
+ block->transferredSize = 0;
+ block->callback = callback;
+
+ idle = issueCommand(2, block);
+ return idle;
+}
+BOOL DVDPrepareStreamAbsAsync(DVDCommandBlock* block, u32 length, u32 offset,
+ DVDCBCallback callback) {
+ BOOL idle;
+ block->command = 6;
+ block->length = length;
+ block->offset = offset;
+ block->callback = callback;
+
+ idle = issueCommand(1, block);
+ return idle;
+}
+BOOL DVDCancelStreamAsync(DVDCommandBlock* block, DVDCBCallback callback) {
+ BOOL idle;
+ block->command = 7;
+ block->callback = callback;
+ idle = issueCommand(1, block);
+ return idle;
+}
+s32 DVDCancelStream(DVDCommandBlock* block) {
+ BOOL result;
+ s32 state;
+ BOOL enabled;
+ s32 retVal;
+
+ result = DVDCancelStreamAsync(block, cbForCancelStreamSync);
+
+ if (result == FALSE) {
+ return -1;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ while (TRUE) {
+ state = ((volatile DVDCommandBlock*)block)->state;
+
+ if (state == 0 || state == -1 || state == 10) {
+ retVal = (s32)block->transferredSize;
+ break;
+ }
+
+ OSSleepThread(&__DVDThreadQueue);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return retVal;
+}
+static void cbForCancelStreamSync(s32 result, DVDCommandBlock* block) {
+ block->transferredSize = (u32)result;
+ OSWakeupThread(&__DVDThreadQueue);
+}
+BOOL DVDStopStreamAtEndAsync(DVDCommandBlock* block, DVDCBCallback callback) {
+ BOOL idle;
+
+ block->command = 8;
+ block->callback = callback;
+
+ idle = issueCommand(1, block);
+
+ return idle;
+}
+BOOL DVDGetStreamErrorStatusAsync(DVDCommandBlock* block, DVDCBCallback callback) {
+ BOOL idle;
+
+ block->command = 9;
+ block->callback = callback;
+
+ idle = issueCommand(1, block);
+
+ return idle;
+}
+BOOL DVDGetStreamPlayAddrAsync(DVDCommandBlock* block, DVDCBCallback callback) {
+ BOOL idle;
+
+ block->command = 10;
+ block->callback = callback;
+
+ idle = issueCommand(1, block);
+
+ return idle;
+}
+BOOL DVDInquiryAsync(DVDCommandBlock* block, DVDDriveInfo* info, DVDCBCallback callback) {
+ BOOL idle;
+
+ block->command = 14;
+ block->addr = (void*)info;
+ block->length = sizeof(DVDDriveInfo);
+ block->transferredSize = 0;
+ block->callback = callback;
+
+ idle = issueCommand(2, block);
+
+ return idle;
+}
+
+void DVDReset(void) {
+ DVDLowReset();
+ __DIRegs[0] = 0x2a;
+ __DIRegs[1] = __DIRegs[1];
+ ResetRequired = FALSE;
+ ResumeFromHere = 0;
+}
+
+s32 DVDGetCommandBlockStatus(const DVDCommandBlock* block) {
+ BOOL enabled;
+ s32 retVal;
+
+ enabled = OSDisableInterrupts();
+
+ if (block->state == 3) {
+ retVal = 1;
+ } else {
+ retVal = block->state;
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ return retVal;
+}
+
+s32 DVDGetDriveStatus() {
+ BOOL enabled;
+ s32 retVal;
+
+ enabled = OSDisableInterrupts();
+
+ if (FatalErrorFlag) {
+ retVal = -1;
+ } else if (PausingFlag) {
+ retVal = 8;
+ } else {
+ if (executing == (DVDCommandBlock*)NULL) {
+ retVal = 0;
+ } else if (executing == &DummyCommandBlock) {
+ retVal = 0;
+ } else {
+ retVal = DVDGetCommandBlockStatus(executing);
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ return retVal;
+}
+
+BOOL DVDSetAutoInvalidation(BOOL autoInval) {
+ BOOL prev;
+ prev = autoInvalidation;
+ autoInvalidation = autoInval;
+ return prev;
+}
+
+inline void DVDPause(void) {
+ BOOL level;
+ level = OSDisableInterrupts();
+ PauseFlag = TRUE;
+ if (executing == (DVDCommandBlock*)NULL) {
+ PausingFlag = TRUE;
+ }
+ OSRestoreInterrupts(level);
+}
+
+inline void DVDResume(void) {
+ BOOL level;
+ level = OSDisableInterrupts();
+ PauseFlag = FALSE;
+ if (PausingFlag) {
+ PausingFlag = FALSE;
+ stateReady();
+ }
+ OSRestoreInterrupts(level);
+}
+
+BOOL DVDCancelAsync(DVDCommandBlock* block, DVDCBCallback callback) {
+ BOOL enabled;
+ DVDLowCallback old;
+
+ enabled = OSDisableInterrupts();
+
+ switch (block->state) {
+ case -1:
+ case 0:
+ case 10:
+ if (callback)
+ (*callback)(0, block);
+ break;
+
+ case 1:
+ if (Canceling) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ Canceling = TRUE;
+ CancelCallback = callback;
+ if (block->command == 4 || block->command == 1) {
+ DVDLowBreak();
+ }
+ break;
+
+ case 2:
+ __DVDDequeueWaitingQueue(block);
+ block->state = 10;
+ if (block->callback)
+ (block->callback)(-3, block);
+ if (callback)
+ (*callback)(0, block);
+ break;
+
+ case 3:
+ switch (block->command) {
+ case 5:
+ case 4:
+ case 13:
+ case 15:
+ if (callback)
+ (*callback)(0, block);
+ break;
+
+ default:
+ if (Canceling) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+ Canceling = TRUE;
+ CancelCallback = callback;
+ break;
+ }
+ break;
+
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 11:
+ old = DVDLowClearCallback();
+ if (old != cbForStateMotorStopped) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ if (block->state == 4)
+ ResumeFromHere = 3;
+ if (block->state == 5)
+ ResumeFromHere = 4;
+ if (block->state == 6)
+ ResumeFromHere = 1;
+ if (block->state == 11)
+ ResumeFromHere = 2;
+ if (block->state == 7)
+ ResumeFromHere = 7;
+
+ block->state = 10;
+ if (block->callback) {
+ (block->callback)(-3, block);
+ }
+ if (callback) {
+ (callback)(0, block);
+ }
+ stateReady();
+ break;
+ }
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+s32 DVDCancel(DVDCommandBlock* block) {
+ BOOL result;
+ s32 state;
+ u32 command;
+ BOOL enabled;
+
+ result = DVDCancelAsync(block, cbForCancelSync);
+
+ if (result == FALSE) {
+ return -1;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ for (;;) {
+ state = ((volatile DVDCommandBlock*)block)->state;
+
+ if ((state == 0) || (state == -1) || (state == 10)) {
+ break;
+ }
+
+ if (state == 3) {
+ command = ((volatile DVDCommandBlock*)block)->command;
+
+ if ((command == 4) || (command == 5) || (command == 13) || (command == 15)) {
+ break;
+ }
+ }
+
+ OSSleepThread(&__DVDThreadQueue);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return 0;
+}
+
+static void cbForCancelSync(s32 result, DVDCommandBlock* block) {
+ OSWakeupThread(&__DVDThreadQueue);
+}
+
+inline BOOL DVDCancelAllAsync(DVDCBCallback callback) {
+ BOOL enabled;
+ DVDCommandBlock* p;
+ BOOL retVal;
+
+ enabled = OSDisableInterrupts();
+ DVDPause();
+
+ while ((p = __DVDPopWaitingQueue()) != 0) {
+ DVDCancelAsync(p, NULL);
+ }
+
+ if (executing)
+ retVal = DVDCancelAsync(executing, callback);
+ else {
+ retVal = TRUE;
+ if (callback)
+ (*callback)(0, NULL);
+ }
+
+ DVDResume();
+ OSRestoreInterrupts(enabled);
+ return retVal;
+}
+
+s32 DVDCancelAll(void) {
+ BOOL result;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ CancelAllSyncComplete = FALSE;
+
+ result = DVDCancelAllAsync(cbForCancelAllSync);
+
+ if (result == FALSE) {
+ OSRestoreInterrupts(enabled);
+ return -1;
+ }
+
+ for (;;) {
+ if (CancelAllSyncComplete)
+ break;
+
+ OSSleepThread(&__DVDThreadQueue);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return 0;
+}
+
+static void cbForCancelAllSync(s32 result, DVDCommandBlock* block) {
+ CancelAllSyncComplete = TRUE;
+ OSWakeupThread(&__DVDThreadQueue);
+}
+
+DVDDiskID* DVDGetCurrentDiskID(void) { return (DVDDiskID*)OSPhysicalToCached(0); }
+BOOL DVDCheckDisk(void) {
+ BOOL enabled;
+ s32 retVal;
+ s32 state;
+ u32 coverReg;
+
+ enabled = OSDisableInterrupts();
+
+ if (FatalErrorFlag) {
+ state = -1;
+ } else if (PausingFlag) {
+ state = 8;
+ } else {
+ if (executing == (DVDCommandBlock*)NULL) {
+ state = 0;
+ } else if (executing == &DummyCommandBlock) {
+ state = 0;
+ } else {
+ state = executing->state;
+ }
+ }
+
+ switch (state) {
+ case 1:
+ case 9:
+ case 10:
+ case 2:
+ retVal = TRUE;
+ break;
+
+ case -1:
+ case 11:
+ case 7:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ retVal = FALSE;
+ break;
+
+ case 0:
+ case 8:
+ coverReg = __DIRegs[1];
+ if (((coverReg >> 2) & 1) || (coverReg & 1)) {
+ retVal = FALSE;
+ } else {
+ retVal = TRUE;
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ return retVal;
+}
+
+void __DVDPrepareResetAsync(DVDCBCallback callback) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+
+ __DVDClearWaitingQueue();
+
+ if (Canceling) {
+ CancelCallback = callback;
+ } else {
+ if (executing) {
+ executing->callback = NULL;
+ }
+
+ DVDCancelAllAsync(callback);
+ }
+
+ OSRestoreInterrupts(enabled);
+}
diff --git a/src/Dolphin/dvd/dvderror.c b/src/Dolphin/dvd/dvderror.c
new file mode 100644
index 0000000..c984a8b
--- /dev/null
+++ b/src/Dolphin/dvd/dvderror.c
@@ -0,0 +1,56 @@
+#include "dolphin/DVDPriv.h"
+#include "dolphin/OSRtcPriv.h"
+
+static u32 ErrorTable[] = {
+ 0, 0x00023A00, 0x00062800, 0x00030200, 0x00031100, 0x00052000,
+ 0x00052001, 0x00052100, 0x00052400, 0x00052401, 0x00052402, 0x000B5A01,
+ 0x00056300, 0x00020401, 0x00020400, 0x00040800, 0x00100007, 0,
+};
+
+static u8 ErrorCode2Num(u32 errorCode) {
+ u32 i;
+
+ for (i = 0; i < sizeof(ErrorTable) / sizeof(ErrorTable[0]); i++) {
+ if (ErrorTable[i] == errorCode) {
+ return (u8)i;
+ }
+ }
+
+ if ((errorCode >= 0x00100000) && (errorCode <= 0x00100008)) {
+ return 17;
+ }
+
+ return 29;
+}
+
+static u8 Convert(u32 error) {
+ u32 statusCode;
+ u32 errorCode;
+ u8 errorNum;
+
+ if (error == 0x01234567)
+ return 255;
+
+ if (error == 0x01234568)
+ return 254;
+
+ statusCode = (error & 0xff000000) >> 24;
+ errorCode = error & 0x00ffffff;
+
+ errorNum = ErrorCode2Num(errorCode);
+ if (statusCode >= 6)
+ statusCode = 6;
+
+ return (u8)(statusCode * 30 + errorNum);
+}
+
+void __DVDStoreErrorCode(u32 error) {
+ OSSramEx* sram;
+ u8 num;
+
+ num = Convert(error);
+
+ sram = __OSLockSramEx();
+ sram->dvdErrorCode = num;
+ __OSUnlockSramEx(TRUE);
+}
diff --git a/src/Dolphin/dvd/dvdfatal.c b/src/Dolphin/dvd/dvdfatal.c
new file mode 100644
index 0000000..ea8093c
--- /dev/null
+++ b/src/Dolphin/dvd/dvdfatal.c
@@ -0,0 +1,136 @@
+#include "dolphin/DVDPriv.h"
+#include "dolphin/gx/GXStruct.h"
+#include "dolphin/os.h"
+#include "dolphin/vi.h"
+
+void __DVDPrintFatalMessage(void);
+
+static void (*FatalFunc)(void) = NULL;
+
+const char* Japanese = "\n\n\nƒGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½B"
+ "\n\n–{‘̂̃pƒ[ƒ{ƒ^ƒ“‚ð‰Ÿ‚µ‚Ä“dŒ¹‚ðOFF‚É‚µA"
+ "\n–{‘Ì‚ÌŽæˆµà–¾‘‚ÌŽwŽ¦‚É]‚Á‚Ä‚­‚¾‚³‚¢B";
+
+const char* English = "\n\n\nAn error has occurred."
+ "\nTurn the power off and refer to the"
+ "\nNintendo GameCube Instruction Booklet"
+ "\nfor further instructions.";
+
+const char* const Europe[] = {
+ // English
+ "\n\n\nAn error has occurred."
+ "\nTurn the power off and refer to the"
+ "\nNintendo GameCube""\x99"" Instruction Booklet"
+ "\nfor further instructions.",
+
+ // German
+ "\n\n\nEin Fehler ist aufgetreten."
+ "\nBitte schalten Sie den NINTENDO GAMECUBE"
+ "\naus und lesen Sie die Bedienungsanleitung,"
+ "\num weitere Informationen zu erhalten.",
+
+ // French
+ "\n\n\nUne erreur est survenue."
+ "\nEteignez la console et r" "\xe9" "f" "\xe9" "rez-vous au"
+ "\nmanuel d'instructions NINTENDO GAMECUBE"
+ "\npour de plus amples informations.",
+
+ // Spanish
+ "\n\n\nSe ha producido un error."
+ "\nApaga la consola y consulta el manual"
+ "\nde instrucciones de NINTENDO GAMECUBE"
+ "\npara obtener m""\xe1""s informaci""\xf3""n.",
+
+ // Italian
+ "\n\n\nSi \xe8 verificato un errore."
+ "\nSpegni (OFF) e controlla il manuale"
+ "\nd'istruzioni del NINTENDO GAMECUBE"
+ "\nper ulteriori indicazioni.",
+
+ // Dutch
+ "\n\n\nEr is een fout opgetreden."
+ "\nZet de NINTENDO GAMECUBE uit en"
+ "\nraadpleeg de handleiding van de"
+ "\nNintendo GameCube voor nadere"
+ "\ninstructies.",
+};
+
+static void ShowMessage(void) {
+ const char* message;
+ GXColor bg = {0, 0, 0, 0};
+ GXColor fg = {255, 255, 255, 0};
+
+ if (VIGetTvFormat() == VI_NTSC) {
+ if (OSGetFontEncode() == OS_FONT_ENCODE_SJIS) {
+ message = Japanese;
+ } else {
+ message = English;
+ }
+ } else {
+ message = Europe[OSGetLanguage()];
+ }
+
+ OSFatal(fg, bg, message);
+}
+
+#ifdef FULL_FRANK
+BOOL DVDSetAutoFatalMessaging(BOOL enable) {
+ BOOL enabled;
+ BOOL prev;
+
+ enabled = OSDisableInterrupts();
+ prev = FatalFunc ? TRUE : FALSE;
+ FatalFunc = enable ? ShowMessage : NULL;
+ OSRestoreInterrupts(enabled);
+ return prev;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm BOOL DVDSetAutoFatalMessaging(BOOL enable) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ bl OSDisableInterrupts
+ lwz r0, FatalFunc
+ cmplwi r0, 0
+ beq lbl_80374DFC
+ li r31, 1
+ b lbl_80374E00
+lbl_80374DFC:
+ li r31, 0
+lbl_80374E00:
+ cmpwi r30, 0
+ beq lbl_80374E14
+ lis r4, ShowMessage@ha
+ addi r0, r4, ShowMessage@l
+ b lbl_80374E18
+lbl_80374E14:
+ li r0, 0
+lbl_80374E18:
+ stw r0, FatalFunc
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format off */
+#endif
+
+void __DVDPrintFatalMessage(void) {
+ if (!FatalFunc) {
+ return;
+ }
+ FatalFunc();
+}
diff --git a/src/Dolphin/dvd/dvdfs.c b/src/Dolphin/dvd/dvdfs.c
new file mode 100644
index 0000000..d0dc27c
--- /dev/null
+++ b/src/Dolphin/dvd/dvdfs.c
@@ -0,0 +1,656 @@
+#include "dolphin/DVDPriv.h"
+#include "dolphin/os.h"
+#include "dolphin/os/OSBootInfo.h"
+
+typedef struct FSTEntry FSTEntry;
+
+struct FSTEntry {
+ unsigned int isDirAndStringOff;
+ unsigned int parentOrPosition;
+ unsigned int nextEntryOrLength;
+};
+
+static OSBootInfo* BootInfo;
+static FSTEntry* FstStart;
+static char* FstStringStart;
+static u32 MaxEntryNum;
+static u32 currentDirectory = 0;
+OSThreadQueue __DVDThreadQueue;
+u32 __DVDLongFileNameFlag = 0;
+
+static void cbForReadAsync(s32 result, DVDCommandBlock* block);
+static void cbForReadSync(s32 result, DVDCommandBlock* block);
+static void cbForSeekAsync(s32 result, DVDCommandBlock* block);
+static void cbForSeekSync(s32 result, DVDCommandBlock* block);
+static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block);
+static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block);
+
+void __DVDFSInit() {
+ BootInfo = (OSBootInfo*)OSPhysicalToCached(0);
+ FstStart = (FSTEntry*)BootInfo->FSTLocation;
+
+ if (FstStart) {
+ MaxEntryNum = FstStart[0].nextEntryOrLength;
+ FstStringStart = (char*)&(FstStart[MaxEntryNum]);
+ }
+}
+
+/* For convenience */
+#define entryIsDir(i) (((FstStart[i].isDirAndStringOff & 0xff000000) == 0) ? FALSE : TRUE)
+#define stringOff(i) (FstStart[i].isDirAndStringOff & ~0xff000000)
+#define parentDir(i) (FstStart[i].parentOrPosition)
+#define nextDir(i) (FstStart[i].nextEntryOrLength)
+#define filePosition(i) (FstStart[i].parentOrPosition)
+#define fileLength(i) (FstStart[i].nextEntryOrLength)
+
+static BOOL isSame(const char* path, const char* string) {
+ while (*string != '\0') {
+ if (tolower(*path++) != tolower(*string++)) {
+ return FALSE;
+ }
+ }
+
+ if ((*path == '/') || (*path == '\0')) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+s32 DVDConvertPathToEntrynum(char* pathPtr) {
+ const char* ptr;
+ char* stringPtr;
+ BOOL isDir;
+ u32 length;
+ u32 dirLookAt;
+ u32 i;
+ const char* origPathPtr = pathPtr;
+ const char* extentionStart;
+ BOOL illegal;
+ BOOL extention;
+
+ dirLookAt = currentDirectory;
+
+ while (1) {
+
+ if (*pathPtr == '\0') {
+ return (s32)dirLookAt;
+ } else if (*pathPtr == '/') {
+ dirLookAt = 0;
+ pathPtr++;
+ continue;
+ } else if (*pathPtr == '.') {
+ if (*(pathPtr + 1) == '.') {
+ if (*(pathPtr + 2) == '/') {
+ dirLookAt = parentDir(dirLookAt);
+ pathPtr += 3;
+ continue;
+ } else if (*(pathPtr + 2) == '\0') {
+ return (s32)parentDir(dirLookAt);
+ }
+ } else if (*(pathPtr + 1) == '/') {
+ pathPtr += 2;
+ continue;
+ } else if (*(pathPtr + 1) == '\0') {
+ return (s32)dirLookAt;
+ }
+ }
+
+ if (__DVDLongFileNameFlag == 0) {
+ extention = FALSE;
+ illegal = FALSE;
+
+ for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++) {
+ if (*ptr == '.') {
+ if ((ptr - pathPtr > 8) || (extention == TRUE)) {
+ illegal = TRUE;
+ break;
+ }
+ extention = TRUE;
+ extentionStart = ptr + 1;
+
+ } else if (*ptr == ' ')
+ illegal = TRUE;
+ }
+
+ if ((extention == TRUE) && (ptr - extentionStart > 3))
+ illegal = TRUE;
+
+ if (illegal)
+ OSPanic(__FILE__, 379,
+ "DVDConvertEntrynumToPath(possibly DVDOpen or DVDChangeDir or DVDOpenDir): "
+ "specified directory or file (%s) doesn't match standard 8.3 format. This is a "
+ "temporary restriction and will be removed soon\n",
+ origPathPtr);
+ } else {
+ for (ptr = pathPtr; (*ptr != '\0') && (*ptr != '/'); ptr++)
+ ;
+ }
+
+ isDir = (*ptr == '\0') ? FALSE : TRUE;
+ length = (u32)(ptr - pathPtr);
+
+ ptr = pathPtr;
+
+ for (i = dirLookAt + 1; i < nextDir(dirLookAt); i = entryIsDir(i) ? nextDir(i) : (i + 1)) {
+ if ((entryIsDir(i) == FALSE) && (isDir == TRUE)) {
+ continue;
+ }
+
+ stringPtr = FstStringStart + stringOff(i);
+
+ if (isSame(ptr, stringPtr) == TRUE) {
+ goto next_hier;
+ }
+ }
+
+ return -1;
+
+ next_hier:
+ if (!isDir) {
+ return (s32)i;
+ }
+
+ dirLookAt = i;
+ pathPtr += length + 1;
+ }
+}
+
+BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) {
+ if ((entrynum < 0) || (entrynum >= MaxEntryNum) || entryIsDir(entrynum)) {
+ return FALSE;
+ }
+
+ fileInfo->startAddr = filePosition(entrynum);
+ fileInfo->length = fileLength(entrynum);
+ fileInfo->callback = (DVDCallback)NULL;
+ fileInfo->cb.state = DVD_STATE_END;
+
+ return TRUE;
+}
+
+BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo) {
+ s32 entry;
+ char currentDir[128];
+
+ entry = DVDConvertPathToEntrynum(fileName);
+
+ if (0 > entry) {
+ DVDGetCurrentDir(currentDir, 128);
+ OSReport("Warning: DVDOpen(): file '%s' was not found under %s.\n", fileName, currentDir);
+ return FALSE;
+ }
+
+ if (entryIsDir(entry)) {
+ return FALSE;
+ }
+
+ fileInfo->startAddr = filePosition(entry);
+ fileInfo->length = fileLength(entry);
+ fileInfo->callback = (DVDCallback)NULL;
+ fileInfo->cb.state = DVD_STATE_END;
+
+ return TRUE;
+}
+
+#ifdef FULL_FRANK
+BOOL DVDClose(DVDFileInfo* fileInfo) {
+ DVDCancel(&(fileInfo->cb));
+ return TRUE;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm BOOL DVDClose(DVDFileInfo* fileInfo) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -8(r1)
+ bl DVDCancel
+ li r3, 1
+ lwz r0, 0xc(r1)
+ addi r1, r1, 8
+ mtlr r0
+ blr
+}
+#pragma pop
+#endif
+
+static u32 myStrncpy(char* dest, char* src, u32 maxlen) {
+ u32 i = maxlen;
+
+ while ((i > 0) && (*src != 0)) {
+ *dest++ = *src++;
+ i--;
+ }
+
+ return (maxlen - i);
+}
+
+static u32 entryToPath(u32 entry, char* path, u32 maxlen) {
+ char* name;
+ u32 loc;
+
+ if (entry == 0) {
+ return 0;
+ }
+
+ name = FstStringStart + stringOff(entry);
+
+ loc = entryToPath(parentDir(entry), path, maxlen);
+
+ if (loc == maxlen) {
+ return loc;
+ }
+
+ *(path + loc++) = '/';
+
+ loc += myStrncpy(path + loc, name, maxlen - loc);
+
+ return loc;
+}
+
+static BOOL DVDConvertEntrynumToPath(s32 entrynum, char* path, u32 maxlen) {
+ u32 loc;
+
+ loc = entryToPath((u32)entrynum, path, maxlen);
+
+ if (loc == maxlen) {
+ path[maxlen - 1] = '\0';
+ return FALSE;
+ }
+
+ if (entryIsDir(entrynum)) {
+ if (loc == maxlen - 1) {
+ path[loc] = '\0';
+ return FALSE;
+ }
+
+ path[loc++] = '/';
+ }
+
+ path[loc] = '\0';
+ return TRUE;
+}
+
+BOOL DVDGetCurrentDir(char* path, u32 maxlen) {
+ return DVDConvertEntrynumToPath((s32)currentDirectory, path, maxlen);
+}
+
+BOOL DVDChangeDir(char* dirName) {
+ s32 entry;
+ entry = DVDConvertPathToEntrynum(dirName);
+ if ((entry < 0) || (entryIsDir(entry) == FALSE)) {
+ return FALSE;
+ }
+
+ currentDirectory = (u32)entry;
+
+ return TRUE;
+}
+
+BOOL DVDReadAsyncPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset,
+ DVDCallback callback, s32 prio) {
+
+ if (!((0 <= offset) && (offset < fileInfo->length))) {
+ OSPanic(__FILE__, 742, "DVDReadAsync(): specified area is out of the file ");
+ }
+
+ if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
+ OSPanic(__FILE__, 748, "DVDReadAsync(): specified area is out of the file ");
+ }
+
+ fileInfo->callback = callback;
+ DVDReadAbsAsyncPrio(&(fileInfo->cb), addr, length, (s32)(fileInfo->startAddr + offset),
+ cbForReadAsync, prio);
+
+ return TRUE;
+}
+#ifndef offsetof
+#define offsetof(type, memb) ((u32) & ((type*)0)->memb)
+#endif
+
+static void cbForReadAsync(s32 result, DVDCommandBlock* block) {
+ DVDFileInfo* fileInfo;
+
+ fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb));
+ if (fileInfo->callback) {
+ (fileInfo->callback)(result, fileInfo);
+ }
+}
+
+/* This is based on the revolution SDK, these may not match in all cases I have also left the line numbers at 0 */
+s32 DVDReadPrio(DVDFileInfo* fileInfo, void* addr, s32 length, s32 offset, s32 prio) {
+ BOOL result;
+ DVDCommandBlock* block;
+ s32 state;
+ BOOL enabled;
+ s32 retVal;
+
+ if (!((0 <= offset) && (offset <= fileInfo->length))) {
+ OSPanic(__FILE__, 0, "DVDRead(): specified area is out of the file ");
+ }
+
+ if (!((0 <= offset + length) && (offset + length < fileInfo->length + DVD_MIN_TRANSFER_SIZE))) {
+ OSPanic(__FILE__, 0, "DVDRead(): specified area is out of the file ");
+ }
+
+ block = &(fileInfo->cb);
+
+ result = DVDReadAbsAsyncPrio(block, addr, length, (s32)(fileInfo->startAddr + offset),
+ cbForReadSync, prio);
+
+ if (result == FALSE) {
+ return -1;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ while(1) {
+ state = ((volatile DVDCommandBlock*)block)->state;
+
+ if (state == DVD_STATE_END) {
+ retVal = (s32)block->transferredSize;
+ break;
+ }
+ if (state == DVD_STATE_FATAL_ERROR) {
+ retVal = DVD_RESULT_FATAL_ERROR;
+ break;
+ }
+ if (state == DVD_STATE_CANCELED) {
+ retVal = DVD_RESULT_CANCELED;
+ break;
+ }
+
+ OSSleepThread(&__DVDThreadQueue);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return retVal;
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+static void cbForReadSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); }
+/* This is based on the revolution SDK, these may not match in all cases */
+BOOL DVDSeekAsyncPrio(DVDFileInfo* fileInfo, s32 offset, DVDCallback callback, s32 prio) {
+ if (!((0 <= offset) && (offset <= fileInfo->length))) {
+ OSPanic(__FILE__, 0, "DVDSeek(): offset is out of the file ");
+ }
+
+ fileInfo->callback = callback;
+ DVDSeekAbsAsyncPrio(&(fileInfo->cb), (s32)(fileInfo->startAddr + offset), cbForSeekAsync,
+ prio);
+
+ return TRUE;
+}
+/* This is based on the revolution SDK, these may not match in all cases */
+static void cbForSeekAsync(s32 result, DVDCommandBlock* block) {
+ DVDFileInfo* fileInfo;
+
+ fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb));
+
+ if (fileInfo->callback) {
+ (fileInfo->callback)(result, fileInfo);
+ }
+}
+/* This is based on the revolution SDK, these may not match in all cases */
+s32 DVDSeekPrio(DVDFileInfo* fileInfo, s32 offset, s32 prio) {
+ BOOL result;
+ DVDCommandBlock* block;
+ s32 state;
+ BOOL enabled;
+ s32 retVal;
+
+ block = &(fileInfo->cb);
+
+ result =
+ DVDSeekAbsAsyncPrio(block, (s32)(fileInfo->startAddr + offset), cbForSeekSync, prio);
+
+ if (result == FALSE) {
+ return -1;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ while (1) {
+ state = ((volatile DVDCommandBlock*)block)->state;
+
+ if (state == DVD_STATE_END) {
+ retVal = 0;
+ break;
+ }
+ if (state == DVD_STATE_FATAL_ERROR) {
+ retVal = DVD_RESULT_FATAL_ERROR;
+ break;
+ }
+ if (state == DVD_STATE_CANCELED) {
+ retVal = DVD_RESULT_CANCELED;
+ break;
+ }
+
+ OSSleepThread(&__DVDThreadQueue);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return retVal;
+}
+/* This is based on the revolution SDK, these may not match in all cases */
+static void cbForSeekSync(s32 result, DVDCommandBlock* block) { OSWakeupThread(&__DVDThreadQueue); }
+
+/* This is based on the revolution SDK, these may not match in all cases */
+s32 DVDGetFileInfoStatus(DVDFileInfo* fileInfo) {
+ return DVDGetCommandBlockStatus(&fileInfo->cb);
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) {
+
+ if ((entrynum < 0) || (entrynum >= MaxEntryNum) || !entryIsDir(entrynum)) {
+ return FALSE;
+ }
+
+ dir->entryNum = (u32)entrynum;
+ dir->location = (u32)entrynum + 1;
+ dir->next = nextDir(entrynum);
+
+ return TRUE;
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+BOOL DVDOpenDir(char* dirName, DVDDir* dir) {
+ s32 entry;
+ char currentDir[128];
+ entry = DVDConvertPathToEntrynum(dirName);
+
+ if (entry < 0) {
+ DVDGetCurrentDir(currentDir, 128);
+ OSReport("Warning: DVDOpenDir(): file '%s' was not found under %s.\n", dirName, currentDir);
+ return FALSE;
+ }
+
+ if (!entryIsDir(entry)) {
+ return FALSE;
+ }
+
+ dir->entryNum = (u32)entry;
+ dir->location = (u32)entry + 1;
+ dir->next = nextDir(entry);
+
+ return TRUE;
+}
+
+BOOL DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) {
+ u32 loc = dir->location;
+ if ((loc <= dir->entryNum) || (dir->next <= loc))
+ return FALSE;
+
+ dirent->entryNum = loc;
+ dirent->isDir = entryIsDir(loc);
+ dirent->name = FstStringStart + stringOff(loc);
+
+ dir->location = entryIsDir(loc) ? nextDir(loc) : (loc + 1);
+
+ return TRUE;
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+BOOL DVDCloseDir(DVDDir* dir) { return TRUE; }
+
+/* This is based on the revolution SDK, these may not match in all cases */
+void DVDRewindDir(DVDDir* dir) { dir->location = dir->entryNum + 1; }
+
+/* This is based on the revolution SDK, these may not match in all cases */
+void* DVDGetFSTLocation(void) { return BootInfo->FSTLocation; }
+
+#define RoundUp32KB(x) (((u32)(x) + 32 * 1024 - 1) & ~(32 * 1024 - 1))
+#define Is32KBAligned(x) (((u32)(x) & (32 * 1024 - 1)) == 0)
+
+BOOL DVDPrepareStreamAsync(DVDFileInfo* fileInfo, u32 length, u32 offset, DVDCallback callback) {
+ u32 start;
+
+ start = fileInfo->startAddr + offset;
+
+ if (!Is32KBAligned(start)) {
+ OSPanic(__FILE__, 1189,
+ "DVDPrepareStreamAsync(): Specified start address (filestart(0x%x) + offset(0x%x)) is "
+ "not 32KB aligned",
+ fileInfo->startAddr, offset);
+ }
+
+ if (length == 0)
+ length = fileInfo->length - offset;
+
+ if (!Is32KBAligned(length)) {
+ OSPanic(__FILE__, 1199,
+ "DVDPrepareStreamAsync(): Specified length (0x%x) is not a multiple of 32768(32*1024)",
+ length);
+ }
+
+ if (!((offset < fileInfo->length) && (offset + length <= fileInfo->length))) {
+ OSPanic(__FILE__, 1207,
+ "DVDPrepareStreamAsync(): The area specified (offset(0x%x), length(0x%x)) is out of "
+ "the file",
+ offset, length);
+ }
+
+ fileInfo->callback = callback;
+ return DVDPrepareStreamAbsAsync(&(fileInfo->cb), length, fileInfo->startAddr + offset,
+ cbForPrepareStreamAsync);
+}
+
+static void cbForPrepareStreamAsync(s32 result, DVDCommandBlock* block) {
+ DVDFileInfo* fileInfo;
+
+ fileInfo = (DVDFileInfo*)((char*)block - offsetof(DVDFileInfo, cb));
+
+ if (fileInfo->callback) {
+ (fileInfo->callback)(result, fileInfo);
+ }
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+s32 DVDPrepareStream(DVDFileInfo* fileInfo, u32 length, u32 offset) {
+ BOOL result;
+ DVDCommandBlock* block;
+ s32 state;
+ BOOL enabled;
+ s32 retVal;
+ u32 start;
+ start = fileInfo->startAddr + offset;
+
+ if (!Is32KBAligned(start)) {
+ OSPanic(__FILE__, 0,
+ "DVDPrepareStream(): Specified start address (filestart(0x%x) + offset(0x%x)) is not "
+ "32KB aligned",
+ fileInfo->startAddr, offset);
+ }
+
+ if (length == 0)
+ length = fileInfo->length - offset;
+
+ if (!Is32KBAligned(length)) {
+ OSPanic(__FILE__, 0,
+ "DVDPrepareStream(): Specified length (0x%x) is not a multiple of 32768(32*1024)",
+ length);
+ }
+
+ if (!((offset <= fileInfo->length) && (offset + length <= fileInfo->length))) {
+ OSPanic(
+ __FILE__, 0,
+ "DVDPrepareStream(): The area specified (offset(0x%x), length(0x%x)) is out of the file",
+ offset, length);
+ }
+
+ block = &(fileInfo->cb);
+ result = DVDPrepareStreamAbsAsync(block, length, start, cbForPrepareStreamSync);
+
+ if (result == FALSE) {
+ return -1;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ while(1) {
+ state = ((volatile DVDCommandBlock*)block)->state;
+
+ if (state == DVD_STATE_END) {
+ retVal = 0;
+ break;
+ }
+ if (state == DVD_STATE_FATAL_ERROR) {
+ retVal = DVD_RESULT_FATAL_ERROR;
+ break;
+ }
+ if (state == DVD_STATE_CANCELED) {
+ retVal = DVD_RESULT_CANCELED;
+ break;
+ }
+
+ OSSleepThread(&__DVDThreadQueue);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return retVal;
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+static void cbForPrepareStreamSync(s32 result, DVDCommandBlock* block) {
+ OSWakeupThread(&__DVDThreadQueue);
+}
+
+/* This is based on the revolution SDK, these may not match in all cases */
+s32 DVDGetTransferredSize(DVDFileInfo* fileinfo) {
+ s32 bytes;
+ DVDCommandBlock* cb;
+
+ cb = &(fileinfo->cb);
+
+ switch (cb->state) {
+ case DVD_STATE_END:
+ case DVD_STATE_COVER_CLOSED:
+ case DVD_STATE_NO_DISK:
+ case DVD_STATE_COVER_OPEN:
+ case DVD_STATE_WRONG_DISK:
+ case DVD_STATE_FATAL_ERROR:
+ case DVD_STATE_MOTOR_STOPPED:
+ case DVD_STATE_CANCELED:
+ case DVD_STATE_RETRY:
+ bytes = (s32)cb->transferredSize;
+ break;
+
+ case DVD_STATE_WAITING:
+ bytes = 0;
+ break;
+
+ case DVD_STATE_BUSY:
+ bytes = (s32)(cb->transferredSize + (cb->currTransferSize - DVDLowGetLength()));
+ break;
+
+ default:
+ break;
+ }
+
+ return bytes;
+}
diff --git a/src/Dolphin/dvd/dvdidutils.c b/src/Dolphin/dvd/dvdidutils.c
new file mode 100644
index 0000000..3c58e98
--- /dev/null
+++ b/src/Dolphin/dvd/dvdidutils.c
@@ -0,0 +1,27 @@
+#include <dolphin/DVDPriv.h>
+#include <dolphin/dvd.h>
+#include <dolphin/dvd_regs.h>
+
+#include <string.h>
+
+BOOL DVDCompareDiskID(DVDDiskID* id1, DVDDiskID* id2) {
+
+ if (id1->gameName[0] && id2->gameName[0] && strncmp(&id1->gameName[0], &id2->gameName[0], 4)) {
+ return FALSE;
+ }
+
+ if (!id1->company[0] || !id2->company[0] || strncmp(&id1->company[0], &id2->company[0], 2)) {
+ return FALSE;
+ }
+
+ if (id1->diskNumber != 0xff && id2->diskNumber != 0xff && id1->diskNumber != id2->diskNumber) {
+ return FALSE;
+ }
+
+ if (id1->gameVersion != 0xff && id2->gameVersion != 0xff &&
+ id1->gameVersion != id2->gameVersion) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/Dolphin/dvd/dvdlow.c b/src/Dolphin/dvd/dvdlow.c
new file mode 100644
index 0000000..1a939ba
--- /dev/null
+++ b/src/Dolphin/dvd/dvdlow.c
@@ -0,0 +1,109 @@
+#include "dolphin/DVDPriv.h"
+#include "dolphin/os.h"
+
+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 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;
+
+typedef struct DVDUnk {
+ u32 _0;
+ u32 _4;
+ u32 _8;
+} DVDUnk;
+
+typedef struct DVDCommand {
+ s32 _0;
+ u32 _4;
+ u32 _8;
+ u32 _c;
+ DVDLowCallback callback;
+} DVDCommand;
+
+static DVDCommand CommandList[4];
+static OSAlarm AlarmForWA;
+static OSAlarm AlarmForTimeout;
+static OSAlarm AlarmForBreak;
+static DVDUnk Prev;
+static DVDUnk Cur;
+
+void __DVDInitWA() {
+ NextCommandNumber = 0;
+ CommandList[0]._0 = -1;
+ __DVDLowSetWAType(0, 0);
+ OSInitAlarm();
+}
+static void Read(u32 tmp1, u32 tmp2, u32 tmp3, DVDLowCallback tmp4);
+void __DVDInterruptHandler(__OSInterrupt interrupt, OSContext* context) {}
+
+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);
+ }
+}
+
+static void AlarmHandlerForTimeout(OSAlarm* alarm, OSContext* context) {
+ OSContext tmpContext;
+ DVDLowCallback callback;
+ __OSMaskInterrupts(0x400);
+ OSClearContext(&tmpContext);
+ OSSetCurrentContext(&tmpContext);
+ callback = Callback;
+ Callback = NULL;
+ if (callback != NULL) {
+ callback(0x10);
+ }
+ OSClearContext(&tmpContext);
+ OSSetCurrentContext(context);
+}
+
+static void Read(u32 tmp1, u32 tmp2, u32 tmp3, DVDLowCallback tmp4) {
+
+}
+
+static void SeekTwiceBeforeRead() {
+
+}
+
+void DVDLowRead(u32 unk, DVDLowCallback callback) {
+
+}
+
+void DVDLowSeek(u32 offset, DVDLowCallback callback) {
+
+}
+
+BOOL DVDLowWaitCoverClose(DVDLowCallback callback) {
+ Callback = callback;
+ WaitingCoverClose = TRUE;
+ StopAtNextInt = FALSE;
+ __DIRegs[1] = 2;
+ return TRUE;
+}
+
+
+void __DVDLowSetWAType(u32 type, u32 location) {
+ BOOL enabled;
+ enabled = OSDisableInterrupts();
+ WorkAroundType = type;
+ WorkAroundSeekLocation = location;
+ OSRestoreInterrupts(enabled);
+}
diff --git a/src/Dolphin/dvd/dvdqueue.c b/src/Dolphin/dvd/dvdqueue.c
new file mode 100644
index 0000000..a381ccf
--- /dev/null
+++ b/src/Dolphin/dvd/dvdqueue.c
@@ -0,0 +1,142 @@
+#include "dolphin/DVDPriv.h"
+
+#define MAX_QUEUES 4
+typedef struct {
+ DVDCommandBlock* next;
+ DVDCommandBlock* prev;
+} DVDQueue;
+
+static DVDQueue WaitingQueue[MAX_QUEUES];
+
+void __DVDClearWaitingQueue(void) {
+ u32 i;
+
+ for (i = 0; i < MAX_QUEUES; i++) {
+ DVDCommandBlock* q;
+
+ q = (DVDCommandBlock*)&(WaitingQueue[i]);
+ q->next = q;
+ q->prev = q;
+ }
+}
+
+BOOL __DVDPushWaitingQueue(s32 prio, DVDCommandBlock* block) {
+ BOOL enabled;
+ DVDCommandBlock* q;
+
+ enabled = OSDisableInterrupts();
+
+ q = (DVDCommandBlock*)&(WaitingQueue[prio]);
+
+ q->prev->next = block;
+ block->prev = q->prev;
+ block->next = q;
+ q->prev = block;
+
+ OSRestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+static DVDCommandBlock* PopWaitingQueuePrio(s32 prio) {
+ DVDCommandBlock* tmp;
+ BOOL enabled;
+ DVDCommandBlock* q;
+
+ enabled = OSDisableInterrupts();
+
+ q = (DVDCommandBlock*)&(WaitingQueue[prio]);
+
+ tmp = q->next;
+ q->next = tmp->next;
+ tmp->next->prev = q;
+
+ OSRestoreInterrupts(enabled);
+
+ tmp->next = (DVDCommandBlock*)NULL;
+ tmp->prev = (DVDCommandBlock*)NULL;
+
+ return tmp;
+}
+
+DVDCommandBlock* __DVDPopWaitingQueue(void) {
+ u32 i;
+ BOOL enabled;
+ DVDCommandBlock* q;
+
+ enabled = OSDisableInterrupts();
+
+ for (i = 0; i < MAX_QUEUES; i++) {
+ q = (DVDCommandBlock*)&(WaitingQueue[i]);
+ if (q->next != q) {
+ OSRestoreInterrupts(enabled);
+ return PopWaitingQueuePrio((s32)i);
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ return (DVDCommandBlock*)NULL;
+}
+
+BOOL __DVDCheckWaitingQueue(void) {
+ u32 i;
+ BOOL enabled;
+ DVDCommandBlock* q;
+
+ enabled = OSDisableInterrupts();
+
+ for (i = 0; i < MAX_QUEUES; i++) {
+ q = (DVDCommandBlock*)&(WaitingQueue[i]);
+ if (q->next != q) {
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ return FALSE;
+}
+
+BOOL __DVDDequeueWaitingQueue(DVDCommandBlock* block) {
+ BOOL enabled;
+ DVDCommandBlock* prev;
+ DVDCommandBlock* next;
+
+ enabled = OSDisableInterrupts();
+
+ prev = block->prev;
+ next = block->next;
+
+ if ((prev == (DVDCommandBlock*)NULL) || (next == (DVDCommandBlock*)NULL)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ prev->next = next;
+ next->prev = prev;
+
+ OSRestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+BOOL __DVDIsBlockInWaitingQueue(DVDCommandBlock* block) {
+ u32 i;
+ DVDCommandBlock* start;
+ DVDCommandBlock* q;
+
+ for (i = 0; i < MAX_QUEUES; i++) {
+ start = (DVDCommandBlock*)&(WaitingQueue[i]);
+
+ if (start->next != start) {
+ for (q = start->next; q != start; q = q->next) {
+ if (q == block)
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
diff --git a/src/Dolphin/dvd/fstload.c b/src/Dolphin/dvd/fstload.c
new file mode 100644
index 0000000..1f7a81b
--- /dev/null
+++ b/src/Dolphin/dvd/fstload.c
@@ -0,0 +1,67 @@
+#include <dolphin/DVDPriv.h>
+#include <dolphin/dvd.h>
+#include <dolphin/dvd_regs.h>
+#include <dolphin/os.h>
+#include <dolphin/os/OSBootInfo.h>
+#include <string.h>
+
+static s32 status = 0;
+
+static u8 bb2Buf[OSRoundUp32B(sizeof(DVDBB2)) + 31];
+static DVDBB2* bb2 = 0;
+static DVDDiskID* idTmp = NULL;
+
+static void cb(s32 result, DVDCommandBlock* block) {
+ if (result > 0) {
+ switch (status) {
+ case 0:
+ status = 1;
+ DVDReadAbsAsyncForBS(block, bb2, OSRoundUp32B(sizeof(bb2)), 0x420, cb);
+ break;
+ case 1:
+ status = 2;
+ DVDReadAbsAsyncForBS(block, bb2->FSTAddress, OSRoundUp32B(bb2->FSTLength), bb2->FSTPosition,
+ cb);
+ }
+ } else if (result == -1) {
+
+ } else if (result == -4) {
+ status = 0;
+ DVDReset();
+ DVDReadDiskID(block, idTmp, cb);
+ }
+}
+
+void __fstLoad() {
+ OSBootInfo* bootInfo;
+ DVDDiskID* id;
+ u8 idTmpBuf[sizeof(DVDDiskID) + 31];
+ static DVDCommandBlock block;
+ void* arenaHi;
+
+ arenaHi = OSGetArenaHi();
+ bootInfo = (OSBootInfo*)OSPhysicalToCached(0);
+
+ idTmp = (DVDDiskID*)(OSRoundUp32B(idTmpBuf));
+ bb2 = (DVDBB2*)(OSRoundUp32B(bb2Buf));
+
+ DVDReset();
+ DVDReadDiskID(&block, idTmp, cb);
+ while (DVDGetDriveStatus() != 0);
+
+ bootInfo->FSTLocation = bb2->FSTAddress;
+ bootInfo->FSTMaxLength = bb2->FSTMaxLength;
+
+ id = &bootInfo->DVDDiskID;
+
+ memcpy(id, idTmp, sizeof(DVDDiskID));
+ OSReport("\n");
+ OSReport(" Game Name ... %c%c%c%c\n", id->gameName[0], id->gameName[1], id->gameName[2],
+ id->gameName[3]);
+ OSReport(" Company ..... %c%c\n", id->company[0], id->company[1]);
+ OSReport(" Disk # ...... %d\n", id->diskNumber);
+ OSReport(" Game ver .... %d\n", id->gameVersion);
+ OSReport(" Streaming ... %s\n", (id->streaming == 0) ? "OFF" : "ON");
+ OSReport("\n");
+ OSSetArenaHi(bb2->FSTAddress);
+}
diff --git a/src/Dolphin/exi/EXIBios.c b/src/Dolphin/exi/EXIBios.c
new file mode 100644
index 0000000..8ff770f
--- /dev/null
+++ b/src/Dolphin/exi/EXIBios.c
@@ -0,0 +1,692 @@
+#include "dolphin/os.h"
+
+#pragma scheduling off
+
+vu32 __EXIRegs[16] : 0xCC006800;
+
+static const char* __EXIVersion =
+ "<< Dolphin SDK - EXI\trelease build: Sep 5 2002 05:33:04 (0x2301) >>";
+
+#define MAX_DEV 3
+#define MAX_CHAN 3
+
+#define REG_MAX 5
+#define REG(chan, idx) (__EXIRegs[((chan)*REG_MAX) + (idx)])
+
+#define STATE_IDLE 0x00
+#define STATE_DMA 0x01
+#define STATE_IMM 0x02
+#define STATE_BUSY (STATE_DMA | STATE_IMM)
+#define STATE_SELECTED 0x04
+#define STATE_ATTACHED 0x08
+#define STATE_LOCKED 0x10
+
+#define EXI_0CR(tstart, dma, rw, tlen) \
+ ((((u32)(tstart)) << 0) | (((u32)(dma)) << 1) | (((u32)(rw)) << 2) | (((u32)(tlen)) << 4))
+
+#define CPR_CS(x) ((1u << (x)) << 7)
+#define CPR_CLK(x) ((x) << 4)
+
+typedef struct EXIControl {
+ EXICallback exiCallback;
+ EXICallback tcCallback;
+ EXICallback extCallback;
+ vu32 state;
+ int immLen;
+ u8* immBuf;
+ u32 dev;
+ u32 id;
+ s32 idTime;
+ int items;
+ struct {
+ u32 dev;
+ EXICallback callback;
+ } queue[MAX_DEV];
+} EXIControl;
+
+static EXIControl Ecb[MAX_CHAN];
+
+s32 __EXIProbeStartTime[2] : (OS_BASE_CACHED | 0x30C0);
+
+static void SetExiInterruptMask(s32 chan, EXIControl* exi) {
+ EXIControl* exi2;
+
+ exi2 = &Ecb[2];
+ switch (chan) {
+ case 0:
+ if ((exi->exiCallback == 0 && exi2->exiCallback == 0) || (exi->state & STATE_LOCKED)) {
+ __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
+ } else {
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_2_EXI);
+ }
+ break;
+ case 1:
+ if (exi->exiCallback == 0 || (exi->state & STATE_LOCKED)) {
+ __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
+ } else {
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXI);
+ }
+ break;
+ case 2:
+ if (__OSGetInterruptHandler(__OS_INTERRUPT_PI_DEBUG) == 0 || (exi->state & STATE_LOCKED)) {
+ __OSMaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
+ } else {
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_DEBUG);
+ }
+ break;
+ }
+}
+
+static void CompleteTransfer(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ u8* buf;
+ u32 data;
+ int i;
+ int len;
+
+ if (exi->state & STATE_BUSY) {
+ if ((exi->state & STATE_IMM) && (len = exi->immLen)) {
+ buf = exi->immBuf;
+ data = REG(chan, 4);
+ for (i = 0; i < len; i++) {
+ *buf++ = (u8)((data >> ((3 - i) * 8)) & 0xff);
+ }
+ }
+ exi->state &= ~STATE_BUSY;
+ }
+}
+
+BOOL EXIImm(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ exi->tcCallback = callback;
+ if (exi->tcCallback) {
+ EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan));
+ }
+
+ exi->state |= STATE_IMM;
+
+ if (type != EXI_READ) {
+ u32 data;
+ int i;
+
+ data = 0;
+ for (i = 0; i < len; i++) {
+ data |= ((u8*)buf)[i] << ((3 - i) * 8);
+ }
+ REG(chan, 4) = data;
+ }
+
+ exi->immBuf = buf;
+ exi->immLen = (type != EXI_WRITE) ? len : 0;
+
+ REG(chan, 3) = EXI_0CR(1, 0, type, len - 1);
+
+ OSRestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+BOOL EXIImmEx(s32 chan, void* buf, s32 len, u32 mode) {
+ s32 xLen;
+
+ while (len) {
+ xLen = (len < 4) ? len : 4;
+ if (!EXIImm(chan, buf, xLen, mode, NULL)) {
+ return FALSE;
+ }
+
+ if (!EXISync(chan)) {
+ return FALSE;
+ }
+
+ (u8*)buf += xLen;
+ len -= xLen;
+ }
+ return TRUE;
+}
+
+BOOL EXIDma(s32 chan, void* buf, s32 len, u32 type, EXICallback callback) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if ((exi->state & STATE_BUSY) || !(exi->state & STATE_SELECTED)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ exi->tcCallback = callback;
+ if (exi->tcCallback) {
+ EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_TC >> (3 * chan));
+ }
+
+ exi->state |= STATE_DMA;
+
+ REG(chan, 1) = (u32)buf & 0x3ffffe0;
+ REG(chan, 2) = (u32)len;
+ REG(chan, 3) = EXI_0CR(1, 1, type, 0);
+
+ OSRestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+extern u32 __OSGetDIConfig(void);
+
+vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6);
+
+BOOL EXISync(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL rc = FALSE;
+ BOOL enabled;
+
+ while (exi->state & STATE_SELECTED) {
+ if (((REG(chan, 3) & 1) >> 0) == 0) {
+ enabled = OSDisableInterrupts();
+ if (exi->state & STATE_SELECTED) {
+ CompleteTransfer(chan);
+ if (__OSGetDIConfig() != 0xff || exi->immLen != 4 ||
+ (REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) ||
+ (REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER &&
+ REG(chan, 4) != 0x04220001) ||
+ __OSDeviceCode == 0x8200) {
+ rc = TRUE;
+ }
+ }
+ OSRestoreInterrupts(enabled);
+ break;
+ }
+ }
+ return rc;
+}
+
+u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext) {
+ u32 cpr;
+ u32 prev;
+
+ prev = cpr = REG(chan, 0);
+ cpr &= 0x7f5;
+ if (exi)
+ cpr |= 2;
+ if (tc)
+ cpr |= 8;
+ if (ext)
+ cpr |= 0x800;
+ REG(chan, 0) = cpr;
+ return prev;
+}
+
+EXICallback EXISetExiCallback(s32 chan, EXICallback exiCallback) {
+ EXIControl* exi = &Ecb[chan];
+ EXICallback prev;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ prev = exi->exiCallback;
+ exi->exiCallback = exiCallback;
+
+ if (chan != 2) {
+ SetExiInterruptMask(chan, exi);
+ } else {
+ SetExiInterruptMask(0, &Ecb[0]);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return prev;
+}
+
+void EXIProbeReset(void) {
+ __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
+ Ecb[0].idTime = Ecb[1].idTime = 0;
+ __EXIProbe(0);
+ __EXIProbe(1);
+}
+
+static BOOL __EXIProbe(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+ BOOL rc;
+ u32 cpr;
+ s32 t;
+
+ if (chan == 2) {
+ return TRUE;
+ }
+
+ rc = TRUE;
+ enabled = OSDisableInterrupts();
+ cpr = REG(chan, 0);
+ if (!(exi->state & EXI_STATE_ATTACHED)) {
+ if (cpr & 0x00000800) {
+ EXIClearInterrupts(chan, FALSE, FALSE, TRUE);
+ __EXIProbeStartTime[chan] = exi->idTime = 0;
+ }
+
+ if (cpr & 0x00001000) {
+ t = (s32)(OSTicksToMilliseconds(OSGetTime()) / 100) + 1;
+ if (__EXIProbeStartTime[chan] == 0) {
+ __EXIProbeStartTime[chan] = t;
+ }
+ if (t - __EXIProbeStartTime[chan] < 300 / 100) {
+ rc = FALSE;
+ }
+ } else {
+ __EXIProbeStartTime[chan] = exi->idTime = 0;
+ rc = FALSE;
+ }
+ } else if (!(cpr & 0x00001000) || (cpr & 0x00000800)) {
+ __EXIProbeStartTime[chan] = exi->idTime = 0;
+ rc = FALSE;
+ }
+ OSRestoreInterrupts(enabled);
+
+ return rc;
+}
+
+BOOL EXIProbe(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL rc;
+ u32 id;
+
+ rc = __EXIProbe(chan);
+ if (rc && exi->idTime == 0) {
+ rc = EXIGetID(chan, 0, &id) ? TRUE : FALSE;
+ }
+ return rc;
+}
+
+s32 EXIProbeEx(s32 chan) {
+ if (EXIProbe(chan)) {
+ return 1;
+ } else if (__EXIProbeStartTime[chan] != 0) {
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static BOOL __EXIAttach(s32 chan, EXICallback extCallback) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if ((exi->state & EXI_STATE_ATTACHED) || __EXIProbe(chan) == FALSE) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
+
+ exi->extCallback = extCallback;
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT >> (3 * chan));
+ exi->state |= STATE_ATTACHED;
+ OSRestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+BOOL EXIAttach(s32 chan, EXICallback extCallback) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+ BOOL rc;
+
+ EXIProbe(chan);
+
+ enabled = OSDisableInterrupts();
+ if (exi->idTime == 0) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+ rc = __EXIAttach(chan, extCallback);
+ OSRestoreInterrupts(enabled);
+ return rc;
+}
+
+BOOL EXIDetach(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if (!(exi->state & STATE_ATTACHED)) {
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+ }
+ if ((exi->state & STATE_LOCKED) && exi->dev == 0) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ exi->state &= ~STATE_ATTACHED;
+ __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL EXISelect(s32 chan, u32 dev, u32 freq) {
+ EXIControl* exi = &Ecb[chan];
+ u32 cpr;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if ((exi->state & STATE_SELECTED) ||
+ chan != 2 && (dev == 0 && !(exi->state & STATE_ATTACHED) && !__EXIProbe(chan) ||
+ !(exi->state & STATE_LOCKED) || (exi->dev != dev))) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ exi->state |= STATE_SELECTED;
+ cpr = REG(chan, 0);
+ cpr &= 0x405;
+ cpr |= CPR_CS(dev) | CPR_CLK(freq);
+ REG(chan, 0) = cpr;
+
+ if (exi->state & STATE_ATTACHED) {
+ switch (chan) {
+ case 0:
+ __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
+ break;
+ case 1:
+ __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
+ break;
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL EXIDeselect(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ u32 cpr;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ if (!(exi->state & STATE_SELECTED)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+ exi->state &= ~STATE_SELECTED;
+ cpr = REG(chan, 0);
+ REG(chan, 0) = cpr & 0x405;
+
+ if (exi->state & STATE_ATTACHED) {
+ switch (chan) {
+ case 0:
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXT);
+ break;
+ case 1:
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_EXI_1_EXT);
+ break;
+ }
+ }
+
+ OSRestoreInterrupts(enabled);
+
+ if (chan != 2 && (cpr & CPR_CS(0))) {
+ return __EXIProbe(chan) ? TRUE : FALSE;
+ }
+
+ return TRUE;
+}
+
+static void EXIIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
+ s32 chan;
+ EXIControl* exi;
+ EXICallback callback;
+
+ chan = (interrupt - __OS_INTERRUPT_EXI_0_EXI) / 3;
+ exi = &Ecb[chan];
+ EXIClearInterrupts(chan, TRUE, FALSE, FALSE);
+ callback = exi->exiCallback;
+ if (callback) {
+ OSContext exceptionContext;
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(&exceptionContext);
+
+ callback(chan, context);
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(context);
+ }
+}
+
+static void TCIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
+ OSContext exceptionContext;
+ s32 chan;
+ EXIControl* exi;
+ EXICallback callback;
+
+ chan = (interrupt - __OS_INTERRUPT_EXI_0_TC) / 3;
+ exi = &Ecb[chan];
+ __OSMaskInterrupts(OS_INTERRUPTMASK(interrupt));
+ EXIClearInterrupts(chan, FALSE, TRUE, FALSE);
+ callback = exi->tcCallback;
+ if (callback) {
+ exi->tcCallback = 0;
+ CompleteTransfer(chan);
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(&exceptionContext);
+
+ callback(chan, context);
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(context);
+ }
+}
+
+static void EXTIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
+ s32 chan;
+ EXIControl* exi;
+ EXICallback callback;
+
+ chan = (interrupt - __OS_INTERRUPT_EXI_0_EXT) / 3;
+ __OSMaskInterrupts((OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_0_EXI) >> (3 * chan));
+ exi = &Ecb[chan];
+ callback = exi->extCallback;
+ exi->state &= ~STATE_ATTACHED;
+ if (callback) {
+ OSContext exceptionContext;
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(&exceptionContext);
+
+ exi->extCallback = 0;
+ callback(chan, context);
+
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(context);
+ }
+}
+
+void EXIInit(void) {
+ OSRegisterVersion(__EXIVersion);
+
+ __OSMaskInterrupts(OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC |
+ OS_INTERRUPTMASK_EXI_0_EXT | OS_INTERRUPTMASK_EXI_1_EXI |
+ OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT |
+ OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC);
+
+ REG(0, 0) = 0;
+ REG(1, 0) = 0;
+ REG(2, 0) = 0;
+
+ REG(0, 0) = 0x00002000;
+
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXI, EXIIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_TC, TCIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_0_EXT, EXTIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXI, EXIIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_TC, TCIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_1_EXT, EXTIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_EXI, EXIIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_EXI_2_TC, TCIntrruptHandler);
+
+ if ((OSGetConsoleType() & 0x10000000) != 0) {
+ __EXIProbeStartTime[0] = __EXIProbeStartTime[1] = 0;
+ Ecb[0].idTime = Ecb[1].idTime = 0;
+ __EXIProbe(0);
+ __EXIProbe(1);
+ }
+}
+
+BOOL EXILock(s32 chan, u32 dev, EXICallback unlockedCallback) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+ int i;
+
+ enabled = OSDisableInterrupts();
+ if (exi->state & STATE_LOCKED) {
+ if (unlockedCallback) {
+ for (i = 0; i < exi->items; i++) {
+ if (exi->queue[i].dev == dev) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+ }
+ exi->queue[exi->items].callback = unlockedCallback;
+ exi->queue[exi->items].dev = dev;
+ exi->items++;
+ }
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ exi->state |= STATE_LOCKED;
+ exi->dev = dev;
+ SetExiInterruptMask(chan, exi);
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL EXIUnlock(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL enabled;
+ EXICallback unlockedCallback;
+
+ enabled = OSDisableInterrupts();
+ if (!(exi->state & STATE_LOCKED)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+ exi->state &= ~STATE_LOCKED;
+ SetExiInterruptMask(chan, exi);
+
+ if (0 < exi->items) {
+ unlockedCallback = exi->queue[0].callback;
+ if (0 < --exi->items) {
+ memmove(&exi->queue[0], &exi->queue[1], sizeof(exi->queue[0]) * exi->items);
+ }
+ unlockedCallback(chan, 0);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+u32 EXIGetState(s32 chan) {
+ EXIControl* exi = &Ecb[chan];
+
+ return (u32)exi->state;
+}
+
+static void UnlockedHandler(s32 chan, OSContext* context) {
+ u32 id;
+
+ EXIGetID(chan, 0, &id);
+}
+
+s32 EXIGetID(s32 chan, u32 dev, u32* id) {
+ EXIControl* exi = &Ecb[chan];
+ BOOL err;
+ u32 cmd;
+ s32 startTime;
+ BOOL enabled;
+
+ if (chan < 2 && dev == 0) {
+ if (!__EXIProbe(chan)) {
+ return 0;
+ }
+
+ if (exi->idTime == __EXIProbeStartTime[chan]) {
+ *id = exi->id;
+ return exi->idTime;
+ }
+
+ if (!__EXIAttach(chan, NULL)) {
+ return 0;
+ }
+
+ startTime = __EXIProbeStartTime[chan];
+ }
+
+ err = !EXILock(chan, dev, (chan < 2 && dev == 0) ? UnlockedHandler : NULL);
+ if (!err) {
+ err = !EXISelect(chan, dev, EXI_FREQ_1M);
+ if (!err) {
+ cmd = 0;
+ err |= !EXIImm(chan, &cmd, 2, EXI_WRITE, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIImm(chan, id, 4, EXI_READ, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIDeselect(chan);
+ }
+ EXIUnlock(chan);
+ }
+
+ if (chan < 2 && dev == 0) {
+ EXIDetach(chan);
+ enabled = OSDisableInterrupts();
+ err |= (startTime != __EXIProbeStartTime[chan]);
+ if (!err) {
+ exi->id = *id;
+ exi->idTime = startTime;
+ }
+ OSRestoreInterrupts(enabled);
+
+ return err ? 0 : exi->idTime;
+ }
+
+ return err ? 0 : !0;
+}
+
+char* EXIGetTypeString(u32 type) {
+ switch (type) {
+ case EXI_MEMORY_CARD_59:
+ return "Memory Card 59";
+ case EXI_MEMORY_CARD_123:
+ return "Memory Card 123";
+ case EXI_MEMORY_CARD_251:
+ return "Memory Card 251";
+ case EXI_MEMORY_CARD_507:
+ return "Memory Card 507";
+ case EXI_USB_ADAPTER:
+ return "USB Adapter";
+ case 0x80000000 | EXI_MEMORY_CARD_59:
+ case 0x80000000 | EXI_MEMORY_CARD_123:
+ case 0x80000000 | EXI_MEMORY_CARD_251:
+ case 0x80000000 | EXI_MEMORY_CARD_507:
+ return "Net Card";
+ case EXI_ETHER_VIEWER:
+ return "Artist Ether";
+ case EXI_STREAM_HANGER:
+ return "Stream Hanger";
+ case EXI_IS_VIEWER:
+ return "IS Viewer";
+ }
+}
+
+#pragma scheduling reset
diff --git a/src/Dolphin/exi/EXIUart.c b/src/Dolphin/exi/EXIUart.c
new file mode 100644
index 0000000..aafc628
--- /dev/null
+++ b/src/Dolphin/exi/EXIUart.c
@@ -0,0 +1,174 @@
+#include "dolphin/os.h"
+
+#define EXI_TX 0x800400u
+#define EXI_MAGIC 0xa5ff005a
+
+static s32 Chan;
+static u32 Dev;
+static u32 Enabled = 0;
+static u32 BarnacleEnabled = 0;
+
+static BOOL ProbeBarnacle(s32 chan, u32 dev, u32* revision) {
+ BOOL err;
+ u32 cmd;
+
+ if (chan != 2 && dev == 0 && !EXIAttach(chan, NULL)) {
+ return FALSE;
+ }
+
+ err = !EXILock(chan, dev, NULL);
+ if (!err) {
+ err = !EXISelect(chan, dev, EXI_FREQ_1M);
+ if (!err) {
+ cmd = 0x20011300;
+ err = FALSE;
+ err |= !EXIImm(chan, &cmd, 4, EXI_WRITE, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIImm(chan, revision, 4, EXI_READ, NULL);
+ err |= !EXISync(chan);
+ err |= !EXIDeselect(chan);
+ }
+ EXIUnlock(chan);
+ }
+
+ if (chan != 2 && dev == 0) {
+ EXIDetach(chan);
+ }
+
+ if (err) {
+ return FALSE;
+ }
+
+ return (*revision != 0xFFFFFFFF) ? TRUE : FALSE;
+}
+
+void __OSEnableBarnacle(s32 chan, u32 dev) {
+ u32 id;
+
+ if (EXIGetID(chan, dev, &id)) {
+ switch (id) {
+ case 0xffffffff:
+ case EXI_MEMORY_CARD_59:
+ case EXI_MEMORY_CARD_123:
+ case EXI_MEMORY_CARD_251:
+ case EXI_MEMORY_CARD_507:
+ case EXI_USB_ADAPTER:
+ case EXI_NPDP_GDEV:
+ case EXI_MODEM:
+ case EXI_MARLIN:
+ case 0x04220000:
+ case 0x04020100:
+ case 0x04020200:
+ case 0x04020300:
+ case 0x04040404:
+ case 0x04060000:
+ case 0x04120000:
+ case 0x04130000:
+ case 0x80000000 | EXI_MEMORY_CARD_59:
+ case 0x80000000 | EXI_MEMORY_CARD_123:
+ case 0x80000000 | EXI_MEMORY_CARD_251:
+ case 0x80000000 | EXI_MEMORY_CARD_507:
+ break;
+ default:
+ if (ProbeBarnacle(chan, dev, &id)) {
+ Chan = chan;
+ Dev = dev;
+ Enabled = BarnacleEnabled = EXI_MAGIC;
+ }
+ break;
+ }
+ }
+}
+
+u32 InitializeUART(u32 baudRate) {
+ if (BarnacleEnabled == EXI_MAGIC) {
+ return 0;
+ }
+
+ if (!(OSGetConsoleType() & OS_CONSOLE_DEVELOPMENT)) {
+ Enabled = 0;
+ return 2;
+ } else {
+ Chan = 0;
+ Dev = 1;
+ Enabled = EXI_MAGIC;
+ return 0;
+ }
+}
+
+u32 ReadUARTN(void* bytes, unsigned long length) { return 4; }
+
+static int QueueLength(void) {
+ u32 cmd;
+
+ if (!EXISelect(Chan, Dev, EXI_FREQ_8M))
+ return -1;
+
+ cmd = EXI_TX << 6;
+ EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
+ EXISync(Chan);
+
+ EXIImm(Chan, &cmd, 1, EXI_READ, NULL);
+ EXISync(Chan);
+ EXIDeselect(Chan);
+
+ return 16 - (int)((cmd >> 24) & 0xff);
+}
+
+u32 WriteUARTN(const void* buf, unsigned long len) {
+ u32 cmd;
+ int qLen;
+ long xLen;
+ char* ptr;
+ BOOL locked;
+ u32 error;
+
+ if (Enabled != EXI_MAGIC)
+ return 2;
+
+ locked = EXILock(Chan, Dev, 0);
+ if (!locked) {
+ return 0;
+ }
+
+ for (ptr = (char*)buf; ptr - buf < len; ptr++) {
+ if (*ptr == '\n')
+ *ptr = '\r';
+ }
+
+ error = 0;
+ cmd = (EXI_TX | 0x2000000) << 6;
+ while (len) {
+ qLen = QueueLength();
+ if (qLen < 0) {
+ error = 3;
+ break;
+ }
+
+ if (qLen < 12 && qLen < len)
+ continue;
+
+ if (!EXISelect(Chan, Dev, EXI_FREQ_8M)) {
+ error = 3;
+ break;
+ }
+
+ EXIImm(Chan, &cmd, 4, EXI_WRITE, NULL);
+ EXISync(Chan);
+
+ while (qLen && len) {
+ if (qLen < 4 && qLen < len)
+ break;
+ xLen = (len < 4) ? (long)len : 4;
+ EXIImm(Chan, (void*)buf, xLen, EXI_WRITE, NULL);
+ (u8*)buf += xLen;
+ len -= xLen;
+ qLen -= xLen;
+ EXISync(Chan);
+ }
+ EXIDeselect(Chan);
+ }
+
+ EXIUnlock(Chan);
+ return error;
+}
diff --git a/src/Dolphin/gx/GXLight.c b/src/Dolphin/gx/GXLight.c
new file mode 100644
index 0000000..a41b90e
--- /dev/null
+++ b/src/Dolphin/gx/GXLight.c
@@ -0,0 +1,271 @@
+#include "dolphin/gx.h"
+#include "dolphin/gx/GXPriv.h"
+
+extern float cosf(float x);
+extern float sqrtf(float x);
+
+#define GX_LARGE_NUMBER 1.0e+18f;
+
+void GXInitLightAttn(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ obj->a0 = a0;
+ obj->a1 = a1;
+ obj->a2 = a2;
+ obj->k0 = k0;
+ obj->k1 = k1;
+ obj->k2 = k2;
+}
+
+void GXInitLightAttnA(GXLightObj* lt_obj, f32 a0, f32 a1, f32 a2) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ obj->a0 = a0;
+ obj->a1 = a1;
+ obj->a2 = a2;
+}
+
+void GXGetLightAttnA(const GXLightObj* lt_obj, f32* a0, f32* a1, f32* a2) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ *a0 = obj->a0;
+ *a1 = obj->a1;
+ *a2 = obj->a2;
+}
+
+void GXInitLightAttnK(GXLightObj* lt_obj, f32 k0, f32 k1, f32 k2) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ obj->k0 = k0;
+ obj->k1 = k1;
+ obj->k2 = k2;
+}
+
+void GXGetLightAttnK(const GXLightObj* lt_obj, f32* k0, f32* k1, f32* k2) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ *k0 = obj->k0;
+ *k1 = obj->k1;
+ *k2 = obj->k2;
+}
+
+#define PI 3.14159265358979323846F
+
+void GXInitLightSpot(GXLightObj* lt_obj, f32 cutoff, GXSpotFn spot_func) {
+ f32 a0, a1, a2, r, d, cr;
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+
+ if (cutoff <= 0.0f || cutoff > 90.0f) {
+ spot_func = GX_SP_OFF;
+ }
+
+ r = cutoff * PI / 180.0f;
+ cr = cosf(r);
+
+ switch (spot_func) {
+ case GX_SP_FLAT:
+ a0 = -1000.0f * cr;
+ a1 = 1000.0f;
+ a2 = 0.0f;
+ break;
+ case GX_SP_COS:
+ a1 = 1.0f / (1.0f - cr);
+ a0 = -cr * a1;
+ a2 = 0.0f;
+ break;
+ case GX_SP_COS2:
+ a2 = 1.0f / (1.0f - cr);
+ a0 = 0.0f;
+ a1 = -cr * a2;
+ break;
+ case GX_SP_SHARP:
+ d = 1.0F / ((1.0F - cr) * (1.0F - cr));
+ a0 = cr * (cr - 2.0F) * d;
+ a1 = 2.0F * d;
+ a2 = -d;
+ break;
+ case GX_SP_RING1:
+ d = 1.0f / ((1.0f - cr) * (1.0F - cr));
+ a2 = -4.0f * d;
+ a0 = a2 * cr;
+ a1 = 4.0f * (1.0f + cr) * d;
+ break;
+ case GX_SP_RING2:
+ d = 1.0f / ((1.0f - cr) * (1.0F - cr));
+ a0 = 1.0f - 2.0f * cr * cr * d;
+ a1 = 4.0f * cr * d;
+ a2 = -2.0f * d;
+ break;
+ case GX_SP_OFF:
+ default:
+ a0 = 1.0f;
+ a1 = 0.0f;
+ a2 = 0.0f;
+ break;
+ }
+
+ obj->a0 = a0;
+ obj->a1 = a1;
+ obj->a2 = a2;
+}
+
+void GXInitLightDistAttn(GXLightObj* lt_obj, f32 ref_dist, f32 ref_br, GXDistAttnFn dist_func) {
+ f32 k0, k1, k2;
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+
+ if (ref_dist < 0.0F) {
+ dist_func = GX_DA_OFF;
+ }
+
+ if (ref_br <= 0.0F || ref_br >= 1.0F) {
+ dist_func = GX_DA_OFF;
+ }
+
+ switch (dist_func) {
+ case GX_DA_GENTLE:
+ k0 = 1.0F;
+ k1 = (1.0F - ref_br) / (ref_br * ref_dist);
+ k2 = 0.0F;
+ break;
+ case GX_DA_MEDIUM:
+ k0 = 1.0f;
+ k1 = 0.5f * (1.0f - ref_br) / (ref_br * ref_dist);
+ k2 = 0.5f * (1.0f - ref_br) / (ref_br * ref_dist * ref_dist);
+ break;
+ case GX_DA_STEEP:
+ k0 = 1.0f;
+ k1 = 0.0f;
+ k2 = (1.0f - ref_br) / (ref_br * ref_dist * ref_dist);
+ break;
+ case GX_DA_OFF:
+ default:
+ k0 = 1.0f;
+ k1 = 0.0f;
+ k2 = 0.0f;
+ break;
+ }
+
+ obj->k0 = k0;
+ obj->k1 = k1;
+ obj->k2 = k2;
+}
+
+void GXInitLightPos(GXLightObj* lt_obj, f32 x, f32 y, f32 z) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+
+ obj->px = x;
+ obj->py = y;
+ obj->pz = z;
+}
+
+void GXGetLightPos(const GXLightObj* lt_obj, f32* x, f32* y, f32* z) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ *x = obj->px;
+ *y = obj->py;
+ *z = obj->pz;
+}
+
+void GXInitLightDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+
+ obj->nx = -nx;
+ obj->ny = -ny;
+ obj->nz = -nz;
+}
+
+void GXGetLightDir(const GXLightObj* lt_obj, f32* nx, f32* ny, f32* nz) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ *nx = -(obj->nx);
+ *ny = -(obj->ny);
+ *nz = -(obj->nz);
+}
+
+void GXInitSpecularDir(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz) {
+ f32 mag;
+ f32 vx, vy, vz;
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+
+ vx = -nx;
+ vy = -ny;
+ vz = (-nz + 1.0F);
+ mag = vx * vx + vy * vy + vz * vz;
+
+ if (mag != 0.0f) {
+ mag = 1.0f / sqrtf(mag);
+ }
+
+ obj->px = vx * mag;
+ obj->py = vy * mag;
+ obj->pz = vz * mag;
+
+ obj->nx = nx * -GX_LARGE_NUMBER;
+ obj->ny = ny * -GX_LARGE_NUMBER;
+ obj->nz = nz * -GX_LARGE_NUMBER;
+}
+
+void GXInitSpecularDirHA(GXLightObj* lt_obj, f32 nx, f32 ny, f32 nz, f32 hx, f32 hy, f32 hz) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+
+ obj->nx = hx;
+ obj->ny = hy;
+ obj->nz = hz;
+
+ obj->px = nx * -GX_LARGE_NUMBER;
+ obj->py = ny * -GX_LARGE_NUMBER;
+ obj->pz = nz * -GX_LARGE_NUMBER;
+}
+
+void GXInitLightColor(GXLightObj* lt_obj, GXColor color) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ obj->color = *(u32*)(&color);
+}
+
+void GXGetLightColor(const GXLightObj* lt_obj, GXColor* color) {
+ GXLightObj_* obj = (GXLightObj_*)lt_obj;
+ *(u32*)color = obj->color;
+}
+
+static inline void PushLight(const register GXLightObj_* lt_obj, register void* dest) {
+ register u32 zero, color;
+ register f32 a0_a1, a2_k0, k1_k2;
+ register f32 px_py, pz_dx, dy_dz;
+
+ asm
+ {
+ lwz color, 12(lt_obj)
+ xor zero, zero, zero
+ psq_l a0_a1, 16(lt_obj), 0, 0
+ psq_l a2_k0, 24(lt_obj), 0, 0
+ psq_l k1_k2, 32(lt_obj), 0, 0
+ psq_l px_py, 40(lt_obj), 0, 0
+ psq_l pz_dx, 48(lt_obj), 0, 0
+ psq_l dy_dz, 56(lt_obj), 0, 0
+
+ stw zero, 0(dest)
+ stw zero, 0(dest)
+ stw zero, 0(dest)
+ stw color, 0(dest)
+ psq_st a0_a1, 0(dest), 0, 0
+ psq_st a2_k0, 0(dest), 0, 0
+ psq_st k1_k2, 0(dest), 0, 0
+ psq_st px_py, 0(dest), 0, 0
+ psq_st pz_dx, 0(dest), 0, 0
+ psq_st dy_dz, 0(dest), 0, 0
+ }
+}
+
+void GXLoadLightObjImm(GXLightObj* lt_obj, GXLightID light) {
+ u32 addr;
+ u32 idx;
+ GXLightObj_* obj;
+ obj = (GXLightObj_*)lt_obj;
+
+ idx = 31 - __cntlzw(light);
+ idx &= 7;
+
+ addr = XF_LIGHT_BASE + idx * XF_LIGHT_SIZE;
+
+ GX_WRITE_U8(16);
+ GX_WRITE_U32(addr | (XF_LIGHT_SIZE - 1) << 16);
+ PushLight(obj, (void*)GX_FIFO_ADDR);
+ __GXData->cpCRreg = 1;
+}
+
+void GXSetChanAmbColor(GXChannelID chan, GXColor color) {
+
+}
diff --git a/src/Dolphin/os/OS.c b/src/Dolphin/os/OS.c
new file mode 100644
index 0000000..f902d5b
--- /dev/null
+++ b/src/Dolphin/os/OS.c
@@ -0,0 +1,609 @@
+#include "dolphin/os.h"
+#include "dolphin/DVDPriv.h"
+#include "dolphin/db.h"
+#include "dolphin/os/OSBootInfo.h"
+
+extern OSTime __OSGetSystemTime();
+extern char _db_stack_end[];
+
+#define OS_BI2_DEBUG_ADDRESS 0x800000F4
+#define DEBUGFLAG_ADDR 0x800030E8
+#define OS_DEBUG_ADDRESS_2 0x800030E9
+#define OS_CURRENTCONTEXT_PADDR 0x00C0
+
+extern char* __OSResetSWInterruptHandler[];
+
+vu16 __OSDeviceCode : (OS_BASE_CACHED | 0x30E6);
+static DVDDriveInfo DriveInfo ATTRIBUTE_ALIGN(32);
+static DVDCommandBlock DriveBlock;
+
+static OSBootInfo* BootInfo;
+static u32* BI2DebugFlag;
+static u32* BI2DebugFlagHolder;
+__declspec(weak) BOOL __OSIsGcam = FALSE;
+static f64 ZeroF;
+static f32 ZeroPS[2];
+static BOOL AreWeInitialized = FALSE;
+static __OSExceptionHandler* OSExceptionTable;
+OSTime __OSStartTime;
+BOOL __OSInIPL;
+
+extern u8 __ArenaHi[];
+extern u8 __ArenaLo[];
+extern u32 __DVDLongFileNameFlag;
+extern u32 __PADSpec;
+
+#define OS_EXCEPTIONTABLE_ADDR 0x3000
+#define OS_DBJUMPPOINT_ADDR 0x60
+// memory locations for important stuff
+#define OS_CACHED_REGION_PREFIX 0x8000
+#define OS_BI2_DEBUG_ADDRESS 0x800000F4
+#define OS_BI2_DEBUGFLAG_OFFSET 0xC
+#define PAD3_BUTTON_ADDR 0x800030E4
+#define OS_DVD_DEVICECODE 0x800030E6
+#define DEBUGFLAG_ADDR 0x800030E8
+#define OS_DEBUG_ADDRESS_2 0x800030E9
+#define DB_EXCEPTIONRET_OFFSET 0xC
+#define DB_EXCEPTIONDEST_OFFSET 0x8
+#define MSR_RI_BIT 0x1E
+
+void OSDefaultExceptionHandler(__OSException exception, OSContext* context);
+extern BOOL __DBIsExceptionMarked(__OSException);
+static void OSExceptionInit(void);
+
+/* clang-format off */
+asm void __OSFPRInit(void)
+{
+ nofralloc
+
+ mfmsr r3
+ ori r3, r3, 0x2000
+ mtmsr r3
+
+ mfspr r3, 0x398
+ rlwinm. r3, r3, 3, 31, 31
+ beq SkipPairedSingles
+
+ lis r3, ZeroPS@ha
+ addi r3, r3, ZeroPS@l
+ psq_l fp0, 0(r3), 0, 0
+ ps_mr fp1, fp0
+ ps_mr fp2, fp0
+ ps_mr fp3, fp0
+ ps_mr fp4, fp0
+ ps_mr fp5, fp0
+ ps_mr fp6, fp0
+ ps_mr fp7, fp0
+ ps_mr fp8, fp0
+ ps_mr fp9, fp0
+ ps_mr fp10, fp0
+ ps_mr fp11, fp0
+ ps_mr fp12, fp0
+ ps_mr fp13, fp0
+ ps_mr fp14, fp0
+ ps_mr fp15, fp0
+ ps_mr fp16, fp0
+ ps_mr fp17, fp0
+ ps_mr fp18, fp0
+ ps_mr fp19, fp0
+ ps_mr fp20, fp0
+ ps_mr fp21, fp0
+ ps_mr fp22, fp0
+ ps_mr fp23, fp0
+ ps_mr fp24, fp0
+ ps_mr fp25, fp0
+ ps_mr fp26, fp0
+ ps_mr fp27, fp0
+ ps_mr fp28, fp0
+ ps_mr fp29, fp0
+ ps_mr fp30, fp0
+ ps_mr fp31, fp0
+
+SkipPairedSingles:
+ lfd fp0, ZeroF
+ fmr fp1, fp0
+ fmr fp2, fp0
+ fmr fp3, fp0
+ fmr fp4, fp0
+ fmr fp5, fp0
+ fmr fp6, fp0
+ fmr fp7, fp0
+ fmr fp8, fp0
+ fmr fp9, fp0
+ fmr fp10, fp0
+ fmr fp11, fp0
+ fmr fp12, fp0
+ fmr fp13, fp0
+ fmr fp14, fp0
+ fmr fp15, fp0
+ fmr fp16, fp0
+ fmr fp17, fp0
+ fmr fp18, fp0
+ fmr fp19, fp0
+ fmr fp20, fp0
+ fmr fp21, fp0
+ fmr fp22, fp0
+ fmr fp23, fp0
+ fmr fp24, fp0
+ fmr fp25, fp0
+ fmr fp26, fp0
+ fmr fp27, fp0
+ fmr fp28, fp0
+ fmr fp29, fp0
+ fmr fp30, fp0
+ fmr fp31, fp0
+
+ mtfsf 0xFF, fp0
+
+ blr
+}
+/* clang-format on */
+
+u32 OSGetConsoleType() {
+ if (BootInfo == NULL || BootInfo->consoleType == 0) {
+ return OS_CONSOLE_ARTHUR;
+ }
+ return BootInfo->consoleType;
+}
+
+void* __OSSavedRegionStart;
+void* __OSSavedRegionEnd;
+
+extern u32 BOOT_REGION_START : 0x812FDFF0; //(*(u32 *)0x812fdff0)
+extern u32 BOOT_REGION_END : 0x812FDFEC; //(*(u32 *)0x812fdfec)
+
+void ClearArena(void) {
+ if ((u32)(OSGetResetCode() + 0x80000000) != 0U) {
+ __OSSavedRegionStart = 0U;
+ __OSSavedRegionEnd = 0U;
+ memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo());
+ return;
+ }
+ __OSSavedRegionStart = (void*)BOOT_REGION_START;
+ __OSSavedRegionEnd = (void*)BOOT_REGION_END;
+ if (BOOT_REGION_START == 0U) {
+ memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo());
+ return;
+ }
+
+ if ((u32)OSGetArenaLo() < (u32)__OSSavedRegionStart) {
+ if ((u32)OSGetArenaHi() <= (u32)__OSSavedRegionStart) {
+ memset((u32)OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo());
+ return;
+ }
+ memset(OSGetArenaLo(), 0U, (u32)__OSSavedRegionStart - (u32)OSGetArenaLo());
+ if ((u32)OSGetArenaHi() > (u32)__OSSavedRegionEnd) {
+ memset((u32)__OSSavedRegionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSSavedRegionEnd);
+ }
+ }
+}
+
+static void InquiryCallback(s32 result, DVDCommandBlock* block) {
+ switch (block->state) {
+ case 0:
+ __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode);
+ break;
+ default:
+ __OSDeviceCode = 1;
+ break;
+ }
+}
+
+void OSInit(void) {
+ /*
+ Initializes the Dolphin operating system.
+ - most of the main operations get farmed out to other functions
+ - loading debug info and setting up heap bounds largely happen here
+ - a lot of OS reporting also gets controlled here
+ */
+ // pretty sure this is the min(/max) amount of pointers etc for the stack to match
+ BI2Debug* DebugInfo;
+ void* debugArenaLo;
+ u32 inputConsoleType;
+ u32 tdev;
+
+ // check if we've already done all this or not
+ if ((BOOL)AreWeInitialized == FALSE) { // fantastic name
+ AreWeInitialized = TRUE; // flag to make sure we don't have to do this again
+
+ // SYSTEM //
+ __OSStartTime = __OSGetSystemTime();
+ OSDisableInterrupts();
+
+ // set some PPC things
+ PPCDisableSpeculation();
+ PPCSetFpNonIEEEMode();
+
+ // DEBUG //
+ // load some DVD stuff
+ BI2DebugFlag = 0; // debug flag from the DVD BI2 header
+ BootInfo = (OSBootInfo*)OS_BASE_CACHED; // set pointer to BootInfo
+
+ __DVDLongFileNameFlag = (u32)0; // flag to tell us whether we make it through the debug loading
+
+ // time to grab a bunch of debug info from the DVD
+ // the address for where the BI2 debug info is, is stored at OS_BI2_DEBUG_ADDRESS
+ DebugInfo = (BI2Debug*)*((u32*)OS_BI2_DEBUG_ADDRESS);
+
+ // if the debug info address exists, grab some debug info
+ if (DebugInfo != NULL) {
+ BI2DebugFlag = &DebugInfo->debugFlag; // debug flag from DVD BI2
+ __PADSpec = (u32)DebugInfo->padSpec; // some other info from DVD BI2
+ *((u8*)DEBUGFLAG_ADDR) = (u8)*BI2DebugFlag; // store flag in mem
+ *((u8*)OS_DEBUG_ADDRESS_2) = (u8)__PADSpec; // store other info in mem
+ } else if (BootInfo->arenaHi) { // if the top of the heap is already set
+ BI2DebugFlagHolder = (u32*)*((u8*)DEBUGFLAG_ADDR); // grab whatever's stored at 0x800030E8
+ BI2DebugFlag = (u32*)&BI2DebugFlagHolder; // flag is then address of flag holder
+ __PADSpec = (u32) * ((u8*)OS_DEBUG_ADDRESS_2); // pad spec is whatever's at 0x800030E9
+ }
+
+ __DVDLongFileNameFlag = 1; // we made it through debug!
+
+ // HEAP //
+ // set up bottom of heap (ArenaLo)
+ // grab address from BootInfo if it exists, otherwise use default __ArenaLo
+ OSSetArenaLo((BootInfo->arenaLo == NULL) ? __ArenaLo : BootInfo->arenaLo);
+
+ // if the input arenaLo is null, and debug flag location exists (and flag is < 2),
+ // set arenaLo to just past the end of the db stack
+ if ((BootInfo->arenaLo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) {
+ debugArenaLo = (char*)(((u32)_db_stack_end + 0x1f) & ~0x1f);
+ OSSetArenaLo(debugArenaLo);
+ }
+
+ // set up top of heap (ArenaHi)
+ // grab address from BootInfo if it exists, otherwise use default __ArenaHi
+ OSSetArenaHi((BootInfo->arenaHi == NULL) ? __ArenaHi : BootInfo->arenaHi);
+
+ // OS INIT AND REPORT //
+ // initialise a whole bunch of OS stuff
+ OSExceptionInit();
+ __OSInitSystemCall();
+ OSInitAlarm();
+ __OSModuleInit();
+ __OSInterruptInit();
+ __OSSetInterruptHandler(__OS_INTERRUPT_PI_RSW, (void*)__OSResetSWInterruptHandler);
+ __OSContextInit();
+ __OSCacheInit();
+ EXIInit();
+ SIInit();
+ __OSInitSram();
+ __OSThreadInit();
+ __OSInitAudioSystem();
+ PPCMthid2(PPCMfhid2() & 0xBFFFFFFF);
+ if ((BOOL)__OSInIPL == FALSE) {
+ __OSInitMemoryProtection();
+ }
+
+ // begin OS reporting
+ OSReport("\nDolphin OS $Revision: 54 $.\n");
+ OSReport("Kernel built : %s %s\n", "Jun 5 2002", "02:09:12");
+ OSReport("Console Type : ");
+
+ // this is a function in the same file, but it doesn't seem to match
+ // inputConsoleType = OSGetConsoleType();
+
+ // inputConsoleType = (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) ?
+ // 0x10000002 : BootInfo->consoleType;
+ if (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) {
+ inputConsoleType = OS_CONSOLE_ARTHUR; // default console type
+ } else {
+ inputConsoleType = BootInfo->consoleType;
+ }
+
+ // work out what console type this corresponds to and report it
+ // consoleTypeSwitchHi = inputConsoleType & 0xF0000000;
+ switch (inputConsoleType & 0xffff0000) { // check "first" byte
+ case OS_CONSOLE_RETAIL:
+ OSReport("Retail %d\n", inputConsoleType);
+ break;
+ default:
+ switch (inputConsoleType & 0x0000ffff) { // if "first" byte is 2, check "the rest"
+ case OS_CONSOLE_EMULATOR:
+ OSReport("Mac Emulator\n");
+ break;
+ case OS_CONSOLE_PC_EMULATOR:
+ OSReport("PC Emulator\n");
+ break;
+ case OS_CONSOLE_ARTHUR:
+ OSReport("EPPC Arthur\n");
+ break;
+ case OS_CONSOLE_MINNOW:
+ OSReport("EPPC Minnow\n");
+ break;
+ default:
+ tdev = ((u32)inputConsoleType & 0x0000ffff);
+ OSReport("Development HW%d (%08x)\n", tdev - 3, inputConsoleType);
+ break;
+ }
+ break;
+ }
+
+ // report memory size
+ OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U);
+ // report heap bounds
+ OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi());
+
+ // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts
+ if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) {
+ EnableMetroTRKInterrupts();
+ }
+
+ // free up memory and re-enable things
+ ClearArena();
+ OSEnableInterrupts();
+
+ // check if we can load OS from IPL; if not, grab it from DVD (?)
+ if ((BOOL)__OSInIPL == FALSE) {
+ DVDInit();
+ if ((BOOL)__OSIsGcam) {
+ __OSDeviceCode = 0x9000;
+ return;
+ }
+ DCInvalidateRange(&DriveInfo, sizeof(DriveInfo));
+ DVDInquiryAsync((char*)&DriveBlock, &DriveInfo, InquiryCallback);
+ }
+ }
+}
+static u32 __OSExceptionLocations[] = {
+ 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000800,
+ 0x00000900, 0x00000C00, 0x00000D00, 0x00000F00, 0x00001300, 0x00001400, 0x00001700,
+};
+
+// dummy entry points to the OS Exception vector
+void __OSEVStart(void);
+void __OSEVEnd(void);
+void __OSEVSetNumber(void);
+void __OSExceptionVector(void);
+
+void __DBVECTOR(void);
+void __OSDBINTSTART(void);
+void __OSDBINTEND(void);
+void __OSDBJUMPSTART(void);
+void __OSDBJUMPEND(void);
+
+#define NOP 0x60000000
+
+__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler);
+
+/*
+ * --INFO--
+ * Address: 800EB654
+ * Size: 000280
+ */
+static void OSExceptionInit(void) {
+ __OSException exception;
+ void* destAddr;
+
+ // These two vars help us change the exception number embedded
+ // in the exception handler code.
+ u32* opCodeAddr;
+ u32 oldOpCode;
+
+ // Address range of the actual code to be copied.
+ u8* handlerStart;
+ u32 handlerSize;
+
+ // Install the first level exception vector.
+ opCodeAddr = (u32*)__OSEVSetNumber;
+ oldOpCode = *opCodeAddr;
+ handlerStart = (u8*)__OSEVStart;
+ handlerSize = (u32)((u8*)__OSEVEnd - (u8*)__OSEVStart);
+
+ // Install the DB integrator, only if we are the first OSInit to be run
+ destAddr = (void*)OSPhysicalToCached(OS_DBJUMPPOINT_ADDR);
+ if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2
+ {
+ DBPrintf("Installing OSDBIntegrator\n");
+ memcpy(destAddr, (void*)__OSDBINTSTART, (u32)__OSDBINTEND - (u32)__OSDBINTSTART);
+ DCFlushRangeNoSync(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART);
+ __sync();
+ ICInvalidateRange(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART);
+ }
+
+ // Copy the right vector into the table
+ for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) {
+ if (BI2DebugFlag && (*BI2DebugFlag >= 2) && __DBIsExceptionMarked(exception)) {
+ // this DBPrintf is suspicious.
+ DBPrintf(">>> OSINIT: exception %d commandeered by TRK\n", exception);
+ continue;
+ }
+
+ // Modify the copy of code in text before transferring
+ // to the exception table.
+ *opCodeAddr = oldOpCode | exception;
+
+ // Modify opcodes at __DBVECTOR if necessary
+ if (__DBIsExceptionMarked(exception)) {
+ DBPrintf(">>> OSINIT: exception %d vectored to debugger\n", exception);
+ memcpy((void*)__DBVECTOR, (void*)__OSDBJUMPSTART, (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART);
+ } else {
+ // make sure the opcodes are still nop
+ u32* ops = (u32*)__DBVECTOR;
+ int cb;
+
+ for (cb = 0; cb < (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART; cb += sizeof(u32)) {
+ *ops++ = NOP;
+ }
+ }
+
+ // Install the modified handler.
+ destAddr = (void*)OSPhysicalToCached(__OSExceptionLocations[(u32)exception]);
+ memcpy(destAddr, handlerStart, handlerSize);
+ DCFlushRangeNoSync(destAddr, handlerSize);
+ __sync();
+ ICInvalidateRange(destAddr, handlerSize);
+ }
+
+ // initialize pointer to exception table
+ OSExceptionTable = OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR);
+
+ // install default exception handlers
+ for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) {
+ __OSSetExceptionHandler(exception, OSDefaultExceptionHandler);
+ }
+
+ // restore the old opcode, so that we can re-start an application without
+ // downloading the text segments
+ *opCodeAddr = oldOpCode;
+
+ DBPrintf("Exceptions initialized...\n");
+}
+
+static asm void __OSDBIntegrator(void) {
+ /* clang-format off */
+ nofralloc
+entry __OSDBINTSTART
+ li r5, OS_DBINTERFACE_ADDR
+ mflr r3
+ stw r3, DB_EXCEPTIONRET_OFFSET(r5)
+ lwz r3, DB_EXCEPTIONDEST_OFFSET(r5)
+ oris r3, r3, OS_CACHED_REGION_PREFIX
+ mtlr r3
+ li r3, 0x30 // MSR_IR | MSR_DR // turn on memory addressing
+ mtmsr r3
+ blr
+entry __OSDBINTEND
+ /* clang-format on */
+}
+
+static asm void __OSDBJump(void){
+ /* clang-format off */
+
+ nofralloc
+entry __OSDBJUMPSTART
+ bla OS_DBJUMPPOINT_ADDR
+entry __OSDBJUMPEND
+ /* clang-format on */
+
+}
+
+__OSExceptionHandler
+ __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) {
+ __OSExceptionHandler oldHandler;
+ oldHandler = OSExceptionTable[exception];
+ OSExceptionTable[exception] = handler;
+ return oldHandler;
+}
+
+__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) {
+ return OSExceptionTable[exception];
+}
+
+static asm void OSExceptionVector(void) {
+ /* clang-format off */
+ nofralloc
+
+entry __OSEVStart
+ // Save r4 into SPRG0
+ mtsprg 0, r4
+
+ // Load current context physical address into r4
+ lwz r4, OS_CURRENTCONTEXT_PADDR
+
+ // Save r3 - r5 into the current context
+ stw r3, OS_CONTEXT_R3(r4)
+ mfsprg r3, 0
+ stw r3, OS_CONTEXT_R4(r4)
+ stw r5, OS_CONTEXT_R5(r4)
+
+ lhz r3, OS_CONTEXT_STATE(r4)
+ ori r3, r3, OS_CONTEXT_STATE_EXC
+ sth r3, OS_CONTEXT_STATE(r4)
+
+ // Save misc registers
+ mfcr r3
+ stw r3, OS_CONTEXT_CR(r4)
+ mflr r3
+ stw r3, OS_CONTEXT_LR(r4)
+ mfctr r3
+ stw r3, OS_CONTEXT_CTR(r4)
+ mfxer r3
+ stw r3, OS_CONTEXT_XER(r4)
+ mfsrr0 r3
+ stw r3, OS_CONTEXT_SRR0(r4)
+ mfsrr1 r3
+ stw r3, OS_CONTEXT_SRR1(r4)
+ mr r5, r3
+
+entry __DBVECTOR
+ nop
+
+ // Set SRR1[IR|DR] to turn on address
+ // translation at the next RFI
+ mfmsr r3
+ ori r3, r3, 0x30
+ mtsrr1 r3
+
+ // This lets us change the exception number based on the
+ // exception we're installing.
+entry __OSEVSetNumber
+ addi r3, 0, 0x0000
+
+ // Load current context virtual address into r4
+ lwz r4, 0xD4
+
+ // Check non-recoverable interrupt
+ rlwinm. r5, r5, 0, MSR_RI_BIT, MSR_RI_BIT
+ bne recoverable
+ addis r5, 0, OSDefaultExceptionHandler@ha
+ addi r5, r5, OSDefaultExceptionHandler@l
+ mtsrr0 r5
+ rfi
+ // NOT REACHED HERE
+
+recoverable:
+ // Locate exception handler.
+ rlwinm r5, r3, 2, 22, 29 // r5 contains exception*4
+ lwz r5, OS_EXCEPTIONTABLE_ADDR(r5)
+ mtsrr0 r5
+
+ // Final state
+ // r3 - exception number
+ // r4 - pointer to context
+ // r5 - garbage
+ // srr0 - exception handler
+ // srr1 - address translation enalbed, not yet recoverable
+
+ rfi
+ // NOT REACHED HERE
+ // The handler will restore state
+
+entry __OSEVEnd
+ nop
+ /* clang-format on */
+}
+
+void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar);
+asm void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) {
+ /* clang-format off */
+ nofralloc
+ OS_EXCEPTION_SAVE_GPRS(context)
+ mfdsisr r5
+ mfdar r6
+
+ stwu r1,-8(r1)
+ b __OSUnhandledException
+ /* clang-foramt on */
+}
+
+void __OSPSInit(void)
+{
+ PPCMthid2(PPCMfhid2() | 0xA0000000);
+ ICFlashInvalidate();
+ __sync();
+ // clang-format off
+ asm
+ {
+ li r3, 0
+ mtspr GQR0, r3
+ }
+ // clang-format on
+}
+
+vu32 __DIRegs[16] : 0xCC006000;
+#define DI_CONFIG_IDX 0x9
+#define DI_CONFIG_CONFIG_MASK 0xFF
+u32 __OSGetDIConfig(void) { return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); }
+
+void OSRegisterVersion(const char* id) { OSReport("%s\n", id); }
diff --git a/src/Dolphin/os/OSAlarm.c b/src/Dolphin/os/OSAlarm.c
new file mode 100644
index 0000000..d362ceb
--- /dev/null
+++ b/src/Dolphin/os/OSAlarm.c
@@ -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
+}
diff --git a/src/Dolphin/os/OSAlloc.c b/src/Dolphin/os/OSAlloc.c
new file mode 100644
index 0000000..2850380
--- /dev/null
+++ b/src/Dolphin/os/OSAlloc.c
@@ -0,0 +1,195 @@
+#include "dolphin/os.h"
+
+typedef struct OSHeapDescriptor {
+ s32 size; // at 0x0
+ struct OSHeapCell* freeList; // at 0x4
+ struct OSHeapCell* usedList; // at 0x8
+} OSHeapDescriptor;
+
+typedef struct OSHeapCell {
+ struct OSHeapCell* prev; // at 0x0
+ struct OSHeapCell* next; // at 0x4
+ s32 size; // at 0x8
+ struct OSHeapDescriptor* hd; // at 0xC
+ s32 usedSize; // at 0x10
+ char UNK_0x14[0x20 - 0x14];
+} OSHeapCell;
+
+volatile s32 __OSCurrHeap = -1;
+
+static void* ArenaEnd = NULL;
+static void* ArenaStart = NULL;
+static s32 NumHeaps = 0;
+static OSHeapDescriptor* HeapArray = NULL;
+
+static OSHeapCell* DLAddFront(OSHeapCell* list, OSHeapCell* child) {
+ child->next = list;
+ child->prev = NULL;
+
+ if (list != NULL) {
+ list->prev = child;
+ }
+
+ return child;
+}
+
+static OSHeapCell* DLExtract(OSHeapCell* list, OSHeapCell* child) {
+ if (child->next != NULL) {
+ child->next->prev = child->prev;
+ }
+
+ if (child->prev == NULL) {
+ return child->next;
+ }
+
+ child->prev->next = child->next;
+ return list;
+}
+
+static OSHeapCell* DLInsert(OSHeapCell* list, OSHeapCell* child) {
+ OSHeapCell* prev = NULL;
+ OSHeapCell* next = list;
+
+ for (; next != NULL; prev = next, next = next->next) {
+ if (child <= next) {
+ break;
+ }
+ }
+
+ child->next = next;
+ child->prev = prev;
+
+ if (next != NULL) {
+ next->prev = child;
+
+ if ((u8*)child + child->size == (u8*)next) {
+ child->size += next->size;
+ next = next->next;
+ child->next = next;
+ if (next != NULL) {
+ next->prev = child;
+ }
+ }
+ }
+
+ if (prev != NULL) {
+ prev->next = child;
+
+ if ((u8*)prev + prev->size == (u8*)child) {
+ prev->size += child->size;
+ prev->next = next;
+ if (next != NULL) {
+ next->prev = prev;
+ }
+ }
+
+ return list;
+ } else {
+ return child;
+ }
+}
+
+void* OSAllocFromHeap(s32 handle, s32 size) {
+ OSHeapDescriptor* hd = &HeapArray[handle];
+ OSHeapCell* cell;
+ u32 avail;
+
+ hd = &HeapArray[handle];
+ size = OSRoundUp32B(size + sizeof(OSHeapCell));
+
+ for (cell = hd->freeList; cell != NULL; cell = cell->next) {
+ if (size <= cell->size) {
+ break;
+ }
+ }
+
+ if (cell == NULL) {
+ return NULL;
+ }
+
+ avail = cell->size - size;
+ if (avail < 64) {
+ hd->freeList = DLExtract(hd->freeList, cell);
+ } else {
+ OSHeapCell* adj;
+ cell->size = size;
+
+ adj = (OSHeapCell*)((u8*)cell + size);
+ adj->size = avail;
+ adj->prev = cell->prev;
+ adj->next = cell->next;
+
+ if (adj->next != NULL) {
+ adj->next->prev = adj;
+ }
+
+ if (adj->prev != NULL) {
+ adj->prev->next = adj;
+ } else {
+ hd->freeList = adj;
+ }
+ }
+
+ hd->usedList = DLAddFront(hd->usedList, cell);
+ return (u8*)cell + sizeof(OSHeapCell);
+}
+
+void OSFreeToHeap(s32 handle, void* p) {
+ OSHeapDescriptor* hd = &HeapArray[handle];
+ OSHeapCell* cell = (OSHeapCell*)((u8*)p - sizeof(OSHeapCell));
+ hd->usedList = DLExtract(hd->usedList, cell);
+ hd->freeList = DLInsert(hd->freeList, cell);
+}
+
+s32 OSSetCurrentHeap(s32 handle) {
+ s32 old = __OSCurrHeap;
+ __OSCurrHeap = handle;
+ return old;
+}
+
+void* OSInitAlloc(void* start, void* end, s32 numHeaps) {
+ u32 headerSize;
+ int i;
+
+ headerSize = numHeaps * sizeof(OSHeapDescriptor);
+ HeapArray = (OSHeapDescriptor*)start;
+ NumHeaps = numHeaps;
+
+ for (i = 0; i < NumHeaps; i++) {
+ OSHeapDescriptor* hd = &HeapArray[i];
+ hd->size = -1;
+ hd->usedList = NULL;
+ hd->freeList = NULL;
+ }
+
+ __OSCurrHeap = -1;
+ ArenaStart = OSRoundUp32BPtr((u8*)HeapArray + headerSize);
+ ArenaEnd = OSRoundDown32BPtr(end);
+
+ return ArenaStart;
+}
+
+s32 OSCreateHeap(void* start, void* end) {
+ s32 handle;
+
+ start = OSRoundUp32BPtr(start);
+ end = OSRoundDown32BPtr(end);
+
+ for (handle = 0; handle < NumHeaps; handle++) {
+ OSHeapCell* cell = (OSHeapCell*)start;
+ OSHeapDescriptor* hd = &HeapArray[handle];
+ if (hd->size < 0) {
+ hd->size = (u32)end - (u32)start;
+
+ cell->prev = NULL;
+ cell->next = NULL;
+ cell->size = hd->size;
+
+ hd->freeList = cell;
+ hd->usedList = NULL;
+ return handle;
+ }
+ }
+
+ return -1;
+}
diff --git a/src/Dolphin/os/OSArena.c b/src/Dolphin/os/OSArena.c
new file mode 100644
index 0000000..da864ab
--- /dev/null
+++ b/src/Dolphin/os/OSArena.c
@@ -0,0 +1,39 @@
+#include <dolphin/os/OSArena.h>
+
+#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1))
+#define TRUNC(n, a) (((u32)(n)) & ~((a)-1))
+
+void* __OSArenaHi;
+void* __OSArenaLo = (void*)-1;
+
+void* OSGetArenaHi(void) { return __OSArenaHi; }
+
+void* OSGetArenaLo(void) { return __OSArenaLo; }
+
+void OSSetArenaHi(void* addr) { __OSArenaHi = addr; }
+
+void OSSetArenaLo(void* addr) { __OSArenaLo = addr; }
+
+void* OSAllocFromArenaLo(u32 size, u32 align) {
+ void* ptr;
+ u8* arenaLo;
+
+ ptr = OSGetArenaLo();
+ arenaLo = ptr = (void*)ROUND(ptr, align);
+ arenaLo += size;
+ arenaLo = (u8*)ROUND(arenaLo, align);
+ OSSetArenaLo(arenaLo);
+ return ptr;
+}
+
+void* OSAllocFromArenaHi(u32 size, u32 align) {
+ void* ptr;
+ u8* arenaHi;
+
+ arenaHi = OSGetArenaHi();
+ arenaHi = (u8*)TRUNC(arenaHi, align);
+ arenaHi -= size;
+ arenaHi = ptr = (void*)TRUNC(arenaHi, align);
+ OSSetArenaHi(arenaHi);
+ return ptr;
+}
diff --git a/src/Dolphin/os/OSAudioSystem.c b/src/Dolphin/os/OSAudioSystem.c
new file mode 100644
index 0000000..1eddcbf
--- /dev/null
+++ b/src/Dolphin/os/OSAudioSystem.c
@@ -0,0 +1,115 @@
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static u8 DSPInitCode[128] = {
+ // clang-format off
+ 0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35,
+ 0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39,
+ 0x12, 0x06, 0x12, 0x03, 0x12, 0x04, 0x12, 0x05, 0x00, 0x80, 0x80, 0x00, 0x00, 0x88, 0xFF, 0xFF,
+ 0x00, 0x84, 0x10, 0x00, 0x00, 0x64, 0x00, 0x1D, 0x02, 0x18, 0x00, 0x00, 0x81, 0x00, 0x1C, 0x1E,
+ 0x00, 0x44, 0x1B, 0x1E, 0x00, 0x84, 0x08, 0x00, 0x00, 0x64, 0x00, 0x27, 0x19, 0x1E, 0x00, 0x00,
+ 0x00, 0xDE, 0xFF, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x28, 0x16, 0xFC, 0x00, 0x54,
+ 0x16, 0xFD, 0x43, 0x48, 0x00, 0x21, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF,
+ 0x02, 0xFF, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // clang-format on
+};
+
+volatile u16 __DSPRegs[] : 0xCC005000;
+#define __DSPWorkBuffer (void*)0x81000000
+
+void __OSInitAudioSystem(void) {
+ u32 r28;
+ u16 r3;
+
+ u32 padding;
+
+ memcpy((void*)((u8*)OSGetArenaHi() - 128), __DSPWorkBuffer, 128);
+ memcpy(__DSPWorkBuffer, (void*)DSPInitCode, 128);
+
+ DCFlushRange(__DSPWorkBuffer, 128);
+
+ __DSPRegs[9] = 0x43;
+ __DSPRegs[5] = 0x8AC;
+ __DSPRegs[5] |= 1;
+ while (__DSPRegs[5] & 1)
+ ;
+ __DSPRegs[0] = 0;
+ while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000)
+ ;
+ *(u32*)&__DSPRegs[16] = 0x1000000;
+ *(u32*)&__DSPRegs[18] = 0;
+ *(u32*)&__DSPRegs[20] = 0x20;
+
+ r3 = __DSPRegs[5];
+ while (!(r3 & 0x20))
+ r3 = __DSPRegs[5];
+ __DSPRegs[5] = r3;
+
+ r28 = OSGetTick();
+ while ((s32)(OSGetTick() - r28) < 0x892)
+ ;
+
+ *(u32*)&__DSPRegs[16] = 0x1000000;
+ *(u32*)&__DSPRegs[18] = 0;
+ *(u32*)&__DSPRegs[20] = 0x20;
+
+ r3 = __DSPRegs[5];
+ while (!(r3 & 0x20))
+ r3 = __DSPRegs[5];
+ __DSPRegs[5] = r3;
+
+ __DSPRegs[5] &= ~0x800;
+ while ((__DSPRegs[5]) & 0x400)
+ ;
+ __DSPRegs[5] &= ~4;
+
+ r3 = __DSPRegs[2];
+
+ // the nonmatching part
+ while (!(r3 & 0x8000))
+ r3 = __DSPRegs[2];
+
+ (void)__DSPRegs[3];
+ r3 != 42069;
+ __DSPRegs[5] |= 4;
+ __DSPRegs[5] = 0x8AC;
+ __DSPRegs[5] |= 1;
+ while (__DSPRegs[5] & 1)
+ ;
+ memcpy(__DSPWorkBuffer, (void*)((u8*)OSGetArenaHi() - 128), 128);
+}
+
+void __OSStopAudioSystem(void) {
+ u32 r28;
+
+#define waitUntil(load, mask) \
+ r28 = (load); \
+ while (r28 & (mask)) { \
+ r28 = (load); \
+ }
+
+ __DSPRegs[5] = 0x804;
+ r28 = __DSPRegs[27];
+ __DSPRegs[27] = r28 & ~0x8000;
+ waitUntil(__DSPRegs[5], 0x400);
+ waitUntil(__DSPRegs[5], 0x200);
+ __DSPRegs[5] = 0x8ac;
+ __DSPRegs[0] = 0;
+
+ while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000)
+ ;
+ r28 = OSGetTick();
+ while ((s32)(OSGetTick() - r28) < 0x2c)
+ ;
+ __DSPRegs[5] |= 1;
+ waitUntil(__DSPRegs[5], 0x001);
+
+#undef waitUntil
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/Dolphin/os/OSCache.c b/src/Dolphin/os/OSCache.c
new file mode 100644
index 0000000..f0d7895
--- /dev/null
+++ b/src/Dolphin/os/OSCache.c
@@ -0,0 +1,426 @@
+#include "dolphin/PPCArch.h"
+#include "dolphin/os.h"
+
+// Can't use this due to weird condition register issues
+//#include "asm_types.h"
+#define HID2 920
+
+#include "dolphin/db.h"
+
+/* clang-format off */
+asm void DCEnable() {
+ nofralloc
+ sync
+ mfspr r3, HID0
+ ori r3, r3, 0x4000
+ mtspr HID0, r3
+ blr
+}
+
+asm void DCInvalidateRange(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ dcbi r0, addr
+ addi addr, addr, 32
+ bdnz @1
+ blr
+}
+
+
+asm void DCFlushRange(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ dcbf r0, addr
+ addi addr, addr, 32
+ bdnz @1
+ sc
+ blr
+}
+
+asm void DCStoreRange(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ dcbst r0, addr
+ addi addr, addr, 32
+ bdnz @1
+ sc
+
+ blr
+}
+
+asm void DCFlushRangeNoSync(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ dcbf r0, addr
+ addi addr, addr, 32
+ bdnz @1
+ blr
+}
+
+
+asm void DCStoreRangeNoSync(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ dcbst r0, addr
+ addi addr, addr, 32
+ bdnz @1
+
+ blr
+}
+
+asm void DCZeroRange(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ dcbz r0, addr
+ addi addr, addr, 32
+ bdnz @1
+
+ blr
+}
+
+
+asm void ICInvalidateRange(register void* addr, register u32 nBytes) {
+ nofralloc
+ cmplwi nBytes, 0
+ blelr
+ clrlwi r5, addr, 27
+ add nBytes, nBytes, r5
+ addi nBytes, nBytes, 31
+ srwi nBytes, nBytes, 5
+ mtctr nBytes
+
+@1
+ icbi r0, addr
+ addi addr, addr, 32
+ bdnz @1
+ sync
+ isync
+
+ blr
+}
+
+
+asm void ICFlashInvalidate() {
+ nofralloc
+ mfspr r3, HID0
+ ori r3, r3, 0x800
+ mtspr HID0, r3
+ blr
+}
+
+asm void ICEnable() {
+ nofralloc
+ isync
+ mfspr r3, HID0
+ ori r3, r3, 0x8000
+ mtspr HID0, r3
+ blr
+}
+
+#define LC_LINES 512
+#define CACHE_LINES 1024
+
+asm void __LCEnable() {
+ nofralloc
+ mfmsr r5
+ ori r5, r5, 0x1000
+ mtmsr r5
+
+ 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
+
+ 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
+
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ blr
+}
+
+void LCEnable() {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ __LCEnable();
+ OSRestoreInterrupts(enabled);
+}
+
+
+asm void LCDisable() {
+ nofralloc
+ lis r3, LC_BASE_PREFIX
+ li r4, LC_LINES
+ mtctr r4
+@1
+ dcbi r0, r3
+ addi r3, r3, 32
+ bdnz @1
+ mfspr r4, HID2
+ rlwinm r4, r4, 0, 4, 2
+ mtspr HID2, r4
+ blr
+}
+
+
+asm void LCLoadBlocks(register void* destTag, register void* srcAddr, register u32 numBlocks) {
+ nofralloc
+ rlwinm r6, numBlocks, 30, 27, 31
+ rlwinm srcAddr, srcAddr, 0, 4, 31
+ or r6, r6, srcAddr
+ mtspr DMA_U, r6
+ rlwinm r6, numBlocks, 2, 28, 29
+ or r6, r6, destTag
+ ori r6, r6, 0x12
+ mtspr DMA_L, r6
+ blr
+}
+
+asm void LCStoreBlocks(register void* destAddr, register void* srcTag, register u32 numBlocks) {
+ nofralloc
+ rlwinm r6, numBlocks, 30, 27, 31
+ rlwinm destAddr, destAddr, 0, 4, 31
+ or r6, r6, destAddr
+ mtspr DMA_U, r6
+ rlwinm r6, numBlocks, 2, 28, 29
+ or r6, r6, srcTag
+ ori r6, r6, 0x2
+ mtspr DMA_L, r6
+ blr
+}
+
+/* clang-format on */
+
+u32 LCLoadData(register void* destAddr, register void* srcAddr, register u32 nBytes) {
+ u32 numBlocks = (nBytes + 31) / 32;
+ u32 numTransactions = (numBlocks + 128 - 1) / 128;
+
+ while (numBlocks > 0) {
+ if (numBlocks < 128) {
+ LCLoadBlocks(destAddr, srcAddr, numBlocks);
+ numBlocks = 0;
+ } else {
+ LCLoadBlocks(destAddr, srcAddr, 0);
+ numBlocks -= 128;
+ destAddr = (void*)((u32)destAddr + 4096);
+ srcAddr = (void*)((u32)srcAddr + 4096);
+ }
+ }
+
+ return numTransactions;
+}
+u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) {
+ u32 numBlocks = (nBytes + 31) / 32;
+ u32 numTransactions = (numBlocks + 128 - 1) / 128;
+
+ while (numBlocks > 0) {
+ if (numBlocks < 128) {
+ LCStoreBlocks(destAddr, srcAddr, numBlocks);
+ numBlocks = 0;
+ } else {
+ LCStoreBlocks(destAddr, srcAddr, 0);
+ numBlocks -= 128;
+ destAddr = (void*)((u32)destAddr + 4096);
+ srcAddr = (void*)((u32)srcAddr + 4096);
+ }
+ }
+
+ return numTransactions;
+}
+
+/* clang-format off */
+asm u32 LCQueueLength() {
+ nofralloc
+ mfspr r4, HID2
+ rlwinm r3, r4, 8, 28, 31
+ blr
+}
+
+asm void LCQueueWait(register u32 len) {
+ nofralloc
+ addi len, len, 1
+@1
+ mfspr r4, HID2
+ rlwinm r4, r4, 8, 28, 31
+ cmpw cr2, r4, r3
+ bge cr2, @1
+ blr
+}
+
+/* clang-format on */
+static void L2Disable(void) {
+ __sync();
+ PPCMtl2cr(PPCMfl2cr() & ~0x80000000);
+ __sync();
+}
+
+void L2GlobalInvalidate(void) {
+ L2Disable();
+ PPCMtl2cr(PPCMfl2cr() | 0x00200000);
+ while (PPCMfl2cr() & 0x00000001u)
+ ;
+ PPCMtl2cr(PPCMfl2cr() & ~0x00200000);
+ while (PPCMfl2cr() & 0x00000001u) {
+ DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n");
+ }
+}
+
+static void L2Init(void) {
+ u32 oldMSR;
+ oldMSR = PPCMfmsr();
+ __sync();
+ PPCMtmsr(MSR_IR | MSR_DR);
+ __sync();
+ L2Disable();
+ L2GlobalInvalidate();
+ PPCMtmsr(oldMSR);
+}
+
+void L2Enable(void) { PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); }
+
+void DMAErrorHandler(OSError error, OSContext* context, ...) {
+ u32 hid2 = PPCMfhid2();
+
+ OSReport("Machine check received\n");
+ OSReport("HID2 = 0x%x SRR1 = 0x%x\n", hid2, context->srr1);
+ if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) ||
+ !(context->srr1 & SRR1_DMA_BIT)) {
+ OSReport("Machine check was not DMA/locked cache related\n");
+ OSDumpContext(context);
+ PPCHalt();
+ }
+
+ OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n");
+ OSReport("The following errors have been detected and cleared :\n");
+
+ if (hid2 & HID2_DCHERR) {
+ OSReport("\t- Requested a locked cache tag that was already in the cache\n");
+ }
+
+ if (hid2 & HID2_DNCERR) {
+ OSReport("\t- DMA attempted to access normal cache\n");
+ }
+
+ if (hid2 & HID2_DCMERR) {
+ OSReport("\t- DMA missed in data cache\n");
+ }
+
+ if (hid2 & HID2_DQOERR) {
+ OSReport("\t- DMA queue overflowed\n");
+ }
+
+ // write hid2 back to clear the error bits
+ PPCMthid2(hid2);
+}
+
+void __OSCacheInit() {
+ if (!(PPCMfhid0() & HID0_ICE)) {
+ ICEnable();
+ DBPrintf("L1 i-caches initialized\n");
+ }
+ if (!(PPCMfhid0() & HID0_DCE)) {
+ DCEnable();
+ DBPrintf("L1 d-caches initialized\n");
+ }
+
+ if (!(PPCMfl2cr() & L2CR_L2E)) {
+ L2Init();
+ L2Enable();
+ DBPrintf("L2 cache initialized\n");
+ }
+
+ OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler);
+ DBPrintf("Locked cache machine check handler installed\n");
+}
diff --git a/src/Dolphin/os/OSContext.c b/src/Dolphin/os/OSContext.c
new file mode 100644
index 0000000..6acefe4
--- /dev/null
+++ b/src/Dolphin/os/OSContext.c
@@ -0,0 +1,550 @@
+#include <dolphin/os.h>
+#include <dolphin/db.h>
+
+#define HID2 920
+
+volatile OSContext* __OSCurrentContext : (OS_BASE_CACHED | 0x00D4);
+volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8);
+
+static asm void __OSLoadFPUContext(register u32, register OSContext* fpuContext) {
+ // clang-format off
+ nofralloc
+ lhz r5, fpuContext->state;
+ clrlwi. r5, r5, 31
+ beq _return
+
+ lfd fp0, OS_CONTEXT_FPSCR(fpuContext)
+ mtfsf 0xFF, fp0
+ mfspr r5, HID2
+ rlwinm. r5, r5, 3, 31, 31
+ beq _regular_FPRs
+
+ psq_l fp0, OS_CONTEXT_PSF0(fpuContext), 0, 0
+ psq_l fp1, OS_CONTEXT_PSF1(fpuContext), 0, 0
+ psq_l fp2, OS_CONTEXT_PSF2(fpuContext), 0, 0
+ psq_l fp3, OS_CONTEXT_PSF3(fpuContext), 0, 0
+ psq_l fp4, OS_CONTEXT_PSF4(fpuContext), 0, 0
+ psq_l fp5, OS_CONTEXT_PSF5(fpuContext), 0, 0
+ psq_l fp6, OS_CONTEXT_PSF6(fpuContext), 0, 0
+ psq_l fp7, OS_CONTEXT_PSF7(fpuContext), 0, 0
+ psq_l fp8, OS_CONTEXT_PSF8(fpuContext), 0, 0
+ psq_l fp9, OS_CONTEXT_PSF9(fpuContext), 0, 0
+ psq_l fp10, OS_CONTEXT_PSF10(fpuContext), 0, 0
+ psq_l fp11, OS_CONTEXT_PSF11(fpuContext), 0, 0
+ psq_l fp12, OS_CONTEXT_PSF12(fpuContext), 0, 0
+ psq_l fp13, OS_CONTEXT_PSF13(fpuContext), 0, 0
+ psq_l fp14, OS_CONTEXT_PSF14(fpuContext), 0, 0
+ psq_l fp15, OS_CONTEXT_PSF15(fpuContext), 0, 0
+ psq_l fp16, OS_CONTEXT_PSF16(fpuContext), 0, 0
+ psq_l fp17, OS_CONTEXT_PSF17(fpuContext), 0, 0
+ psq_l fp18, OS_CONTEXT_PSF18(fpuContext), 0, 0
+ psq_l fp19, OS_CONTEXT_PSF19(fpuContext), 0, 0
+ psq_l fp20, OS_CONTEXT_PSF20(fpuContext), 0, 0
+ psq_l fp21, OS_CONTEXT_PSF21(fpuContext), 0, 0
+ psq_l fp22, OS_CONTEXT_PSF22(fpuContext), 0, 0
+ psq_l fp23, OS_CONTEXT_PSF23(fpuContext), 0, 0
+ psq_l fp24, OS_CONTEXT_PSF24(fpuContext), 0, 0
+ psq_l fp25, OS_CONTEXT_PSF25(fpuContext), 0, 0
+ psq_l fp26, OS_CONTEXT_PSF26(fpuContext), 0, 0
+ psq_l fp27, OS_CONTEXT_PSF27(fpuContext), 0, 0
+ psq_l fp28, OS_CONTEXT_PSF28(fpuContext), 0, 0
+ psq_l fp29, OS_CONTEXT_PSF29(fpuContext), 0, 0
+ psq_l fp30, OS_CONTEXT_PSF30(fpuContext), 0, 0
+ psq_l fp31, OS_CONTEXT_PSF31(fpuContext), 0, 0
+
+_regular_FPRs:
+ lfd fp0, fpuContext->fpr[0]
+ lfd fp1, fpuContext->fpr[1]
+ lfd fp2, fpuContext->fpr[2]
+ lfd fp3, fpuContext->fpr[3]
+ lfd fp4, fpuContext->fpr[4]
+ lfd fp5, fpuContext->fpr[5]
+ lfd fp6, fpuContext->fpr[6]
+ lfd fp7, fpuContext->fpr[7]
+ lfd fp8, fpuContext->fpr[8]
+ lfd fp9, fpuContext->fpr[9]
+ lfd fp10, fpuContext->fpr[10]
+ lfd fp11, fpuContext->fpr[11]
+ lfd fp12, fpuContext->fpr[12]
+ lfd fp13, fpuContext->fpr[13]
+ lfd fp14, fpuContext->fpr[14]
+ lfd fp15, fpuContext->fpr[15]
+ lfd fp16, fpuContext->fpr[16]
+ lfd fp17, fpuContext->fpr[17]
+ lfd fp18, fpuContext->fpr[18]
+ lfd fp19, fpuContext->fpr[19]
+ lfd fp20, fpuContext->fpr[20]
+ lfd fp21, fpuContext->fpr[21]
+ lfd fp22, fpuContext->fpr[22]
+ lfd fp23, fpuContext->fpr[23]
+ lfd fp24, fpuContext->fpr[24]
+ lfd fp25, fpuContext->fpr[25]
+ lfd fp26, fpuContext->fpr[26]
+ lfd fp27, fpuContext->fpr[27]
+ lfd fp28, fpuContext->fpr[28]
+ lfd fp29, fpuContext->fpr[29]
+ lfd fp30, fpuContext->fpr[30]
+ lfd fp31, fpuContext->fpr[31]
+_return:
+ blr
+ // clang-format on
+}
+
+static asm void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext) {
+ // clang-format off
+ nofralloc
+
+ lhz r3, fpuContext->state
+ ori r3, r3, 1
+ sth r3, fpuContext->state
+
+ stfd fp0, fpuContext->fpr[0]
+ stfd fp1, fpuContext->fpr[1]
+ stfd fp2, fpuContext->fpr[2]
+ stfd fp3, fpuContext->fpr[3]
+ stfd fp4, fpuContext->fpr[4]
+ stfd fp5, fpuContext->fpr[5]
+ stfd fp6, fpuContext->fpr[6]
+ stfd fp7, fpuContext->fpr[7]
+ stfd fp8, fpuContext->fpr[8]
+ stfd fp9, fpuContext->fpr[9]
+ stfd fp10, fpuContext->fpr[10]
+ stfd fp11, fpuContext->fpr[11]
+ stfd fp12, fpuContext->fpr[12]
+ stfd fp13, fpuContext->fpr[13]
+ stfd fp14, fpuContext->fpr[14]
+ stfd fp15, fpuContext->fpr[15]
+ stfd fp16, fpuContext->fpr[16]
+ stfd fp17, fpuContext->fpr[17]
+ stfd fp18, fpuContext->fpr[18]
+ stfd fp19, fpuContext->fpr[19]
+ stfd fp20, fpuContext->fpr[20]
+ stfd fp21, fpuContext->fpr[21]
+ stfd fp22, fpuContext->fpr[22]
+ stfd fp23, fpuContext->fpr[23]
+ stfd fp24, fpuContext->fpr[24]
+ stfd fp25, fpuContext->fpr[25]
+ stfd fp26, fpuContext->fpr[26]
+ stfd fp27, fpuContext->fpr[27]
+ stfd fp28, fpuContext->fpr[28]
+ stfd fp29, fpuContext->fpr[29]
+ stfd fp30, fpuContext->fpr[30]
+ stfd fp31, fpuContext->fpr[31]
+
+ mffs fp0
+ stfd fp0, OS_CONTEXT_FPSCR(fpuContext)
+
+ lfd fp0, fpuContext->fpr[0]
+
+ mfspr r3, HID2
+ rlwinm. r3, r3, 3, 31, 31
+ bc 12, 2, _return
+
+ psq_st fp0, OS_CONTEXT_PSF0(fpuContext), 0, 0
+ psq_st fp1, OS_CONTEXT_PSF1(fpuContext), 0, 0
+ psq_st fp2, OS_CONTEXT_PSF2(fpuContext), 0, 0
+ psq_st fp3, OS_CONTEXT_PSF3(fpuContext), 0, 0
+ psq_st fp4, OS_CONTEXT_PSF4(fpuContext), 0, 0
+ psq_st fp5, OS_CONTEXT_PSF5(fpuContext), 0, 0
+ psq_st fp6, OS_CONTEXT_PSF6(fpuContext), 0, 0
+ psq_st fp7, OS_CONTEXT_PSF7(fpuContext), 0, 0
+ psq_st fp8, OS_CONTEXT_PSF8(fpuContext), 0, 0
+ psq_st fp9, OS_CONTEXT_PSF9(fpuContext), 0, 0
+ psq_st fp10, OS_CONTEXT_PSF10(fpuContext), 0, 0
+ psq_st fp11, OS_CONTEXT_PSF11(fpuContext), 0, 0
+ psq_st fp12, OS_CONTEXT_PSF12(fpuContext), 0, 0
+ psq_st fp13, OS_CONTEXT_PSF13(fpuContext), 0, 0
+ psq_st fp14, OS_CONTEXT_PSF14(fpuContext), 0, 0
+ psq_st fp15, OS_CONTEXT_PSF15(fpuContext), 0, 0
+ psq_st fp16, OS_CONTEXT_PSF16(fpuContext), 0, 0
+ psq_st fp17, OS_CONTEXT_PSF17(fpuContext), 0, 0
+ psq_st fp18, OS_CONTEXT_PSF18(fpuContext), 0, 0
+ psq_st fp19, OS_CONTEXT_PSF19(fpuContext), 0, 0
+ psq_st fp20, OS_CONTEXT_PSF20(fpuContext), 0, 0
+ psq_st fp21, OS_CONTEXT_PSF21(fpuContext), 0, 0
+ psq_st fp22, OS_CONTEXT_PSF22(fpuContext), 0, 0
+ psq_st fp23, OS_CONTEXT_PSF23(fpuContext), 0, 0
+ psq_st fp24, OS_CONTEXT_PSF24(fpuContext), 0, 0
+ psq_st fp25, OS_CONTEXT_PSF25(fpuContext), 0, 0
+ psq_st fp26, OS_CONTEXT_PSF26(fpuContext), 0, 0
+ psq_st fp27, OS_CONTEXT_PSF27(fpuContext), 0, 0
+ psq_st fp28, OS_CONTEXT_PSF28(fpuContext), 0, 0
+ psq_st fp29, OS_CONTEXT_PSF29(fpuContext), 0, 0
+ psq_st fp30, OS_CONTEXT_PSF30(fpuContext), 0, 0
+ psq_st fp31, OS_CONTEXT_PSF31(fpuContext), 0, 0
+
+_return:
+ blr
+ // clang-format on
+}
+
+asm void OSLoadFPUContext(register OSContext* fpuContext) {
+ // clang-format off
+ nofralloc
+ addi r4, fpuContext, 0
+ b __OSLoadFPUContext
+ // clang-format on
+}
+
+asm void OSSaveFPUContext(register OSContext* fpuContext) {
+ // clang-format off
+ nofralloc
+ addi r5, fpuContext, 0
+ b __OSSaveFPUContext
+ // clang-format on
+}
+
+asm void OSSetCurrentContext(register OSContext* context){
+ // clang-format off
+ nofralloc
+
+ addis r4, r0, OS_CACHED_REGION_PREFIX
+
+ stw context, 0x00D4(r4)
+
+ clrlwi r5, context, 2
+ stw r5, 0x00C0(r4)
+
+ lwz r5, 0x00D8(r4)
+ cmpw r5, context
+ bne _disableFPU
+
+ lwz r6, context->srr1
+ ori r6, r6, 0x2000
+ stw r6, context->srr1
+ mfmsr r6
+ ori r6, r6, 2
+ mtmsr r6
+ blr
+
+_disableFPU:
+ lwz r6, context->srr1
+ rlwinm r6, r6, 0, 19, 17
+ stw r6, context->srr1
+ mfmsr r6
+ rlwinm r6, r6, 0, 19, 17
+ ori r6, r6, 2
+ mtmsr r6
+ isync
+ blr
+ // clang-format on
+}
+
+OSContext* OSGetCurrentContext(void) {
+ return (OSContext*)__OSCurrentContext;
+}
+
+asm u32 OSSaveContext(register OSContext* context) {
+ // clang-format off
+ nofralloc
+ stmw r13, context->gpr[13]
+ mfspr r0, GQR1
+ stw r0, context->gqr[1]
+ mfspr r0, GQR2
+ stw r0, context->gqr[2]
+ mfspr r0, GQR3
+ stw r0, context->gqr[3]
+ mfspr r0, GQR4
+ stw r0, context->gqr[4]
+ mfspr r0, GQR5
+ stw r0, context->gqr[5]
+ mfspr r0, GQR6
+ stw r0, context->gqr[6]
+ mfspr r0, GQR7
+ stw r0, context->gqr[7]
+ mfcr r0
+ stw r0, context->cr
+ mflr r0
+ stw r0, context->lr
+ stw r0, context->srr0
+ mfmsr r0
+ stw r0, context->srr1
+ mfctr r0
+ stw r0, context->ctr
+ mfxer r0
+ stw r0, context->xer
+ stw r1, context->gpr[1]
+ stw r2, context->gpr[2]
+ li r0, 0x1
+ stw r0, context->gpr[3]
+ li r3, 0
+ blr
+ // clang-format on
+}
+
+extern void __RAS_OSDisableInterrupts_begin();
+extern void __RAS_OSDisableInterrupts_end();
+
+asm void OSLoadContext(register OSContext* context) {
+ // clang-format off
+ nofralloc
+
+ lis r4,__RAS_OSDisableInterrupts_begin@ha
+ lwz r6,context->srr0
+ addi r5,r4,__RAS_OSDisableInterrupts_begin@l
+ cmplw r6,r5
+ ble _notInRAS
+ lis r4,__RAS_OSDisableInterrupts_end@ha
+ addi r0,r4,__RAS_OSDisableInterrupts_end@l
+ cmplw r6,r0
+ bge _notInRAS
+ stw r5,context->srr0
+
+_notInRAS:
+
+ lwz r0, context->gpr[0]
+ lwz r1, context->gpr[1]
+ lwz r2, context->gpr[2]
+
+ lhz r4, context->state
+ rlwinm. r5, r4, 0, 30, 30
+ beq notexc
+ rlwinm r4, r4, 0, 31, 29
+ sth r4, context->state
+ lmw r5, context->gpr[5]
+ b misc
+notexc:
+ lmw r13, context->gpr[13]
+misc:
+
+ lwz r4, context->gqr[1]
+ mtspr GQR1, r4
+ lwz r4, context->gqr[2]
+ mtspr GQR2, r4
+ lwz r4, context->gqr[3]
+ mtspr GQR3, r4
+ lwz r4, context->gqr[4]
+ mtspr GQR4, r4
+ lwz r4, context->gqr[5]
+ mtspr GQR5, r4
+ lwz r4, context->gqr[6]
+ mtspr GQR6, r4
+ lwz r4, context->gqr[7]
+ mtspr GQR7, r4
+
+ lwz r4, context->cr
+ mtcr r4
+ lwz r4, context->lr
+ mtlr r4
+ lwz r4, context->ctr
+ mtctr r4
+ lwz r4, context->xer
+ mtxer r4
+
+ mfmsr r4
+ rlwinm r4, r4, 0, 17, 15
+ rlwinm r4, r4, 0, 31, 29
+ mtmsr r4
+
+ lwz r4, context->srr0
+ mtsrr0 r4
+ lwz r4, context->srr1
+ mtsrr1 r4
+
+ lwz r4, context->gpr[4]
+ lwz r3, context->gpr[3]
+
+ rfi
+ // clang-format on
+}
+
+asm u32 OSGetStackPointer() {
+ // clang-format off
+ nofralloc
+ mr r3, r1
+ blr
+ // clang-format on
+}
+
+asm u32 OSSwitchStack(register u32 newsp) {
+ // clang-format off
+ nofralloc
+ mr r5, r1
+ mr r1, newsp
+ mr r3, r5
+ blr
+ // clang-format on
+}
+
+asm int OSSwitchFiber(register u32 pc, register u32 newsp) {
+ // clang-format off
+ nofralloc
+ mflr r0
+ mr r5, r1
+ stwu r5, -8(newsp)
+ mr r1, newsp
+ stw r0, 4(r5)
+ mtlr pc
+ blrl
+ lwz r5, 0(r1)
+ lwz r0, 4(r5)
+ mtlr r0
+ mr r1, r5
+ blr
+ // clang-format on
+}
+
+void OSClearContext(register OSContext* context) {
+ context->mode = 0;
+ context->state = 0;
+ if (context == __OSFPUContext)
+ __OSFPUContext = NULL;
+}
+
+asm void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) {
+ // clang-format off
+ nofralloc
+
+ stw pc, OS_CONTEXT_SRR0(context)
+ stw newsp, OS_CONTEXT_R1(context)
+ li r11, 0
+ ori r11, r11, 0x00008000 | 0x00000020 | 0x00000010 | 0x00000002 | 0x00001000
+ stw r11, OS_CONTEXT_SRR1(context)
+ li r0, 0x0
+ stw r0, OS_CONTEXT_CR(context)
+ stw r0, OS_CONTEXT_XER(context)
+
+
+ stw r2, OS_CONTEXT_R2(context)
+ stw r13, OS_CONTEXT_R13(context)
+
+ stw r0, OS_CONTEXT_R3(context)
+ stw r0, OS_CONTEXT_R4(context)
+ stw r0, OS_CONTEXT_R5(context)
+ stw r0, OS_CONTEXT_R6(context)
+ stw r0, OS_CONTEXT_R7(context)
+ stw r0, OS_CONTEXT_R8(context)
+ stw r0, OS_CONTEXT_R9(context)
+ stw r0, OS_CONTEXT_R10(context)
+ stw r0, OS_CONTEXT_R11(context)
+ stw r0, OS_CONTEXT_R12(context)
+
+ stw r0, OS_CONTEXT_R14(context)
+ stw r0, OS_CONTEXT_R15(context)
+ stw r0, OS_CONTEXT_R16(context)
+ stw r0, OS_CONTEXT_R17(context)
+ stw r0, OS_CONTEXT_R18(context)
+ stw r0, OS_CONTEXT_R19(context)
+ stw r0, OS_CONTEXT_R20(context)
+ stw r0, OS_CONTEXT_R21(context)
+ stw r0, OS_CONTEXT_R22(context)
+ stw r0, OS_CONTEXT_R23(context)
+ stw r0, OS_CONTEXT_R24(context)
+ stw r0, OS_CONTEXT_R25(context)
+ stw r0, OS_CONTEXT_R26(context)
+ stw r0, OS_CONTEXT_R27(context)
+ stw r0, OS_CONTEXT_R28(context)
+ stw r0, OS_CONTEXT_R29(context)
+ stw r0, OS_CONTEXT_R30(context)
+ stw r0, OS_CONTEXT_R31(context)
+
+ stw r0, OS_CONTEXT_GQR0(context)
+ stw r0, OS_CONTEXT_GQR1(context)
+ stw r0, OS_CONTEXT_GQR2(context)
+ stw r0, OS_CONTEXT_GQR3(context)
+ stw r0, OS_CONTEXT_GQR4(context)
+ stw r0, OS_CONTEXT_GQR5(context)
+ stw r0, OS_CONTEXT_GQR6(context)
+ stw r0, OS_CONTEXT_GQR7(context)
+
+ b OSClearContext
+ // clang-format on
+}
+
+void OSDumpContext(OSContext* context) {
+ u32 i;
+ u32* p;
+
+ OSReport("------------------------- Context 0x%08x -------------------------\n", context);
+
+ for (i = 0; i < 16; ++i) {
+ OSReport("r%-2d = 0x%08x (%14d) r%-2d = 0x%08x (%14d)\n", i, context->gpr[i],
+ context->gpr[i], i + 16, context->gpr[i + 16], context->gpr[i + 16]);
+ }
+
+ OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr);
+ OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1);
+
+ OSReport("\nGQRs----------\n");
+ for (i = 0; i < 4; ++i) {
+ OSReport("gqr%d = 0x%08x \t gqr%d = 0x%08x\n", i, context->gqr[i], i + 4, context->gqr[i + 4]);
+ }
+
+ if (context->state & OS_CONTEXT_STATE_FPSAVED) {
+ OSContext* currentContext;
+ OSContext fpuContext;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ currentContext = OSGetCurrentContext();
+ OSClearContext(&fpuContext);
+ OSSetCurrentContext(&fpuContext);
+
+ OSReport("\n\nFPRs----------\n");
+ for (i = 0; i < 32; i += 2) {
+ OSReport("fr%d \t= %d \t fr%d \t= %d\n", i, (u32)context->fpr[i], i + 1,
+ (u32)context->fpr[i + 1]);
+ }
+ OSReport("\n\nPSFs----------\n");
+ for (i = 0; i < 32; i += 2) {
+ OSReport("ps%d \t= 0x%x \t ps%d \t= 0x%x\n", i, (u32)context->psf[i], i + 1,
+ (u32)context->psf[i + 1]);
+ }
+
+ OSClearContext(&fpuContext);
+ OSSetCurrentContext(currentContext);
+ OSRestoreInterrupts(enabled);
+ }
+
+ OSReport("\nAddress: Back Chain LR Save\n");
+ for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) {
+ OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]);
+ }
+}
+
+static asm void OSSwitchFPUContext(register __OSException exception, register OSContext* context) {
+ // clang-format off
+ nofralloc
+ mfmsr r5
+ ori r5, r5, 0x2000
+ mtmsr r5
+ isync
+ lwz r5, OS_CONTEXT_SRR1(context)
+ ori r5, r5, 0x2000
+ mtsrr1 r5
+ addis r3, r0, OS_CACHED_REGION_PREFIX
+ lwz r5, 0x00D8(r3)
+ stw context, 0x00D8(r3)
+ cmpw r5, r4
+ beq _restoreAndExit
+ cmpwi r5, 0x0
+ beq _loadNewFPUContext
+ bl __OSSaveFPUContext
+_loadNewFPUContext:
+ bl __OSLoadFPUContext
+_restoreAndExit:
+ lwz r3, OS_CONTEXT_CR(context)
+ mtcr r3
+ lwz r3, OS_CONTEXT_LR(context)
+ mtlr r3
+ lwz r3, OS_CONTEXT_SRR0(context)
+ mtsrr0 r3
+ lwz r3, OS_CONTEXT_CTR(context)
+ mtctr r3
+ lwz r3, OS_CONTEXT_XER(context)
+ mtxer r3
+ lhz r3, context->state
+ rlwinm r3, r3, 0, 31, 29
+ sth r3, context->state
+ lwz r5, OS_CONTEXT_R5(context)
+ lwz r3, OS_CONTEXT_R3(context)
+ lwz r4, OS_CONTEXT_R4(context)
+ rfi
+ // clang-format on
+}
+
+void __OSContextInit(void) {
+ __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext);
+ __OSFPUContext = NULL;
+ DBPrintf("FPU-unavailable handler installed\n");
+}
diff --git a/src/Dolphin/os/OSError.c b/src/Dolphin/os/OSError.c
new file mode 100644
index 0000000..3859a62
--- /dev/null
+++ b/src/Dolphin/os/OSError.c
@@ -0,0 +1,360 @@
+#include <dolphin/PPCArch.h>
+#include <dolphin/dsp_regs.h>
+#include <dolphin/dvd_regs.h>
+#include <dolphin/os.h>
+#include <stdio.h>
+
+OSThread* __OSCurrentThread : (OS_BASE_CACHED | 0x00E4);
+OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC);
+volatile OSContext* __OSFPUContext : (OS_BASE_CACHED | 0x00D8);
+
+OSErrorHandler __OSErrorTable[OS_ERROR_MAX];
+#define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE)
+u32 __OSFpscrEnableBits = FPSCR_ENABLE;
+
+__declspec(weak) void OSReport(const char* msg, ...) {
+ va_list args;
+ va_start(args, msg);
+ vprintf(msg, args);
+ va_end(args);
+}
+
+__declspec(weak) void OSVReport(const char* msg, va_list list) { vprintf(msg, list); }
+
+__declspec(weak) void OSPanic(const char* file, int line, const char* msg, ...) {
+ va_list marker;
+ u32 i;
+ u32* p;
+
+ OSDisableInterrupts();
+ va_start(marker, msg);
+ vprintf(msg, marker);
+ va_end(marker);
+ OSReport(" in \"%s\" on line %d.\n", file, line);
+
+ OSReport("\nAddress: Back Chain LR Save\n");
+ for (i = 0, p = (u32*)OSGetStackPointer(); p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) {
+ OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]);
+ }
+
+ PPCHalt();
+}
+
+#ifdef FULL_FRANK
+OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) {
+ OSErrorHandler oldHandler;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ oldHandler = __OSErrorTable[error];
+ __OSErrorTable[error] = handler;
+
+ if (error == OS_ERROR_FPE) {
+ u32 msr;
+ u32 fpscr;
+ OSThread* thread;
+
+ msr = PPCMfmsr();
+ PPCMtmsr(msr | MSR_FP);
+ fpscr = PPCMffpscr();
+ if (handler) {
+ for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) {
+ thread->context.srr1 |= MSR_FE0 | MSR_FE1;
+ if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) {
+ int i;
+ thread->context.state |= OS_CONTEXT_STATE_FPSAVED;
+ for (i = 0; i < 32; ++i) {
+ *(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL;
+ *(u64*)&thread->context.psf[i] = (u64)0xffffffffffffffffLL;
+ }
+ thread->context.fpscr = FPSCR_NI;
+ }
+ thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE;
+ thread->context.fpscr &=
+ ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN |
+ FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX |
+ FPSCR_OX | FPSCR_FX | FPSCR_FI);
+ }
+ fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE;
+ msr |= MSR_FE0 | MSR_FE1;
+ } else {
+ for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) {
+ thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1);
+ thread->context.fpscr &= ~FPSCR_ENABLE;
+ thread->context.fpscr &=
+ ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN |
+ FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX |
+ FPSCR_OX | FPSCR_FX | FPSCR_FI);
+ }
+ fpscr &= ~FPSCR_ENABLE;
+ msr &= ~(MSR_FE0 | MSR_FE1);
+ }
+
+ fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN |
+ FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX |
+ FPSCR_OX | FPSCR_FX | FPSCR_FI);
+
+ PPCMtfpscr(fpscr);
+ PPCMtmsr(msr);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return oldHandler;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x30(r1)
+ stw r31, 0x2c(r1)
+ stw r30, 0x28(r1)
+ stw r29, 0x24(r1)
+ addi r29, r3, 0
+ stw r28, 0x20(r1)
+ addi r28, r4, 0
+ bl OSDisableInterrupts
+ lis r4, __OSErrorTable@ha
+ rlwinm r5, r29, 2, 0xe, 0x1d
+ addi r0, r4, __OSErrorTable@l
+ clrlwi r6, r29, 0x10
+ add r4, r0, r5
+ lwz r30, 0(r4)
+ cmplwi r6, 0x10
+ mr r29, r3
+ stw r28, 0(r4)
+ bne lbl_8037FD44
+ bl PPCMfmsr
+ addi r31, r3, 0
+ ori r3, r31, 0x2000
+ bl PPCMtmsr
+ bl PPCMffpscr
+ cmplwi r28, 0
+ beq lbl_8037FCD8
+ lis r5, __OSActiveThreadQueue@ha
+ lis r4, 0x6005F8FF@ha
+ lwz r6, __OSActiveThreadQueue@l(r5)
+ addi r4, r4, 0x6005F8FF@l
+ b lbl_8037FCBC
+lbl_8037FBD8:
+ lwz r0, 0x19c(r6)
+ ori r0, r0, 0x900
+ stw r0, 0x19c(r6)
+ lhz r5, 0x1a2(r6)
+ clrlwi. r0, r5, 0x1f
+ bne lbl_8037FC98
+ ori r5, r5, 1
+ li r0, 4
+ sth r5, 0x1a2(r6)
+ mtctr r0
+ addi r5, r6, 0
+lbl_8037FC04:
+ li r0, -1
+ stw r0, 0x94(r5)
+ stw r0, 0x90(r5)
+ stw r0, 0x1cc(r5)
+ stw r0, 0x1c8(r5)
+ stw r0, 0x9c(r5)
+ stw r0, 0x98(r5)
+ stw r0, 0x1d4(r5)
+ stw r0, 0x1d0(r5)
+ stw r0, 0xa4(r5)
+ stw r0, 0xa0(r5)
+ stw r0, 0x1dc(r5)
+ stw r0, 0x1d8(r5)
+ stw r0, 0xac(r5)
+ stw r0, 0xa8(r5)
+ stw r0, 0x1e4(r5)
+ stw r0, 0x1e0(r5)
+ stw r0, 0xb4(r5)
+ stw r0, 0xb0(r5)
+ stw r0, 0x1ec(r5)
+ stw r0, 0x1e8(r5)
+ stw r0, 0xbc(r5)
+ stw r0, 0xb8(r5)
+ stw r0, 0x1f4(r5)
+ stw r0, 0x1f0(r5)
+ stw r0, 0xc4(r5)
+ stw r0, 0xc0(r5)
+ stw r0, 0x1fc(r5)
+ stw r0, 0x1f8(r5)
+ stw r0, 0xcc(r5)
+ stw r0, 0xc8(r5)
+ stw r0, 0x204(r5)
+ stw r0, 0x200(r5)
+ addi r5, r5, 0x40
+ bdnz lbl_8037FC04
+ li r0, 4
+ stw r0, 0x194(r6)
+lbl_8037FC98:
+ lwz r0, __OSFpscrEnableBits
+ lwz r5, 0x194(r6)
+ rlwinm r0, r0, 0, 0x18, 0x1c
+ or r0, r5, r0
+ stw r0, 0x194(r6)
+ lwz r0, 0x194(r6)
+ and r0, r0, r4
+ stw r0, 0x194(r6)
+ lwz r6, 0x2fc(r6)
+lbl_8037FCBC:
+ cmplwi r6, 0
+ bne lbl_8037FBD8
+ lwz r0, __OSFpscrEnableBits
+ ori r31, r31, 0x900
+ rlwinm r0, r0, 0, 0x18, 0x1c
+ or r3, r3, r0
+ b lbl_8037FD2C
+lbl_8037FCD8:
+ lis r5, __OSActiveThreadQueue@ha
+ lis r4, 0x6005F8FF@ha
+ lwz r6, __OSActiveThreadQueue@l(r5)
+ addi r4, r4, 0x6005F8FF@l
+ li r5, -2305
+ b lbl_8037FD18
+lbl_8037FCF0:
+ lwz r0, 0x19c(r6)
+ and r0, r0, r5
+ stw r0, 0x19c(r6)
+ lwz r0, 0x194(r6)
+ rlwinm r0, r0, 0, 0x1d, 0x17
+ stw r0, 0x194(r6)
+ lwz r0, 0x194(r6)
+ and r0, r0, r4
+ stw r0, 0x194(r6)
+ lwz r6, 0x2fc(r6)
+lbl_8037FD18:
+ cmplwi r6, 0
+ bne lbl_8037FCF0
+ li r0, -2305
+ rlwinm r3, r3, 0, 0x1d, 0x17
+ and r31, r31, r0
+lbl_8037FD2C:
+ lis r4, 0x6005F8FF@ha
+ addi r0, r4, 0x6005F8FF@l
+ and r3, r3, r0
+ bl PPCMtfpscr
+ mr r3, r31
+ bl PPCMtmsr
+lbl_8037FD44:
+ mr r3, r29
+ bl OSRestoreInterrupts
+ mr r3, r30
+ lwz r0, 0x34(r1)
+ lwz r31, 0x2c(r1)
+ lwz r30, 0x28(r1)
+ lwz r29, 0x24(r1)
+ lwz r28, 0x20(r1)
+ addi r1, r1, 0x30
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) {
+ OSTime now;
+
+ now = OSGetTime();
+
+ if (!(context->srr1 & MSR_RI)) {
+ OSReport("Non-recoverable Exception %d", exception);
+ } else {
+ if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) &&
+ __OSErrorTable[OS_ERROR_FPE] != 0) {
+ u32 fpscr;
+ u32 msr;
+
+ exception = OS_ERROR_FPE;
+
+ msr = PPCMfmsr();
+ PPCMtmsr(msr | MSR_FP);
+
+ if (__OSFPUContext) {
+ OSSaveFPUContext((OSContext*)__OSFPUContext);
+ }
+
+ fpscr = PPCMffpscr();
+ fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN |
+ FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX |
+ FPSCR_OX | FPSCR_FX | FPSCR_FI);
+ PPCMtfpscr(fpscr);
+
+ PPCMtmsr(msr);
+
+ if (__OSFPUContext == context) {
+ OSDisableScheduler();
+ __OSErrorTable[exception](exception, context, dsisr, dar);
+ context->srr1 &= ~MSR_FP;
+ __OSFPUContext = NULL;
+
+ context->fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI |
+ FPSCR_VXSNAN | FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX |
+ FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI);
+ OSEnableScheduler();
+ __OSReschedule();
+ } else {
+ context->srr1 &= ~MSR_FP;
+ __OSFPUContext = NULL;
+ }
+
+ OSLoadContext(context);
+ }
+
+ if (__OSErrorTable[exception]) {
+ OSDisableScheduler();
+ __OSErrorTable[exception](exception, context, dsisr, dar);
+ OSEnableScheduler();
+ __OSReschedule();
+ OSLoadContext(context);
+ }
+
+ if (exception == OS_ERROR_DECREMENTER) {
+ OSLoadContext(context);
+ }
+
+ OSReport("Unhandled Exception %d", exception);
+ }
+
+ OSReport("\n");
+ OSDumpContext(context);
+ OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar);
+ OSReport("TB = 0x%016llx\n", now);
+
+ switch (exception) {
+ case __OS_EXCEPTION_DSI:
+ OSReport("\nInstruction at 0x%x (read from SRR0) attempted to access "
+ "invalid address 0x%x (read from DAR)\n",
+ context->srr0, dar);
+ break;
+ case __OS_EXCEPTION_ISI:
+ OSReport("\nAttempted to fetch instruction from invalid address 0x%x "
+ "(read from SRR0)\n",
+ context->srr0);
+ break;
+ case __OS_EXCEPTION_ALIGNMENT:
+ OSReport("\nInstruction at 0x%x (read from SRR0) attempted to access "
+ "unaligned address 0x%x (read from DAR)\n",
+ context->srr0, dar);
+ break;
+ case __OS_EXCEPTION_PROGRAM:
+ OSReport("\nProgram exception : Possible illegal instruction/operation "
+ "at or around 0x%x (read from SRR0)\n",
+ context->srr0, dar);
+ break;
+ case OS_ERROR_PROTECTION:
+ OSReport("\n");
+ OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], __DSPRegs[0x00000018 + 1]);
+ OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], __DSPRegs[0x00000010 + 1]);
+ OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]);
+ break;
+ }
+
+ OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt,
+ __OSLastInterruptSrr0, __OSLastInterruptTime);
+
+ PPCHalt();
+}
diff --git a/src/Dolphin/os/OSFont.c b/src/Dolphin/os/OSFont.c
new file mode 100644
index 0000000..34224bf
--- /dev/null
+++ b/src/Dolphin/os/OSFont.c
@@ -0,0 +1,757 @@
+#include <OS.h>
+#include <gx.h>
+#include <vi.h>
+
+#define ROM_FONT_SJIS_START ((void*)0x001AFF00)
+#define ROM_FONT_SJIS_SIZE 0x0004D000
+#define ROM_FONT_ANSI_START ((void*)0x001FCF00)
+#define ROM_FONT_ANSI_SIZE 0x00003000
+
+typedef const u8* (*ParseStringFunc)(u16, const u8*, OSFontData**, u32*);
+
+static u16 FontEncode = 0xFFFF;
+
+static OSFontData* FontDataAnsi;
+static OSFontData* FontDataSjis;
+static BOOL FixedPitch;
+static ParseStringFunc ParseString;
+
+extern u16 HankakuToCode[];
+extern u16 Zenkaku2Code[];
+
+static const u8* ParseStringS(u16, const u8*, OSFontData**, u32*);
+static const u8* ParseStringW(u16, const u8*, OSFontData**, u32*);
+
+static BOOL IsSjisLeadByte(u8 ch) {
+ return (0x81 <= ch && ch <= 0x9F) || (0xE0 <= ch && ch <= 0xFC);
+}
+
+static BOOL IsSjisTrailByte(u8 ch) {
+ return (0x40 <= ch && ch <= 0xFC) && (ch != 0x7F);
+}
+
+static u32 GetFontCode(u16 encode, u16 code) {
+ u32 tmp;
+ s32 trail;
+
+ if (encode == OS_FONT_ENCODE_SJIS) {
+ if (code >= 0x20 && code <= 0xDF) {
+ return HankakuToCode[code - 0x20];
+ } else if (code > 0x889E && code <= 0x9872) {
+ tmp = ((code >> 8) - 0x88) * 0xBC;
+ trail = code & 0xFF;
+
+ if (!IsSjisTrailByte(trail)) {
+ return 0;
+ }
+
+ trail -= 0x40;
+ if (trail >= 0x40) {
+ trail--;
+ }
+
+ return tmp + trail + 0x2BE;
+ } else if (code >= 0x8140 && code < 0x879E) {
+ tmp = ((code >> 8) - 0x81) * 0xBC;
+ trail = code & 0xFF;
+
+ if (!IsSjisTrailByte(trail)) {
+ return 0;
+ }
+
+ trail -= 0x40;
+ if (trail >= 0x40) {
+ trail--;
+ }
+
+ return Zenkaku2Code[tmp + trail];
+ }
+ } else if (code > 0x20 && code <= 0xFF) {
+ return code - 0x20;
+ }
+
+ return 0;
+}
+
+// 'Yay0' decompression (See YAGCD sections 16.1.1, 16.1.2)
+static void Decode(u8* src, u8* dst) {
+ int j;
+ s32 linkOfs;
+ s32 chunkPos;
+ int i;
+ s32 chunksOfs;
+ u32 maskTblPos;
+ s32 expandSize;
+ s32 linkTblOfs;
+ s32 count;
+ u32 maskBits;
+ u32 mask;
+
+ expandSize = *(s32*)(src + 0x4);
+ linkTblOfs = *(s32*)(src + 0x8);
+ chunksOfs = *(s32*)(src + 0xC);
+
+ i = 0;
+ maskBits = 0;
+ maskTblPos = 16;
+
+ do {
+ // Get next mask
+ if (maskBits == 0) {
+ mask = *(u32*)(src + maskTblPos);
+ maskTblPos += sizeof(u32);
+ maskBits = sizeof(u32) * 8;
+ }
+
+ // Non-linked chunk
+ if (mask & 0x80000000) {
+ dst[i++] = src[chunksOfs++];
+ }
+ // Linked chunk
+ else {
+ // Read offset from link table
+ linkOfs = src[linkTblOfs] << 8 | src[linkTblOfs + 1];
+ linkTblOfs += sizeof(u16);
+
+ // Apply offset
+ chunkPos = i - (linkOfs & 0x0FFF);
+ count = linkOfs >> 12;
+ if (count == 0) {
+ count = src[chunksOfs++] + 0x12;
+ } else {
+ count += 2;
+ }
+
+ // Copy chunk
+ for (j = 0; j < count; j++, i++, chunkPos++) {
+ dst[i] = dst[chunkPos - 1];
+ }
+ }
+
+ // Prepare next mask bit
+ mask <<= 1;
+ maskBits--;
+ } while (i < expandSize);
+}
+
+static u32 GetFontSize(const u8* font) {
+ if (font[0] == 'Y' && font[1] == 'a' && font[2] == 'y') {
+ return *(u32*)(font + 0x4);
+ }
+
+ return 0;
+}
+
+u16 OSGetFontEncode(void) {
+ if (FontEncode != 0xFFFF) {
+ return FontEncode;
+ }
+
+ switch (*(u32*)OSPhysicalToCached(0xcc)) {
+ case VI_NTSC:
+ FontEncode = ((__VIRegs[55] & 2) != 0)
+ ? OS_FONT_ENCODE_SJIS
+ : OS_FONT_ENCODE_ANSI;
+ break;
+ case VI_PAL:
+ case VI_MPAL:
+ case VI_DEBUG:
+ case VI_DEBUG_PAL:
+ case VI_EURGB60:
+ default:
+ FontEncode = OS_FONT_ENCODE_ANSI;
+ }
+
+ ParseString = ParseStringS;
+
+ return FontEncode;
+}
+
+u16 OSSetFontEncode(u16 encode) {
+ u16 old = OSGetFontEncode();
+
+ if (encode <= OS_FONT_ENCODE_UTF32) {
+ FontEncode = encode;
+
+ if (encode >= OS_FONT_ENCODE_UTF8 && encode <= OS_FONT_ENCODE_UTF32) {
+ ParseString = ParseStringW;
+ }
+ }
+
+ return old;
+}
+
+static void ReadROM(void* dst, s32 size, const void* src) {
+ s32 blockSize;
+
+ while (size > 0) {
+ blockSize = (size <= 256) ? size : 256;
+ size -= blockSize;
+
+ while (!__OSReadROM(dst, blockSize, src)) {
+ ;
+ }
+
+ src = (u8*)src + blockSize;
+ dst = (u8*)dst + blockSize;
+ }
+}
+
+static u32 ReadFont(void* dst, u16 encode, OSFontData* font) {
+ u8* tex;
+ int i;
+ u32 code;
+ u32 size;
+ s32 sheet;
+ s32 numRestTex;
+ s32 row;
+ s32 col;
+ u8* tmp;
+
+ if (encode == OS_FONT_ENCODE_SJIS) {
+ ReadROM(dst, ROM_FONT_SJIS_SIZE, ROM_FONT_SJIS_START);
+ } else {
+ ReadROM(dst, ROM_FONT_ANSI_SIZE, ROM_FONT_ANSI_START);
+ }
+
+ size = GetFontSize(dst);
+ if (size == 0) {
+ return 0;
+ }
+
+ Decode(dst, (u8*)font);
+
+ if (encode == OS_FONT_ENCODE_SJIS) {
+ u16 sp28[] = {0x2ABE, 0x003D, 0x003D, 0x003D};
+
+ /**
+ * Find 'T' texture (See OSGetFontTexture)
+ */
+ code = GetFontCode(encode, 'T');
+ // Font sheet on which the texture resides
+ sheet = (s32)code / (font->texNumCol * font->texNumRow);
+ // Number of succeeding textures on the sheet
+ numRestTex = code - (sheet * (font->texNumCol * font->texNumRow));
+ // Texture position on sheet
+ row = numRestTex / font->texNumCol;
+ col = numRestTex - row * font->texNumCol;
+ // Texture position
+ row *= font->cellHeight;
+ col *= font->cellWidth;
+ // Font code texture
+ tex = (u8*)font + font->fontSheetOfs;
+ tex += sheet * font->texSize / 2;
+
+ // Editing the texture at runtime?
+ for (i = 4; i < 8; i++) {
+ tmp = tex + (((font->texWidth / 8) * 32) / 2) * ((row + i) / 8);
+ tmp += (col / 8) * 16;
+ tmp += ((row + i) % 8) * 2;
+ tmp += (col % 8) / 4;
+ *(u16*)tmp = sp28[i - 4];
+ }
+ }
+
+ return size;
+}
+
+u32 OSLoadFont(OSFontData* font, void* dst) {
+ u32 size;
+
+ switch (OSGetFontEncode()) {
+ case OS_FONT_ENCODE_ANSI:
+ FontDataAnsi = font;
+ size = ReadFont(dst, OS_FONT_ENCODE_ANSI, FontDataAnsi);
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ FontDataSjis = font;
+ size = ReadFont(dst, OS_FONT_ENCODE_SJIS, FontDataSjis);
+ break;
+ case OS_FONT_ENCODE_UTF8:
+ case OS_FONT_ENCODE_UTF16:
+ case OS_FONT_ENCODE_UTF32:
+ FontDataAnsi = font;
+ size = ReadFont(dst, OS_FONT_ENCODE_ANSI, FontDataAnsi);
+ if (size == 0) {
+ break;
+ }
+
+ FontDataSjis = (OSFontData*)((u8*)FontDataAnsi + size);
+ size += ReadFont(dst, OS_FONT_ENCODE_SJIS, FontDataSjis);
+ break;
+ case OS_FONT_ENCODE_2:
+ default:
+ size = 0;
+ break;
+ }
+
+ return size;
+}
+
+static const u8* ParseStringS(u16 encode, const u8* str, OSFontData** fontOut,
+ u32* codeOut) {
+ OSFontData* font;
+ u16 code = 0;
+
+ switch (encode) {
+ case OS_FONT_ENCODE_ANSI:
+ font = FontDataAnsi;
+ code = *str;
+ if (code != 0) {
+ str++;
+ }
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ font = FontDataSjis;
+ code = *str;
+ if (code == 0) {
+ break;
+ }
+ str++;
+
+ if (IsSjisLeadByte(code) && IsSjisTrailByte(*str)) {
+ code = (code << 8 | *str++);
+ }
+ break;
+ }
+
+ *fontOut = font;
+ *codeOut = GetFontCode(encode, code);
+
+ return str;
+}
+
+static const u8* ParseStringW(u16 encode, const u8* str, OSFontData** fontOut,
+ u32* codeOut) {
+ OSFontData* font;
+ u16 code = 0;
+ u32 utf32 = 0;
+
+ switch (encode) {
+ case OS_FONT_ENCODE_ANSI:
+ font = FontDataAnsi;
+ code = *str;
+ if (code != 0) {
+ str++;
+ }
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ font = FontDataSjis;
+ code = *str;
+ if (code == 0) {
+ break;
+ }
+ str++;
+
+ if (IsSjisLeadByte(code) && IsSjisTrailByte(*str)) {
+ code = (code << 8 | *str++);
+ }
+ break;
+ case OS_FONT_ENCODE_UTF8:
+ str = (u8 *)OSUTF8to32(str, &utf32);
+ break;
+ case OS_FONT_ENCODE_UTF16:
+ str = (const u8*)OSUTF16to32((const u16*)str, &utf32);
+ break;
+ case OS_FONT_ENCODE_UTF32:
+ utf32 = *(u32*)str;
+ if (utf32 != 0) {
+ str += sizeof(u32);
+ }
+ break;
+ }
+
+ if (utf32 != 0) {
+ encode = OS_FONT_ENCODE_ANSI;
+ font = FontDataAnsi;
+ code = OSUTF32toANSI(utf32);
+
+ if (code == 0 || (FixedPitch && utf32 <= 0x7F)) {
+ code = OSUTF32toSJIS(utf32);
+ if (code != 0) {
+ encode = OS_FONT_ENCODE_SJIS;
+ font = FontDataSjis;
+ }
+ }
+ }
+
+ *fontOut = font;
+ *codeOut = GetFontCode(encode, code);
+
+ return str;
+}
+
+const char* OSGetFontTexel(const char* str, void* dst, s32 xOfs, s32 arg3,
+ u32* widthOut) {
+ OSFontData* font;
+ s32 numRestTex;
+ u8* local_24;
+ s32 row;
+ u8* local_20;
+ s32 col;
+ s32 local_48;
+ u32 code;
+ int j;
+ int i;
+ u32 sheet;
+ u8* local_4C;
+ u8* font_u8;
+ u8* tex;
+ s32 local_44;
+
+ str = (const char*)ParseString(OSGetFontEncode(), (const u8*)str, &font,
+ &code);
+ local_4C = (u8*)font + sizeof(OSFontData);
+
+ /**
+ * Find font code texture (See OSGetFontTexture)
+ */
+ // Font sheet on which the texture resides
+ sheet = (s32)code / (font->texNumCol * font->texNumRow);
+ // Number of succeeding textures on the sheet
+ numRestTex = code - (sheet * (font->texNumCol * font->texNumRow));
+ // Texture position on sheet
+ row = numRestTex / font->texNumCol;
+ col = numRestTex - row * font->texNumCol;
+ // Texture position
+ row *= font->cellHeight;
+ col *= font->cellWidth;
+ // Font code texture
+ tex = (u8*)font + font->fontSheetOfs;
+ tex += sheet * font->texSize / 2;
+
+ for (i = 0; i < font->cellHeight; i++) {
+ for (j = 0; j < font->cellWidth; j++) {
+ local_20 =
+ tex + (((font->texWidth / 8) * 32) / 2) * ((row + i) / 8);
+ local_20 += ((col + j) / 8) * 16;
+ local_20 += ((row + i) % 8) * 2;
+ local_20 += ((col + j) % 8) / 4;
+
+ local_44 = (col + j) % 4;
+
+ local_24 = (u8*)dst + ((i / 8) * (((arg3 * 4) / 8) * 32));
+ local_24 += (((xOfs + j) / 8) * 32);
+ local_24 += ((i % 8) * 4);
+ local_24 += ((xOfs + j) % 8) / 2;
+
+ local_48 = (xOfs + j) % 2;
+
+ *local_24 |=
+ (u8)(local_4C[(*local_20 >> (6 - (local_44 * 2))) & 3] &
+ (local_48 != 0 ? 0x0F : 0xF0));
+ }
+ }
+
+ if (widthOut != NULL) {
+ // TODO: Permuter fake(?)match
+ font_u8 = (u8*)font;
+ *widthOut = (font_u8 + font->charWidthTblOfs)[code];
+ }
+
+ return str;
+}
+
+static void ExpandFontSheet(const OSFontData* font, u8* src, u8* dst) {
+ int i;
+ const u8* tmp = (const u8*)font + sizeof(OSFontData);
+
+ if (font->texFmt == GX_TF_I4) {
+ for (i = (s32)font->fontSheetSize / 2 - 1; i >= 0; i--) {
+ dst[i * 2 + 0] =
+ tmp[src[i] >> 6 & 3] & 0xF0 | tmp[src[i] >> 4 & 3] & 0x0F;
+ dst[i * 2 + 1] =
+ tmp[src[i] >> 2 & 3] & 0xF0 | tmp[src[i] >> 0 & 3] & 0x0F;
+ }
+ } else if (font->texFmt == GX_TF_IA4) {
+ for (i = (s32)font->fontSheetSize / 4 - 1; i >= 0; i--) {
+ dst[i * 4 + 0] = tmp[src[i] >> 6 & 3];
+ dst[i * 4 + 1] = tmp[src[i] >> 4 & 3];
+ dst[i * 4 + 2] = tmp[src[i] >> 2 & 3];
+ dst[i * 4 + 3] = tmp[src[i] >> 0 & 3];
+ }
+ }
+
+ DCStoreRange(dst, font->fontSheetSize);
+}
+
+BOOL OSInitFont(OSFontData* font) {
+ u8* sheets;
+
+ switch (OSGetFontEncode()) {
+ case OS_FONT_ENCODE_ANSI:
+ FontDataAnsi = font;
+ if (ReadFont((u8*)font + 0x1D120, OS_FONT_ENCODE_ANSI, FontDataAnsi) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs;
+ FontDataAnsi->fontSheetOfs = ROUND_UP(FontDataAnsi->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataAnsi, sheets,
+ (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs);
+ break;
+ case OS_FONT_ENCODE_SJIS:
+ FontDataSjis = font;
+ if (ReadFont((u8*)font + 0xD3F00, OS_FONT_ENCODE_SJIS, FontDataSjis) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataSjis + FontDataSjis->fontSheetOfs;
+ FontDataSjis->fontSheetOfs = ROUND_UP(FontDataSjis->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataSjis, sheets,
+ (u8*)FontDataSjis + FontDataSjis->fontSheetOfs);
+ break;
+ case OS_FONT_ENCODE_2:
+ break;
+ case OS_FONT_ENCODE_UTF8:
+ case OS_FONT_ENCODE_UTF16:
+ case OS_FONT_ENCODE_UTF32:
+ FontDataAnsi = font;
+ if (ReadFont((u8*)font + 0xF4020, OS_FONT_ENCODE_ANSI, FontDataAnsi) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs;
+ FontDataAnsi->fontSheetOfs = ROUND_UP(FontDataAnsi->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataAnsi, sheets,
+ (u8*)FontDataAnsi + FontDataAnsi->fontSheetOfs);
+
+ FontDataSjis = (OSFontData*)((u8*)FontDataAnsi + 0x20120);
+ if (ReadFont((u8*)font + 0xF4020, OS_FONT_ENCODE_SJIS, FontDataSjis) ==
+ 0) {
+ return FALSE;
+ }
+
+ sheets = (u8*)FontDataSjis + FontDataSjis->fontSheetOfs;
+ FontDataSjis->fontSheetOfs = ROUND_UP(FontDataSjis->fontSheetOfs, 32);
+ ExpandFontSheet(FontDataSjis, sheets,
+ (u8*)FontDataSjis + FontDataSjis->fontSheetOfs);
+ break;
+ }
+
+ return TRUE;
+}
+
+const char* OSGetFontTexture(const char* str, void** texOut, u32* xOut,
+ u32* yOut, u32* widthOut) {
+ OSFontData* font;
+ s32 numRestTex;
+ u8* font_u8;
+ u32 code;
+ u32 sheet;
+ u32 row;
+ u32 col;
+ u32 tmp;
+
+ str = (const char*)ParseString(OSGetFontEncode(), (const u8*)str, &font,
+ &code);
+
+ // Font sheet on which the texture resides
+ sheet = (s32)code / (font->texNumCol * font->texNumRow);
+ // Font code texture
+ *texOut = (font->texSize * sheet) + ((u8*)font + font->fontSheetOfs);
+
+ // Number of succeeding textures on the sheet
+ // TODO: Permuter fake(?)match
+ tmp = font->texNumRow;
+ numRestTex = code - (sheet * (font->texNumCol * tmp));
+
+ // Sheet row on which the texure resides
+ row = numRestTex / font->texNumCol;
+ // Sheet column on which the texture resides
+ col = numRestTex - row * font->texNumCol;
+
+ // Texture position
+ *xOut = col * font->cellWidth;
+ *yOut = row * font->cellHeight;
+
+ if (widthOut != NULL) {
+ // TODO: Permuter fake(?)match
+ font_u8 = (u8*)font;
+ *widthOut = (font_u8 + font->charWidthTblOfs)[code];
+ }
+
+ return str;
+}
+
+const char* OSGetFontWidth(const char* str, u32* widthOut) {
+ OSFontData* font;
+ u8* font_u8;
+ u32 code;
+
+ str = (const char*)ParseString(OSGetFontEncode(), (const u8*)str, &font,
+ &code);
+
+ if (widthOut != NULL) {
+ // TODO: Permuter fake(?)match
+ font_u8 = (u8*)font;
+ *widthOut = (font_u8 + font->charWidthTblOfs)[code];
+ }
+
+ return str;
+}
+
+static u16 HankakuToCode[] = {
+ 0x020C, 0x020D, 0x020E, 0x020F, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214,
+ 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021A, 0x021B, 0x021C, 0x021D,
+ 0x021E, 0x021F, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226,
+ 0x0227, 0x0228, 0x0229, 0x022A, 0x022B, 0x022C, 0x022D, 0x022E, 0x022F,
+ 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, 0x0238,
+ 0x0239, 0x023A, 0x023B, 0x023C, 0x023D, 0x023E, 0x023F, 0x0240, 0x0241,
+ 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x024A,
+ 0x024B, 0x024C, 0x024D, 0x024E, 0x024F, 0x0250, 0x0251, 0x0252, 0x0253,
+ 0x0254, 0x0255, 0x0256, 0x0257, 0x0258, 0x0259, 0x025A, 0x025B, 0x025C,
+ 0x025D, 0x025E, 0x025F, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265,
+ 0x0266, 0x0267, 0x0268, 0x0269, 0x026A, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C, 0x020C,
+ 0x020C, 0x020C, 0x020C, 0x026B, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270,
+ 0x0271, 0x0272, 0x0273, 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279,
+ 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282,
+ 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B,
+ 0x028C, 0x028D, 0x028E, 0x028F, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294,
+ 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D,
+ 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6,
+ 0x02A7, 0x02A8, 0x02A9};
+
+static u16 Zenkaku2Code[] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
+ 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011,
+ 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A,
+ 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C,
+ 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E,
+ 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
+ 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062,
+ 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072,
+ 0x0073, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083,
+ 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E,
+ 0x008F, 0x0090, 0x0091, 0x0000, 0x0000, 0x0000, 0x0000, 0x0092, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0093, 0x0094, 0x0095, 0x0096,
+ 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1,
+ 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA,
+ 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3,
+ 0x00B4, 0x00B5, 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8,
+ 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6,
+ 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8,
+ 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1,
+ 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA,
+ 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0101, 0x0102, 0x0103,
+ 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010A, 0x010B, 0x010C,
+ 0x010D, 0x010E, 0x010F, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115,
+ 0x0116, 0x0117, 0x0118, 0x0119, 0x011A, 0x011B, 0x011C, 0x011D, 0x011E,
+ 0x011F, 0x0120, 0x0121, 0x0122, 0x0123, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0125,
+ 0x0126, 0x0127, 0x0128, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E,
+ 0x012F, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C, 0x013D, 0x013E, 0x013F, 0x0140,
+ 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, 0x0148, 0x0149,
+ 0x014A, 0x014B, 0x014C, 0x014D, 0x014E, 0x014F, 0x0150, 0x0151, 0x0152,
+ 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015A, 0x015B,
+ 0x015C, 0x015D, 0x015E, 0x015F, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164,
+ 0x0165, 0x0166, 0x0167, 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D,
+ 0x016E, 0x016F, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, 0x0176,
+ 0x0177, 0x0178, 0x0179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x017F, 0x0180,
+ 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189,
+ 0x018A, 0x018B, 0x018C, 0x018D, 0x018E, 0x018F, 0x0190, 0x0191, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0193,
+ 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0199, 0x019A, 0x019B, 0x019C,
+ 0x019D, 0x019E, 0x019F, 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, 0x01A5,
+ 0x01A6, 0x01A7, 0x01A8, 0x01A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01AA, 0x01AB, 0x01AC,
+ 0x01AD, 0x01AE, 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5,
+ 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD, 0x01BE,
+ 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7,
+ 0x01C8, 0x01C9, 0x01CA, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x01CB, 0x01CC, 0x01CD, 0x01CE, 0x01CF, 0x01D0, 0x01D1, 0x01D2, 0x01D3,
+ 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D9, 0x01DA, 0x01DB, 0x01DC,
+ 0x01DD, 0x01DE, 0x01DF, 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5,
+ 0x01E6, 0x01E7, 0x01E8, 0x01E9, 0x01EA, 0x01EB, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x01EC, 0x01ED, 0x01EE, 0x01EF, 0x01F0, 0x01F1, 0x01F2, 0x01F3,
+ 0x01F4, 0x01F5, 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x01FA, 0x01FB, 0x01FC,
+ 0x01FD, 0x01FE, 0x01FF, 0x0200, 0x0201, 0x0202, 0x0203, 0x0204, 0x0205,
+ 0x0206, 0x0207, 0x0208, 0x0209, 0x020A, 0x020B, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x020C, 0x020D, 0x020E, 0x020F, 0x0210,
+ 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219,
+ 0x021A, 0x021B, 0x021C, 0x021D, 0x021E, 0x021F, 0x0220, 0x0221, 0x0222,
+ 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022A, 0x022B,
+ 0x022C, 0x022D, 0x022E, 0x022F, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234,
+ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023A, 0x023B, 0x023C, 0x023D,
+ 0x023E, 0x023F, 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246,
+ 0x0247, 0x0248, 0x0249, 0x024A, 0x024B, 0x024C, 0x024D, 0x024E, 0x024F,
+ 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, 0x0258,
+ 0x0259, 0x025A, 0x025B, 0x025C, 0x025D, 0x025E, 0x025F, 0x0260, 0x0261,
+ 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026A,
+ 0x026B, 0x026C, 0x026D, 0x026E, 0x026F, 0x0270, 0x0271, 0x0272, 0x0273,
+ 0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027A, 0x027B, 0x027C,
+ 0x027D, 0x027E, 0x027F, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285,
+ 0x0286, 0x0287, 0x0288, 0x0289, 0x028A, 0x028B, 0x028C, 0x028D, 0x028E,
+ 0x028F, 0x0290, 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297,
+ 0x0298, 0x0299, 0x029A, 0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0,
+ 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9,
+ 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE, 0x02AF, 0x02B0, 0x02B1, 0x02B2,
+ 0x02B3, 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8, 0x02B9, 0x02BA, 0x02BB,
+ 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0, 0x02C1, 0x02C2, 0x02C3, 0x02C4,
+ 0x02C5, 0x02C6, 0x02C7, 0x02C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x02C9, 0x02CA, 0x02CB, 0x02CC, 0x02CD, 0x02CE,
+ 0x02CF, 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6, 0x02D7,
+ 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x02DE, 0x02DF, 0x02E0,
+ 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5, 0x02E6, 0x0000, 0x02E7, 0x02E8,
+ 0x02E9, 0x02EA, 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF, 0x02F0, 0x02F1,
+ 0x02F2, 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9, 0x02FA,
+ 0x02FB, 0x02FC, 0x02FD, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x02FE, 0x02FF, 0x0300, 0x0301, 0x0302, 0x0303, 0x0304,
+ 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030A, 0x030B, 0x030C, 0x030D,
+ 0x030E, 0x030F, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316,
+ 0x0317, 0x0318, 0x0319, 0x031A, 0x031B, 0x0000};
diff --git a/src/Dolphin/os/OSInterrupt.c b/src/Dolphin/os/OSInterrupt.c
new file mode 100644
index 0000000..30b6e81
--- /dev/null
+++ b/src/Dolphin/os/OSInterrupt.c
@@ -0,0 +1,433 @@
+#include <dolphin/os.h>
+
+static asm void ExternalInterruptHandler(register __OSException exception,
+ register OSContext* context);
+
+// TODO: Move these to a more appropriate location
+vu32 __PIRegs[12] : 0xCC003000;
+vu32 __EXIRegs[16] : 0xCC006800;
+vu16 __MEMRegs[64] : 0xCC004000;
+vu16 __DSPRegs[32] : 0xCC005000;
+vu32 __AIRegs[8] : 0xCC006C00;
+
+extern void __RAS_OSDisableInterrupts_begin(void);
+extern void __RAS_OSDisableInterrupts_end(void);
+
+static __OSInterruptHandler* InterruptHandlerTable;
+
+static OSInterruptMask InterruptPrioTable[] = {
+ OS_INTERRUPTMASK_PI_ERROR,
+ OS_INTERRUPTMASK_PI_DEBUG,
+ OS_INTERRUPTMASK_MEM,
+ OS_INTERRUPTMASK_PI_RSW,
+ OS_INTERRUPTMASK_PI_VI,
+ OS_INTERRUPTMASK_PI_PE,
+ OS_INTERRUPTMASK_PI_HSP,
+ OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP | OS_INTERRUPTMASK_AI |
+ OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI,
+ OS_INTERRUPTMASK_DSP_AI,
+ OS_INTERRUPTMASK_PI_CP,
+ 0xFFFFFFFF,
+};
+
+asm BOOL OSDisableInterrupts(void) {
+ // clang-format off
+ nofralloc
+entry __RAS_OSDisableInterrupts_begin
+ mfmsr r3
+ rlwinm r4, r3, 0, 17, 15
+ mtmsr r4
+entry __RAS_OSDisableInterrupts_end
+ rlwinm r3, r3, 17, 31, 31
+ blr
+ // clang-format on
+}
+asm BOOL OSEnableInterrupts(void) {
+ // clang-format off
+ nofralloc
+
+ mfmsr r3
+ ori r4, r3, 0x8000
+ mtmsr r4
+ rlwinm r3, r3, 17, 31, 31
+ blr
+ // clang-format on
+}
+
+asm BOOL OSRestoreInterrupts(register BOOL level){
+ // clang-format off
+
+ nofralloc
+
+ cmpwi level, 0
+ mfmsr r4
+ beq _disable
+ ori r5, r4, 0x8000
+ b _restore
+_disable:
+ rlwinm r5, r4, 0, 17, 15
+_restore:
+ mtmsr r5
+ rlwinm r3, r4, 17, 31, 31
+ blr
+ // clang-format on
+}
+
+__OSInterruptHandler
+ __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) {
+ __OSInterruptHandler oldHandler;
+
+ oldHandler = InterruptHandlerTable[interrupt];
+ InterruptHandlerTable[interrupt] = handler;
+ return oldHandler;
+}
+
+__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) {
+ return InterruptHandlerTable[interrupt];
+}
+
+void __OSInterruptInit(void) {
+ InterruptHandlerTable = OSPhysicalToCached(0x3040);
+ memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler));
+
+ *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0;
+
+ *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0;
+
+ __PIRegs[1] = 0xf0;
+
+ __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI |
+ OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI);
+
+ __OSSetExceptionHandler(4, ExternalInterruptHandler);
+}
+
+u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) {
+ u32 reg;
+
+ switch (__cntlzw(mask)) {
+ case __OS_INTERRUPT_MEM_0:
+ case __OS_INTERRUPT_MEM_1:
+ case __OS_INTERRUPT_MEM_2:
+ case __OS_INTERRUPT_MEM_3:
+ case __OS_INTERRUPT_MEM_ADDRESS:
+ reg = 0;
+ if (!(current & OS_INTERRUPTMASK_MEM_0))
+ reg |= 0x1;
+ if (!(current & OS_INTERRUPTMASK_MEM_1))
+ reg |= 0x2;
+ if (!(current & OS_INTERRUPTMASK_MEM_2))
+ reg |= 0x4;
+ if (!(current & OS_INTERRUPTMASK_MEM_3))
+ reg |= 0x8;
+ if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS))
+ reg |= 0x10;
+ __MEMRegs[0x0000000e] = (u16)reg;
+ mask &= ~OS_INTERRUPTMASK_MEM;
+ break;
+ case __OS_INTERRUPT_DSP_AI:
+ case __OS_INTERRUPT_DSP_ARAM:
+ case __OS_INTERRUPT_DSP_DSP:
+ reg = __DSPRegs[0x00000005];
+ reg &= ~0x1F8;
+ if (!(current & OS_INTERRUPTMASK_DSP_AI))
+ reg |= 0x10;
+ if (!(current & OS_INTERRUPTMASK_DSP_ARAM))
+ reg |= 0x40;
+ if (!(current & OS_INTERRUPTMASK_DSP_DSP))
+ reg |= 0x100;
+ __DSPRegs[0x00000005] = (u16)reg;
+ mask &= ~OS_INTERRUPTMASK_DSP;
+ break;
+ case __OS_INTERRUPT_AI_AI:
+ reg = __AIRegs[0];
+ reg &= ~0x2C;
+ if (!(current & OS_INTERRUPTMASK_AI_AI))
+ reg |= 0x4;
+ __AIRegs[0] = reg;
+ mask &= ~OS_INTERRUPTMASK_AI;
+ break;
+ case __OS_INTERRUPT_EXI_0_EXI:
+ case __OS_INTERRUPT_EXI_0_TC:
+ case __OS_INTERRUPT_EXI_0_EXT:
+ reg = __EXIRegs[0];
+ reg &= ~0x2C0F;
+ if (!(current & OS_INTERRUPTMASK_EXI_0_EXI))
+ reg |= 0x1;
+ if (!(current & OS_INTERRUPTMASK_EXI_0_TC))
+ reg |= 0x4;
+ if (!(current & OS_INTERRUPTMASK_EXI_0_EXT))
+ reg |= 0x400;
+ __EXIRegs[0] = reg;
+ mask &= ~OS_INTERRUPTMASK_EXI_0;
+ break;
+ case __OS_INTERRUPT_EXI_1_EXI:
+ case __OS_INTERRUPT_EXI_1_TC:
+ case __OS_INTERRUPT_EXI_1_EXT:
+ reg = __EXIRegs[5];
+ reg &= ~0xC0F;
+
+ if (!(current & OS_INTERRUPTMASK_EXI_1_EXI))
+ reg |= 0x1;
+ if (!(current & OS_INTERRUPTMASK_EXI_1_TC))
+ reg |= 0x4;
+ if (!(current & OS_INTERRUPTMASK_EXI_1_EXT))
+ reg |= 0x400;
+ __EXIRegs[5] = reg;
+ mask &= ~OS_INTERRUPTMASK_EXI_1;
+ break;
+ case __OS_INTERRUPT_EXI_2_EXI:
+ case __OS_INTERRUPT_EXI_2_TC:
+ reg = __EXIRegs[10];
+ reg &= ~0xF;
+ if (!(current & OS_INTERRUPTMASK_EXI_2_EXI))
+ reg |= 0x1;
+ if (!(current & OS_INTERRUPTMASK_EXI_2_TC))
+ reg |= 0x4;
+
+ __EXIRegs[10] = reg;
+ mask &= ~OS_INTERRUPTMASK_EXI_2;
+ break;
+ case __OS_INTERRUPT_PI_CP:
+ case __OS_INTERRUPT_PI_SI:
+ case __OS_INTERRUPT_PI_DI:
+ case __OS_INTERRUPT_PI_RSW:
+ case __OS_INTERRUPT_PI_ERROR:
+ case __OS_INTERRUPT_PI_VI:
+ case __OS_INTERRUPT_PI_DEBUG:
+ case __OS_INTERRUPT_PI_PE_TOKEN:
+ case __OS_INTERRUPT_PI_PE_FINISH:
+ case __OS_INTERRUPT_PI_HSP:
+ reg = 0xF0;
+
+ if (!(current & OS_INTERRUPTMASK_PI_CP)) {
+ reg |= 0x800;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_SI)) {
+ reg |= 0x8;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_DI)) {
+ reg |= 0x4;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_RSW)) {
+ reg |= 0x2;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_ERROR)) {
+ reg |= 0x1;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_VI)) {
+ reg |= 0x100;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) {
+ reg |= 0x1000;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) {
+ reg |= 0x200;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) {
+ reg |= 0x400;
+ }
+ if (!(current & OS_INTERRUPTMASK_PI_HSP)) {
+ reg |= 0x2000;
+ }
+ __PIRegs[1] = reg;
+ mask &= ~OS_INTERRUPTMASK_PI;
+ break;
+ default:
+ break;
+ }
+ return mask;
+}
+
+OSInterruptMask OSGetInterruptMask(void) { return *(OSInterruptMask*)OSPhysicalToCached(0x00C8); }
+
+OSInterruptMask OSSetInterruptMask(OSInterruptMask local) {
+ BOOL enabled;
+ OSInterruptMask global;
+ OSInterruptMask prev;
+ OSInterruptMask mask;
+
+ enabled = OSDisableInterrupts();
+ global = *(OSInterruptMask*)OSPhysicalToCached(0x00C4);
+ prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C8);
+ mask = (global | prev) ^ local;
+ *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = local;
+ while (mask) {
+ mask = SetInterruptMask(mask, global | local);
+ }
+ OSRestoreInterrupts(enabled);
+ return prev;
+}
+
+OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) {
+ BOOL enabled;
+ OSInterruptMask prev;
+ OSInterruptMask local;
+ OSInterruptMask mask;
+
+ enabled = OSDisableInterrupts();
+ prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4);
+ local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8);
+ mask = ~(prev | local) & global;
+ global |= prev;
+ *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global;
+ while (mask) {
+ mask = SetInterruptMask(mask, global | local);
+ }
+ OSRestoreInterrupts(enabled);
+ return prev;
+}
+
+OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) {
+ BOOL enabled;
+ OSInterruptMask prev;
+ OSInterruptMask local;
+ OSInterruptMask mask;
+
+ enabled = OSDisableInterrupts();
+ prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4);
+ local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8);
+ mask = (prev | local) & global;
+ global = prev & ~global;
+ *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global;
+ while (mask) {
+ mask = SetInterruptMask(mask, global | local);
+ }
+ OSRestoreInterrupts(enabled);
+ return prev;
+}
+
+volatile OSTime __OSLastInterruptTime;
+volatile __OSInterrupt __OSLastInterrupt;
+volatile u32 __OSLastInterruptSrr0;
+
+void __OSDispatchInterrupt(__OSException exception, OSContext* context) {
+ u32 intsr;
+ u32 reg;
+ OSInterruptMask cause;
+ OSInterruptMask unmasked;
+ OSInterruptMask* prio;
+ __OSInterrupt interrupt;
+ __OSInterruptHandler handler;
+ intsr = __PIRegs[0];
+ intsr &= ~0x00010000;
+
+ if (intsr == 0 || (intsr & __PIRegs[1]) == 0) {
+ OSLoadContext(context);
+ }
+
+ cause = 0;
+
+ if (intsr & 0x00000080) {
+ reg = __MEMRegs[15];
+ if (reg & 0x1)
+ cause |= OS_INTERRUPTMASK_MEM_0;
+ if (reg & 0x2)
+ cause |= OS_INTERRUPTMASK_MEM_1;
+ if (reg & 0x4)
+ cause |= OS_INTERRUPTMASK_MEM_2;
+ if (reg & 0x8)
+ cause |= OS_INTERRUPTMASK_MEM_3;
+ if (reg & 0x10)
+ cause |= OS_INTERRUPTMASK_MEM_ADDRESS;
+ }
+
+ if (intsr & 0x00000040) {
+ reg = __DSPRegs[5];
+ if (reg & 0x8)
+ cause |= OS_INTERRUPTMASK_DSP_AI;
+ if (reg & 0x20)
+ cause |= OS_INTERRUPTMASK_DSP_ARAM;
+ if (reg & 0x80)
+ cause |= OS_INTERRUPTMASK_DSP_DSP;
+ }
+
+ if (intsr & 0x00000020) {
+ reg = __AIRegs[0];
+ if (reg & 0x8)
+ cause |= OS_INTERRUPTMASK_AI_AI;
+ }
+
+ if (intsr & 0x00000010) {
+ reg = __EXIRegs[0];
+ if (reg & 0x2)
+ cause |= OS_INTERRUPTMASK_EXI_0_EXI;
+ if (reg & 0x8)
+ cause |= OS_INTERRUPTMASK_EXI_0_TC;
+ if (reg & 0x800)
+ cause |= OS_INTERRUPTMASK_EXI_0_EXT;
+ reg = __EXIRegs[5];
+ if (reg & 0x2)
+ cause |= OS_INTERRUPTMASK_EXI_1_EXI;
+ if (reg & 0x8)
+ cause |= OS_INTERRUPTMASK_EXI_1_TC;
+ if (reg & 0x800)
+ cause |= OS_INTERRUPTMASK_EXI_1_EXT;
+ reg = __EXIRegs[10];
+ if (reg & 0x2)
+ cause |= OS_INTERRUPTMASK_EXI_2_EXI;
+ if (reg & 0x8)
+ cause |= OS_INTERRUPTMASK_EXI_2_TC;
+ }
+
+ if (intsr & 0x00002000)
+ cause |= OS_INTERRUPTMASK_PI_HSP;
+ if (intsr & 0x00001000)
+ cause |= OS_INTERRUPTMASK_PI_DEBUG;
+ if (intsr & 0x00000400)
+ cause |= OS_INTERRUPTMASK_PI_PE_FINISH;
+ if (intsr & 0x00000200)
+ cause |= OS_INTERRUPTMASK_PI_PE_TOKEN;
+ if (intsr & 0x00000100)
+ cause |= OS_INTERRUPTMASK_PI_VI;
+ if (intsr & 0x00000008)
+ cause |= OS_INTERRUPTMASK_PI_SI;
+ if (intsr & 0x00000004)
+ cause |= OS_INTERRUPTMASK_PI_DI;
+ if (intsr & 0x00000002)
+ cause |= OS_INTERRUPTMASK_PI_RSW;
+ if (intsr & 0x00000800)
+ cause |= OS_INTERRUPTMASK_PI_CP;
+ if (intsr & 0x00000001)
+ cause |= OS_INTERRUPTMASK_PI_ERROR;
+
+ unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) |
+ *(OSInterruptMask*)OSPhysicalToCached(0x00C8));
+ if (unmasked) {
+ for (prio = InterruptPrioTable;; ++prio) {
+ if (unmasked & *prio) {
+ interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio);
+ break;
+ }
+ }
+
+ handler = __OSGetInterruptHandler(interrupt);
+ if (handler) {
+ if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) {
+ __OSLastInterrupt = interrupt;
+ __OSLastInterruptTime = OSGetTime();
+ __OSLastInterruptSrr0 = context->srr0;
+ }
+
+ OSDisableScheduler();
+ handler(interrupt, context);
+ OSEnableScheduler();
+ __OSReschedule();
+ OSLoadContext(context);
+ }
+ }
+
+ OSLoadContext(context);
+}
+
+static asm void ExternalInterruptHandler(register __OSException exception,
+ register OSContext* context) {
+#pragma unused(exception)
+ // clang-format off
+ nofralloc
+ OS_EXCEPTION_SAVE_GPRS(context)
+
+ stwu r1, -8(r1)
+ b __OSDispatchInterrupt
+ // clang-format on
+}
diff --git a/src/Dolphin/os/OSLink.c b/src/Dolphin/os/OSLink.c
new file mode 100644
index 0000000..933e55b
--- /dev/null
+++ b/src/Dolphin/os/OSLink.c
@@ -0,0 +1,556 @@
+#include "dolphin/os.h"
+
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))
+
+// Name Value Field Calculation
+#define R_PPC_NONE 0 // none none
+#define R_PPC_ADDR32 1 // word32 S + A
+#define R_PPC_ADDR24 2 // low24* (S + A) >> 2
+#define R_PPC_ADDR16 3 // half16* S + A
+#define R_PPC_ADDR16_LO 4 // half16 #lo(S + A)
+#define R_PPC_ADDR16_HI 5 // half16 #hi(S + A)
+#define R_PPC_ADDR16_HA 6 // half16 #ha(S + A)
+#define R_PPC_ADDR14 7 // low14* (S + A) >> 2
+#define R_PPC_ADDR14_BRTAKEN 8 // low14* (S + A) >> 2
+#define R_PPC_ADDR14_BRNTAKEN 9 // low14* (S + A) >> 2
+#define R_PPC_REL24 10 // low24* (S + A - P) >> 2
+#define R_PPC_REL14 11 // low14* (S + A - P) >> 2
+#define R_PPC_REL14_BRTAKEN 12 // low14* (S + A - P) >> 2
+#define R_PPC_REL14_BRNTAKEN 13 // low14* (S + A - P) >> 2
+
+#define R_PPC_GOT16 14 // half16* G + A
+#define R_PPC_GOT16_LO 15 // half16 #lo(G + A)
+#define R_PPC_GOT16_HI 16 // half16 #hi(G + A)
+#define R_PPC_GOT16_HA 17 // half16 #ha(G + A)
+#define R_PPC_PLTREL24 18 // low24* (L + A - P) >> 2
+#define R_PPC_COPY 19 // none none
+#define R_PPC_GLOB_DAT 20 // word32 S + A
+#define R_PPC_JMP_SLOT 21 // none
+#define R_PPC_RELATIVE 22 // word32 B + A
+
+#define R_PPC_LOCAL24PC 23 // low24*
+
+#define R_PPC_UADDR32 24 // word32 S + A
+#define R_PPC_UADDR16 25 // half16* S + A
+#define R_PPC_REL32 26 // word32 S + A - P
+
+#define R_PPC_PLT32 27 // word32 L + A
+#define R_PPC_PLTREL32 28 // word32 L + A - P
+#define R_PPC_PLT16_LO 29 // half16 #lo(L + A)
+#define R_PPL_PLT16_HI 30 // half16 #hi(L + A)
+#define R_PPC_PLT16_HA 31 // half16 #ha(L + A)
+
+#define R_PPC_SDAREL16 32 // half16* S + A - _SDA_BASE_
+#define R_PPC_SECTOFF 33 // half16* R + A
+#define R_PPC_SECTOFF_LO 34 // half16 #lo(R + A)
+#define R_PPC_SECTOFF_HI 35 // half16 #hi(R + A)
+#define R_PPC_SECTOFF_HA 36 // half16 #ha(R + A)
+#define R_PPC_ADDR30 37 // word30 (S + A - P) >> 2
+
+#define R_PPC_EMB_NADDR32 101 // uword32 N (A - S)
+#define R_PPC_EMB_NADDR16 102 // uhalf16 Y (A - S)
+#define R_PPC_EMB_NADDR16_LO 103 // uhalf16 N #lo(A - S)
+#define R_PPC_EMB_NADDR16_HI 104 // uhalf16 N #hi(A - S)
+#define R_PPC_EMB_NADDR16_HA 105 // uhalf16 N #ha(A - S)
+#define R_PPC_EMB_SDAI16 106 // uhalf16 Y T
+#define R_PPC_EMB_SDA2I16 107 // uhalf16 Y U
+#define R_PPC_EMB_SDA2REL 108 // uhalf16 Y S + A - _SDA2_BASE_
+#define R_PPC_EMB_SDA21 109 // ulow21 N
+#define R_PPC_EMB_MRKREF 110 // none N
+#define R_PPC_EMB_RELSEC16 111 // uhalf16 Y V + A
+#define R_PPC_EMB_RELST_LO 112 // uhalf16 N #lo(W + A)
+#define R_PPC_EMB_RELST_HI 113 // uhalf16 N #hi(W + A)
+#define R_PPC_EMB_RELST_HA 114 // uhalf16 N #ha(W + A)
+#define R_PPC_EMB_BIT_FLD 115 // uword32 Y
+#define R_PPC_EMB_RELSDA 116 // uhalf16 Y
+
+OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8);
+const void* __OSStringTable : (OS_BASE_CACHED | 0x30D0);
+
+#pragma dont_inline on
+__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {}
+
+__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {}
+
+#pragma dont_inline reset
+
+#define EnqueueTail(queue, moduleInfo, link) \
+ do { \
+ OSModuleInfo* __prev; \
+ \
+ __prev = (queue)->tail; \
+ if (__prev == NULL) \
+ (queue)->head = (moduleInfo); \
+ else \
+ __prev->link.next = (moduleInfo); \
+ (moduleInfo)->link.prev = __prev; \
+ (moduleInfo)->link.next = NULL; \
+ (queue)->tail = (moduleInfo); \
+ } while (0)
+
+#define DequeueItem(queue, moduleInfo, link) \
+ do { \
+ OSModuleInfo* __next; \
+ OSModuleInfo* __prev; \
+ \
+ __next = (moduleInfo)->link.next; \
+ __prev = (moduleInfo)->link.prev; \
+ \
+ if (__next == NULL) \
+ (queue)->tail = __prev; \
+ else \
+ __next->link.prev = __prev; \
+ \
+ if (__prev == NULL) \
+ (queue)->head = __next; \
+ else \
+ __prev->link.next = __next; \
+ } while (0)
+
+void OSSetStringTable(const void* stringTable) { __OSStringTable = stringTable; }
+
+static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) {
+ OSModuleID idNew;
+ OSImportInfo* imp;
+ OSRel* rel;
+ OSSectionInfo* si;
+ OSSectionInfo* siFlush;
+ u32* p;
+ u32 offset;
+ u32 x;
+
+ idNew = newModule ? newModule->info.id : 0;
+ for (imp = (OSImportInfo*)module->impOffset;
+ imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) {
+ if (imp->id == idNew) {
+ goto Found;
+ }
+ }
+ return FALSE;
+
+Found:
+ siFlush = 0;
+ for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) {
+ (u8*)p += rel->offset;
+ if (idNew) {
+ si = &OSGetSectionInfo(newModule)[rel->section];
+ offset = OS_SECTIONINFO_OFFSET(si->offset);
+ } else {
+ offset = 0;
+ }
+ switch (rel->type) {
+ case R_PPC_NONE:
+ break;
+ case R_PPC_ADDR32:
+ x = offset + rel->addend;
+ *p = x;
+ break;
+ case R_PPC_ADDR24:
+ x = offset + rel->addend;
+ *p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
+ break;
+ case R_PPC_ADDR16:
+ x = offset + rel->addend;
+ *(u16*)p = (u16)(x & 0xffff);
+ break;
+ case R_PPC_ADDR16_LO:
+ x = offset + rel->addend;
+ *(u16*)p = (u16)(x & 0xffff);
+ break;
+ case R_PPC_ADDR16_HI:
+ x = offset + rel->addend;
+ *(u16*)p = (u16)(((x >> 16) & 0xffff));
+ break;
+ case R_PPC_ADDR16_HA:
+ x = offset + rel->addend;
+ *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff);
+ break;
+ case R_PPC_ADDR14:
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_ADDR14_BRNTAKEN:
+ x = offset + rel->addend;
+ *p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
+ break;
+ case R_PPC_REL24:
+ x = offset + rel->addend - (u32)p;
+ *p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
+ break;
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ x = offset + rel->addend - (u32)p;
+ *p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
+ break;
+ case R_DOLPHIN_NOP:
+ break;
+ case R_DOLPHIN_SECTION:
+ si = &OSGetSectionInfo(module)[rel->section];
+ p = (u32*)OS_SECTIONINFO_OFFSET(si->offset);
+ if (siFlush) {
+ offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
+ DCFlushRange((void*)offset, siFlush->size);
+ ICInvalidateRange((void*)offset, siFlush->size);
+ }
+ siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0;
+ break;
+ default:
+ OSReport("OSLink: unknown relocation type %3d\n", rel->type);
+ break;
+ }
+ }
+
+ if (siFlush) {
+ offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
+ DCFlushRange((void*)offset, siFlush->size);
+ ICInvalidateRange((void*)offset, siFlush->size);
+ }
+
+ return TRUE;
+}
+
+#if OS_MODULE_VERSION >= 3
+static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) {
+ u32 i;
+ OSSectionInfo* si;
+ OSModuleHeader* moduleHeader;
+ OSModuleInfo* moduleInfo;
+ OSImportInfo* imp;
+
+ moduleHeader = (OSModuleHeader*)newModule;
+ moduleHeader->bssSection = 0;
+
+ if (OS_MODULE_VERSION < newModule->version ||
+ 2 <= newModule->version &&
+ (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 ||
+ moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) {
+ return FALSE;
+ }
+
+ EnqueueTail(&__OSModuleInfoList, newModule, link);
+ newModule->sectionInfoOffset += (u32)moduleHeader;
+ moduleHeader->relOffset += (u32)moduleHeader;
+ moduleHeader->impOffset += (u32)moduleHeader;
+ if (3 <= newModule->version) {
+ moduleHeader->fixSize += (u32)moduleHeader;
+ }
+ for (i = 1; i < newModule->numSections; i++) {
+ si = &OSGetSectionInfo(newModule)[i];
+ if (si->offset != 0) {
+ si->offset += (u32)moduleHeader;
+ } else if (si->size != 0) {
+ moduleHeader->bssSection = (u8)i;
+ si->offset = (u32)bss;
+ bss = (void*)((u32)bss + si->size);
+ }
+ }
+ for (imp = (OSImportInfo*)moduleHeader->impOffset;
+ imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) {
+ imp->offset += (u32)moduleHeader;
+ }
+ if (moduleHeader->prologSection != SHN_UNDEF) {
+ moduleHeader->prolog +=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset);
+ }
+ if (moduleHeader->epilogSection != SHN_UNDEF) {
+ moduleHeader->epilog +=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset);
+ }
+ if (moduleHeader->unresolvedSection != SHN_UNDEF) {
+ moduleHeader->unresolved +=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset);
+ }
+ if (__OSStringTable) {
+ newModule->nameOffset += (u32)__OSStringTable;
+ }
+
+ Relocate(0, moduleHeader);
+
+ for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) {
+ Relocate(moduleHeader, (OSModuleHeader*)moduleInfo);
+ if (moduleInfo != newModule) {
+ Relocate((OSModuleHeader*)moduleInfo, moduleHeader);
+ }
+ }
+
+ if (fixed) {
+ for (imp = (OSImportInfo*)moduleHeader->impOffset;
+ imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) {
+ if (imp->id == 0 || imp->id == newModule->id) {
+ moduleHeader->impSize = (u32)((u8*)imp - (u8*)moduleHeader->impOffset);
+ break;
+ }
+ }
+ }
+
+ memset(bss, 0, moduleHeader->bssSize);
+
+ OSNotifyLink(newModule);
+
+ return TRUE;
+}
+
+BOOL OSLink(OSModuleInfo* newModule, void* bss) { return Link(newModule, bss, FALSE); }
+
+BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) {
+ if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) {
+ return FALSE;
+ }
+ return Link(newModule, bss, TRUE);
+}
+#else
+BOOL OSLink(OSModuleInfo* newModule, void* bss) {
+ u32 i;
+ OSSectionInfo* si;
+ OSModuleHeader* moduleHeader;
+ OSModuleInfo* moduleInfo;
+ OSImportInfo* imp;
+
+ moduleHeader = (OSModuleHeader*)newModule;
+ moduleHeader->bssSection = 0;
+
+ if (OS_MODULE_VERSION < newModule->version ||
+ 2 <= newModule->version &&
+ (moduleHeader->align && (u32)newModule % moduleHeader->align != 0 ||
+ moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0)) {
+ return FALSE;
+ }
+
+ EnqueueTail(&__OSModuleInfoList, newModule, link);
+ memset(bss, 0, moduleHeader->bssSize);
+ newModule->sectionInfoOffset += (u32)moduleHeader;
+ moduleHeader->relOffset += (u32)moduleHeader;
+ moduleHeader->impOffset += (u32)moduleHeader;
+
+ for (i = 1; i < newModule->numSections; i++) {
+ si = &OSGetSectionInfo(newModule)[i];
+ if (si->offset != 0) {
+ si->offset += (u32)moduleHeader;
+ } else if (si->size != 0) {
+ moduleHeader->bssSection = (u8)i;
+ si->offset = (u32)bss;
+ bss = (void*)((u32)bss + si->size);
+ }
+ }
+ for (imp = (OSImportInfo*)moduleHeader->impOffset;
+ imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) {
+ imp->offset += (u32)moduleHeader;
+ }
+ if (moduleHeader->prologSection != SHN_UNDEF) {
+ moduleHeader->prolog +=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset);
+ }
+ if (moduleHeader->epilogSection != SHN_UNDEF) {
+ moduleHeader->epilog +=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset);
+ }
+ if (moduleHeader->unresolvedSection != SHN_UNDEF) {
+ moduleHeader->unresolved +=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset);
+ }
+ if (__OSStringTable) {
+ newModule->nameOffset += (u32)__OSStringTable;
+ }
+
+ Relocate(0, moduleHeader);
+
+ for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) {
+ Relocate(moduleHeader, (OSModuleHeader*)moduleInfo);
+ if (moduleInfo != newModule) {
+ Relocate((OSModuleHeader*)moduleInfo, moduleHeader);
+ }
+ }
+
+ OSNotifyLink(newModule);
+
+ return TRUE;
+}
+#endif
+
+static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) {
+ OSModuleID idNew;
+ OSImportInfo* imp;
+ OSRel* rel;
+ OSSectionInfo* si;
+ OSSectionInfo* siFlush;
+ u32* p;
+ u32 offset;
+ u32 x;
+
+ idNew = newModule->info.id;
+ for (imp = (OSImportInfo*)module->impOffset;
+ imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++) {
+ if (imp->id == idNew) {
+ goto Found;
+ }
+ }
+ return FALSE;
+
+Found:
+ siFlush = 0;
+ for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) {
+ (u8*)p += rel->offset;
+ si = &OSGetSectionInfo(newModule)[rel->section];
+ offset = OS_SECTIONINFO_OFFSET(si->offset);
+ x = 0;
+ switch (rel->type) {
+ case R_PPC_NONE:
+ break;
+ case R_PPC_ADDR32:
+ *p = x;
+ break;
+ case R_PPC_ADDR24:
+ *p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
+ break;
+ case R_PPC_ADDR16:
+ *(u16*)p = (u16)(x & 0xffff);
+ break;
+ case R_PPC_ADDR16_LO:
+ *(u16*)p = (u16)(x & 0xffff);
+ break;
+ case R_PPC_ADDR16_HI:
+ *(u16*)p = (u16)(((x >> 16) & 0xffff));
+ break;
+ case R_PPC_ADDR16_HA:
+ *(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff);
+ break;
+ case R_PPC_ADDR14:
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_ADDR14_BRNTAKEN:
+ *p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
+ break;
+ case R_PPC_REL24:
+ if (module->unresolvedSection != SHN_UNDEF) {
+ x = (u32)module->unresolved - (u32)p;
+ }
+ *p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
+ break;
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ *p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
+ break;
+ case R_DOLPHIN_NOP:
+ break;
+ case R_DOLPHIN_SECTION:
+ si = &OSGetSectionInfo(module)[rel->section];
+ p = (u32*)OS_SECTIONINFO_OFFSET(si->offset);
+ if (siFlush) {
+ offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
+ DCFlushRange((void*)offset, siFlush->size);
+ ICInvalidateRange((void*)offset, siFlush->size);
+ }
+ siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0;
+ break;
+ default:
+ OSReport("OSUnlink: unknown relocation type %3d\n", rel->type);
+ break;
+ }
+ }
+
+ if (siFlush) {
+ offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
+ DCFlushRange((void*)offset, siFlush->size);
+ ICInvalidateRange((void*)offset, siFlush->size);
+ }
+
+ return TRUE;
+}
+
+BOOL OSUnlink(OSModuleInfo* oldModule) {
+ OSModuleHeader* moduleHeader;
+ OSModuleInfo* moduleInfo;
+ u32 i;
+ OSSectionInfo* si;
+ OSImportInfo* imp;
+
+ moduleHeader = (OSModuleHeader*)oldModule;
+
+ DequeueItem(&__OSModuleInfoList, oldModule, link);
+
+ for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) {
+ Undo(moduleHeader, (OSModuleHeader*)moduleInfo);
+ }
+
+ OSNotifyUnlink(oldModule);
+
+ if (__OSStringTable) {
+ oldModule->nameOffset -= (u32)__OSStringTable;
+ }
+ if (moduleHeader->prologSection != SHN_UNDEF) {
+ moduleHeader->prolog -=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->prologSection].offset);
+ }
+ if (moduleHeader->epilogSection != SHN_UNDEF) {
+ moduleHeader->epilog -=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->epilogSection].offset);
+ }
+ if (moduleHeader->unresolvedSection != SHN_UNDEF) {
+ moduleHeader->unresolved -=
+ OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->unresolvedSection].offset);
+ }
+ for (imp = (OSImportInfo*)moduleHeader->impOffset;
+ imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++) {
+ imp->offset -= (u32)moduleHeader;
+ }
+ for (i = 1; i < oldModule->numSections; i++) {
+ si = &OSGetSectionInfo(oldModule)[i];
+ if (i == moduleHeader->bssSection) {
+ moduleHeader->bssSection = 0;
+ si->offset = 0;
+ } else if (si->offset != 0) {
+ si->offset -= (u32)moduleHeader;
+ }
+ }
+ moduleHeader->relOffset -= (u32)moduleHeader;
+ moduleHeader->impOffset -= (u32)moduleHeader;
+ oldModule->sectionInfoOffset -= (u32)moduleHeader;
+
+ return TRUE;
+}
+
+void __OSModuleInit(void) {
+ __OSModuleInfoList.head = __OSModuleInfoList.tail = 0;
+ __OSStringTable = 0;
+}
+
+OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset) {
+ OSModuleInfo* moduleInfo;
+ OSSectionInfo* sectionInfo;
+ u32 i;
+ u32 baseSection;
+
+ if (ptr == NULL) {
+ return NULL;
+ }
+
+ for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) {
+ sectionInfo = OSGetSectionInfo(moduleInfo);
+ for (i = 0; i < moduleInfo->numSections; ++i) {
+ if (sectionInfo->size) {
+ baseSection = OS_SECTIONINFO_OFFSET(sectionInfo->offset);
+ if (baseSection <= (u32)ptr && (u32)ptr < baseSection + sectionInfo->size) {
+ if (section) {
+ *section = i;
+ }
+ if (offset) {
+ *offset = (u32)ptr - baseSection;
+ }
+ return moduleInfo;
+ }
+ }
+ sectionInfo++;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/Dolphin/os/OSMemory.c b/src/Dolphin/os/OSMemory.c
new file mode 100644
index 0000000..8f76aa8
--- /dev/null
+++ b/src/Dolphin/os/OSMemory.c
@@ -0,0 +1,247 @@
+#include <dolphin/os.h>
+
+#define TRUNC(n, a) (((u32)(n)) & ~((a)-1))
+#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1))
+
+vu16 __MEMRegs[64] : 0xCC004000;
+extern OSErrorHandler __OSErrorTable[16];
+
+static BOOL OnReset(BOOL final);
+
+static OSResetFunctionInfo ResetFunctionInfo = {
+ OnReset,
+ 127,
+};
+
+#ifdef FULL_FRANK
+static BOOL OnReset(BOOL final) {
+ if (final != FALSE) {
+ __MEMRegs[8] = 0xFF;
+ __OSMaskInterrupts(0xf0000000);
+ }
+ return TRUE;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+static asm BOOL OnReset(BOOL final) {
+ nofralloc
+ mflr r0
+ cmpwi r3, 0
+ stw r0, 4(r1)
+ stwu r1, -8(r1)
+ beq @1
+ lis r3, __MEMRegs+16@ha
+ li r0, 0xff
+ sth r0, __MEMRegs+16@l(r3)
+ lis r3, 0xf000
+ bl __OSMaskInterrupts
+@1
+ li r3, 1
+ lwz r0, 0xc(r1)
+ addi r1, r1, 8
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+u32 OSGetPhysicalMemSize() { return *(u32*)(OSPhysicalToCached(0x0028)); }
+
+u32 OSGetConsoleSimulatedMemSize() { return *(u32*)(OSPhysicalToCached(0x00F0)); }
+
+static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
+ u32 addr;
+ u32 cause;
+
+ cause = __MEMRegs[0xf];
+ addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11];
+ __MEMRegs[0x10] = 0;
+
+ if (__OSErrorTable[OS_ERROR_PROTECTION]) {
+ __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr);
+ return;
+ }
+
+ __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr);
+}
+
+void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) {
+ BOOL enabled;
+ u32 start;
+ u32 end;
+ u16 reg;
+ if (4 <= chan) {
+ return;
+ }
+
+ control &= OS_PROTECT_CONTROL_RDWR;
+
+ end = (u32)addr + nBytes;
+ start = TRUNC(addr, 1u << 10);
+ end = ROUND(end, 1u << 10);
+
+ DCFlushRange((void*)start, end - start);
+
+ enabled = OSDisableInterrupts();
+
+ __OSMaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan));
+
+ __MEMRegs[0 + 2 * chan] = (u16)(start >> 10);
+ __MEMRegs[1 + 2 * chan] = (u16)(end >> 10);
+
+ reg = __MEMRegs[8];
+ reg &= ~(OS_PROTECT_CONTROL_RDWR << 2 * chan);
+ reg |= control << 2 * chan;
+ __MEMRegs[8] = reg;
+
+ if (control != OS_PROTECT_CONTROL_RDWR) {
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan));
+ }
+
+ OSRestoreInterrupts(enabled);
+}
+
+asm void Config24MB() {
+ // clang-format off
+ nofralloc
+
+ addi r7,r0,0
+
+ addis r4,r0,0x00000002@ha
+ addi r4,r4,0x00000002@l
+ addis r3,r0,0x800001ff@ha
+ addi r3,r3,0x800001ff@l
+
+ addis r6,r0,0x01000002@ha
+ addi r6,r6,0x01000002@l
+ addis r5,r0,0x810000ff@ha
+ addi r5,r5,0x810000ff@l
+
+ isync
+
+ mtspr dbat0u,r7
+ mtspr dbat0l,r4
+ mtspr dbat0u,r3
+ isync
+
+ mtspr ibat0u,r7
+ mtspr ibat0l,r4
+ mtspr ibat0u,r3
+ isync
+
+ mtspr dbat2u,r7
+ mtspr dbat2l,r6
+ mtspr dbat2u,r5
+ isync
+
+ mtspr ibat2u,r7
+ mtspr ibat2l,r6
+ mtspr ibat2u,r5
+ isync
+
+ mfmsr r3
+ ori r3, r3, 0x30
+ mtsrr1 r3
+
+ mflr r3
+ mtsrr0 r3
+ rfi
+ // clang-format on
+}
+
+asm void Config48MB() {
+ // clang-format off
+ nofralloc
+
+ addi r7,r0,0x0000
+
+ addis r4,r0,0x00000002@ha
+ addi r4,r4,0x00000002@l
+ addis r3,r0,0x800003ff@ha
+ addi r3,r3,0x800003ff@l
+
+ addis r6,r0,0x02000002@ha
+ addi r6,r6,0x02000002@l
+ addis r5,r0,0x820001ff@ha
+ addi r5,r5,0x820001ff@l
+
+ isync
+
+ mtspr dbat0u,r7
+ mtspr dbat0l,r4
+ mtspr dbat0u,r3
+ isync
+
+ mtspr ibat0u,r7
+ mtspr ibat0l,r4
+ mtspr ibat0u,r3
+ isync
+
+ mtspr dbat2u,r7
+ mtspr dbat2l,r6
+ mtspr dbat2u,r5
+ isync
+
+ mtspr ibat2u,r7
+ mtspr ibat2l,r6
+ mtspr ibat2u,r5
+ isync
+
+ mfmsr r3
+ ori r3, r3, 0x30
+ mtsrr1 r3
+
+ mflr r3
+ mtsrr0 r3
+ rfi
+ // clang-format on
+}
+
+asm void RealMode(register u32 addr) {
+ // clang-format off
+ nofralloc
+ clrlwi r3, r3, 2
+ mtsrr0 r3
+ mfmsr r3
+ rlwinm r3, r3, 0, 28, 25
+ mtsrr1 r3
+ rfi
+ // clang-format on
+}
+
+void __OSInitMemoryProtection() {
+ u32 padding[8];
+ u32 simulatedSize;
+ BOOL enabled;
+ simulatedSize = OSGetConsoleSimulatedMemSize();
+ enabled = OSDisableInterrupts();
+ if (simulatedSize <= 0x1800000) {
+ RealMode((u32)&Config24MB);
+ } else if (simulatedSize <= 0x3000000) {
+ RealMode((u32)&Config48MB);
+ }
+
+ __MEMRegs[16] = 0;
+ __MEMRegs[8] = 0xFF;
+
+ __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 |
+ OS_INTERRUPTMASK_MEM_3);
+ __OSSetInterruptHandler(__OS_INTERRUPT_MEM_0, MEMIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_MEM_1, MEMIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_MEM_2, MEMIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_MEM_3, MEMIntrruptHandler);
+ __OSSetInterruptHandler(__OS_INTERRUPT_MEM_ADDRESS, MEMIntrruptHandler);
+ OSRegisterResetFunction(&ResetFunctionInfo);
+
+ if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() &&
+ OSGetConsoleSimulatedMemSize() == 0x1800000) {
+ __MEMRegs[20] = 2;
+ }
+
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS);
+ OSRestoreInterrupts(enabled);
+}
diff --git a/src/Dolphin/os/OSMessage.c b/src/Dolphin/os/OSMessage.c
new file mode 100644
index 0000000..db4d2fd
--- /dev/null
+++ b/src/Dolphin/os/OSMessage.c
@@ -0,0 +1,86 @@
+#include <dolphin/os.h>
+
+void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount) {
+ OSInitThreadQueue(&mq->queueSend);
+ OSInitThreadQueue(&mq->queueReceive);
+ mq->msgArray = msgArray;
+ mq->msgCount = msgCount;
+ mq->firstIndex = 0;
+ mq->usedCount = 0;
+}
+
+BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) {
+ BOOL enabled;
+ s32 lastIndex;
+
+ enabled = OSDisableInterrupts();
+
+ while (mq->msgCount <= mq->usedCount) {
+ if (!(flags & OS_MESSAGE_BLOCK)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ } else {
+ OSSleepThread(&mq->queueSend);
+ }
+ }
+
+ lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount;
+ mq->msgArray[lastIndex] = msg;
+ mq->usedCount++;
+
+ OSWakeupThread(&mq->queueReceive);
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+
+ while (mq->usedCount == 0) {
+ if (!(flags & OS_MESSAGE_BLOCK)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ } else {
+ OSSleepThread(&mq->queueReceive);
+ }
+ }
+
+ if (msg != NULL) {
+ *msg = mq->msgArray[mq->firstIndex];
+ }
+ mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount;
+ mq->usedCount--;
+
+ OSWakeupThread(&mq->queueSend);
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+
+ while (mq->msgCount <= mq->usedCount)
+ {
+ if (!(flags & OS_MESSAGE_BLOCK)) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ } else {
+ OSSleepThread(&mq->queueSend);
+ }
+ }
+
+ mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount;
+ mq->msgArray[mq->firstIndex] = msg;
+ mq->usedCount++;
+
+ OSWakeupThread(&mq->queueReceive);
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
diff --git a/src/Dolphin/os/OSMutex.c b/src/Dolphin/os/OSMutex.c
new file mode 100644
index 0000000..f853729
--- /dev/null
+++ b/src/Dolphin/os/OSMutex.c
@@ -0,0 +1,223 @@
+#include "dolphin/os.h"
+
+#define PushTail(queue, mutex, link) \
+ do { \
+ OSMutex* __prev; \
+ \
+ __prev = (queue)->tail; \
+ if (__prev == NULL) \
+ (queue)->head = (mutex); \
+ else \
+ __prev->link.next = (mutex); \
+ (mutex)->link.prev = __prev; \
+ (mutex)->link.next = NULL; \
+ (queue)->tail = (mutex); \
+ } while (0)
+
+#define PopHead(queue, mutex, link) \
+ do { \
+ OSMutex* __next; \
+ \
+ (mutex) = (queue)->head; \
+ __next = (mutex)->link.next; \
+ if (__next == NULL) \
+ (queue)->tail = NULL; \
+ else \
+ __next->link.prev = NULL; \
+ (queue)->head = __next; \
+ } while (0)
+
+#define PopItem(queue, mutex, link) \
+ do { \
+ OSMutex* __next; \
+ OSMutex* __prev; \
+ \
+ __next = (mutex)->link.next; \
+ __prev = (mutex)->link.prev; \
+ \
+ if (__next == NULL) \
+ (queue)->tail = __prev; \
+ else \
+ __next->link.prev = __prev; \
+ \
+ if (__prev == NULL) \
+ (queue)->head = __next; \
+ else \
+ __prev->link.next = __next; \
+ } while (0)
+
+void OSInitMutex(OSMutex* mutex) {
+ OSInitThreadQueue(&mutex->queue);
+ mutex->thread = 0;
+ mutex->count = 0;
+}
+
+void OSLockMutex(OSMutex* mutex) {
+ BOOL enabled = OSDisableInterrupts();
+ OSThread* currentThread = OSGetCurrentThread();
+ OSThread* ownerThread;
+
+ while (TRUE) {
+ ownerThread = ((OSMutex*)mutex)->thread;
+ if (ownerThread == 0) {
+ mutex->thread = currentThread;
+ mutex->count++;
+ PushTail(&currentThread->queueMutex, mutex, link);
+ break;
+ } else if (ownerThread == currentThread) {
+ mutex->count++;
+ break;
+ } else {
+ currentThread->mutex = mutex;
+ __OSPromoteThread(mutex->thread, currentThread->priority);
+ OSSleepThread(&mutex->queue);
+ currentThread->mutex = 0;
+ }
+ }
+ OSRestoreInterrupts(enabled);
+}
+
+void OSUnlockMutex(OSMutex* mutex) {
+ BOOL enabled = OSDisableInterrupts();
+ OSThread* currentThread = OSGetCurrentThread();
+
+ if (mutex->thread == currentThread && --mutex->count == 0) {
+ PopItem(&currentThread->queueMutex, mutex, link);
+ mutex->thread = NULL;
+ if (currentThread->priority < currentThread->base) {
+ currentThread->priority = __OSGetEffectivePriority(currentThread);
+ }
+
+ OSWakeupThread(&mutex->queue);
+ }
+ OSRestoreInterrupts(enabled);
+}
+
+void __OSUnlockAllMutex(OSThread* thread) {
+ OSMutex* mutex;
+
+ while (thread->queueMutex.head) {
+ PopHead(&thread->queueMutex, mutex, link);
+ mutex->count = 0;
+ mutex->thread = NULL;
+ OSWakeupThread(&mutex->queue);
+ }
+}
+
+BOOL OSTryLockMutex(OSMutex* mutex) {
+ BOOL enabled = OSDisableInterrupts();
+ OSThread* currentThread = OSGetCurrentThread();
+ BOOL locked;
+ if (mutex->thread == 0) {
+ mutex->thread = currentThread;
+ mutex->count++;
+ PushTail(&currentThread->queueMutex, mutex, link);
+ locked = TRUE;
+ } else if (mutex->thread == currentThread) {
+ mutex->count++;
+ locked = TRUE;
+ } else {
+ locked = FALSE;
+ }
+ OSRestoreInterrupts(enabled);
+ return locked;
+}
+
+void OSInitCond(OSCond* cond) { OSInitThreadQueue(&cond->queue); }
+
+void OSWaitCond(OSCond* cond, OSMutex* mutex) {
+ BOOL enabled = OSDisableInterrupts();
+ OSThread* currentThread = OSGetCurrentThread();
+ s32 count;
+
+ if (mutex->thread == currentThread) {
+ count = mutex->count;
+ mutex->count = 0;
+ PopItem(&currentThread->queueMutex, mutex, link);
+ mutex->thread = NULL;
+
+ if (currentThread->priority < currentThread->base) {
+ currentThread->priority = __OSGetEffectivePriority(currentThread);
+ }
+
+ OSDisableScheduler();
+ OSWakeupThread(&mutex->queue);
+ OSEnableScheduler();
+ OSSleepThread(&cond->queue);
+ OSLockMutex(mutex);
+ mutex->count = count;
+ }
+
+ OSRestoreInterrupts(enabled);
+}
+
+void OSSignalCond(OSCond* cond) { OSWakeupThread(&cond->queue); }
+
+static BOOL IsMember(OSMutexQueue* queue, OSMutex* mutex) {
+ OSMutex* member;
+
+ for (member = queue->head; member; member = member->link.next) {
+ if (mutex == member)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL __OSCheckMutex(OSMutex* mutex) {
+ OSThread* thread;
+ OSThreadQueue* queue;
+ OSPriority priority = 0;
+
+ queue = &mutex->queue;
+ if (!(queue->head == NULL || queue->head->link.prev == NULL))
+ return FALSE;
+ if (!(queue->tail == NULL || queue->tail->link.next == NULL))
+ return FALSE;
+ for (thread = queue->head; thread; thread = thread->link.next) {
+ if (!(thread->link.next == NULL || thread == thread->link.next->link.prev))
+ return FALSE;
+ if (!(thread->link.prev == NULL || thread == thread->link.prev->link.next))
+ return FALSE;
+
+ if (thread->state != OS_THREAD_STATE_WAITING)
+ return FALSE;
+
+ if (thread->priority < priority)
+ return FALSE;
+ priority = thread->priority;
+ }
+
+ if (mutex->thread) {
+ if (mutex->count <= 0)
+ return FALSE;
+ } else {
+ if (0 != mutex->count)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL __OSCheckDeadLock(OSThread* thread) {
+ OSMutex* mutex;
+
+ mutex = thread->mutex;
+ while (mutex && mutex->thread) {
+ if (mutex->thread == thread)
+ return TRUE;
+ mutex = mutex->thread->mutex;
+ }
+ return FALSE;
+}
+
+BOOL __OSCheckMutexes(OSThread* thread) {
+ OSMutex* mutex;
+
+ for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) {
+ if (mutex->thread != thread)
+ return FALSE;
+ if (!__OSCheckMutex(mutex))
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/src/Dolphin/os/OSReboot.c b/src/Dolphin/os/OSReboot.c
new file mode 100644
index 0000000..4b952cf
--- /dev/null
+++ b/src/Dolphin/os/OSReboot.c
@@ -0,0 +1,166 @@
+#include <os.h>
+#include <dvd.h>
+
+/*#include <dolphin/dvd/dvd.h>
+#include <dolphin/os/OSCache.h>
+#include <dolphin/os/OSInterrupt.h>
+#include <dolphin/os/OSReset.h>*/
+
+static void *Header[0x20 / sizeof(void *)];
+static void *SaveStart;
+static void *SaveEnd;
+static BOOL Prepared;
+
+void Run(register Event callback)
+{
+ OSDisableInterrupts();
+ ICFlashInvalidate();
+ __sync();
+ __isync();
+ asm {
+ mtlr callback
+ blr
+ }
+}
+
+static void Callback(void)
+{
+ Prepared = TRUE;
+}
+
+#pragma push
+asm void __OSReboot(u32 resetCode, BOOL forceMenu)
+{ // clang-format off
+ nofralloc
+/* 80348144 00344D24 7C 08 02 A6 */ mflr r0
+/* 80348148 00344D28 90 01 00 04 */ stw r0, 4(r1)
+/* 8034814C 00344D2C 94 21 FC B8 */ stwu r1, -0x348(r1)
+/* 80348150 00344D30 93 E1 03 44 */ stw r31, 0x344(r1)
+/* 80348154 00344D34 93 C1 03 40 */ stw r30, 0x340(r1)
+/* 80348158 00344D38 93 A1 03 3C */ stw r29, 0x33c(r1)
+/* 8034815C 00344D3C 7C 7D 1B 78 */ mr r29, r3
+/* 80348160 00344D40 3C 60 80 4A */ lis r3, Header@ha
+/* 80348164 00344D44 3B C3 7D 40 */ addi r30, r3, Header@l
+/* 80348168 00344D48 4B FF F1 FD */ bl OSDisableInterrupts
+/* 8034816C 00344D4C 80 AD BC F0 */ lwz r5, SaveStart(r13)
+/* 80348170 00344D50 3F E0 81 80 */ lis r31, 0x817FFFFC@ha
+/* 80348174 00344D54 38 60 00 00 */ li r3, 0
+/* 80348178 00344D58 80 0D BC F4 */ lwz r0, SaveEnd(r13)
+/* 8034817C 00344D5C 3C 80 81 30 */ lis r4, 0x812FDFF0@ha
+/* 80348180 00344D60 38 E0 00 01 */ li r7, 1
+/* 80348184 00344D64 93 BF FF FC */ stw r29, 0x817FFFFC@l(r31)
+/* 80348188 00344D68 3C C0 80 00 */ lis r6, 0x800030E2@ha
+/* 8034818C 00344D6C 90 7F FF F8 */ stw r3, -8(r31)
+/* 80348190 00344D70 38 61 00 70 */ addi r3, r1, 0x70
+/* 80348194 00344D74 98 E6 30 E2 */ stb r7, 0x800030E2@l(r6)
+/* 80348198 00344D78 90 A4 DF F0 */ stw r5, 0x812FDFF0@l(r4)
+/* 8034819C 00344D7C 90 04 DF EC */ stw r0, -0x2014(r4)
+/* 803481A0 00344D80 4B FF D0 B5 */ bl OSClearContext
+/* 803481A4 00344D84 38 61 00 70 */ addi r3, r1, 0x70
+/* 803481A8 00344D88 4B FF CE E5 */ bl OSSetCurrentContext
+/* 803481AC 00344D8C 4B FE FC 3D */ bl DVDInit
+/* 803481B0 00344D90 38 60 00 01 */ li r3, 1
+/* 803481B4 00344D94 4B FF 1A 45 */ bl DVDSetAutoInvalidation
+/* 803481B8 00344D98 3C 60 80 35 */ lis r3, Callback@ha
+/* 803481BC 00344D9C 38 63 81 38 */ addi r3, r3, Callback@l
+/* 803481C0 00344DA0 4B FF 1E 75 */ bl __DVDPrepareResetAsync
+/* 803481C4 00344DA4 4B FF 1D 8D */ bl DVDCheckDisk
+/* 803481C8 00344DA8 2C 03 00 00 */ cmpwi r3, 0
+/* 803481CC 00344DAC 40 82 00 0C */ bne lbl_803481D8
+/* 803481D0 00344DB0 80 7F FF FC */ lwz r3, -4(r31)
+/* 803481D4 00344DB4 48 00 02 31 */ bl __OSDoHotReset
+lbl_803481D8:
+/* 803481D8 00344DB8 38 60 FF E0 */ li r3, -32
+/* 803481DC 00344DBC 4B FF F5 51 */ bl __OSMaskInterrupts
+/* 803481E0 00344DC0 38 60 04 00 */ li r3, 0x400
+/* 803481E4 00344DC4 4B FF F5 D1 */ bl __OSUnmaskInterrupts
+/* 803481E8 00344DC8 4B FF F1 91 */ bl OSEnableInterrupts
+/* 803481EC 00344DCC 48 00 00 04 */ b lbl_803481F0
+lbl_803481F0:
+/* 803481F0 00344DD0 48 00 00 04 */ b lbl_803481F4
+lbl_803481F4:
+/* 803481F4 00344DD4 80 0D BC F8 */ lwz r0, Prepared(r13)
+/* 803481F8 00344DD8 2C 00 00 00 */ cmpwi r0, 0
+/* 803481FC 00344DDC 41 82 FF F8 */ beq lbl_803481F4
+/* 80348200 00344DE0 7F C4 F3 78 */ mr r4, r30
+/* 80348204 00344DE4 38 61 00 40 */ addi r3, r1, 0x40
+/* 80348208 00344DE8 38 A0 00 20 */ li r5, 0x20
+/* 8034820C 00344DEC 38 C0 24 40 */ li r6, 0x2440
+/* 80348210 00344DF0 38 E0 00 00 */ li r7, 0
+/* 80348214 00344DF4 4B FF 17 51 */ bl DVDReadAbsAsyncForBS
+/* 80348218 00344DF8 3F E0 81 80 */ lis r31, 0x8180
+/* 8034821C 00344DFC 48 00 00 04 */ b lbl_80348220
+lbl_80348220:
+/* 80348220 00344E00 48 00 00 04 */ b lbl_80348224
+lbl_80348224:
+/* 80348224 00344E04 80 01 00 4C */ lwz r0, 0x4c(r1)
+/* 80348228 00344E08 2C 00 00 01 */ cmpwi r0, 1
+/* 8034822C 00344E0C 41 82 FF F8 */ beq lbl_80348224
+/* 80348230 00344E10 40 80 00 14 */ bge lbl_80348244
+/* 80348234 00344E14 2C 00 FF FF */ cmpwi r0, -1
+/* 80348238 00344E18 41 82 00 18 */ beq lbl_80348250
+/* 8034823C 00344E1C 40 80 00 20 */ bge lbl_8034825C
+/* 80348240 00344E20 4B FF FF E4 */ b lbl_80348224
+lbl_80348244:
+/* 80348244 00344E24 2C 00 00 0C */ cmpwi r0, 0xc
+/* 80348248 00344E28 40 80 FF DC */ bge lbl_80348224
+/* 8034824C 00344E2C 48 00 00 04 */ b lbl_80348250
+lbl_80348250:
+/* 80348250 00344E30 80 7F FF FC */ lwz r3, -4(r31)
+/* 80348254 00344E34 48 00 01 B1 */ bl __OSDoHotReset
+/* 80348258 00344E38 4B FF FF CC */ b lbl_80348224
+lbl_8034825C:
+/* 8034825C 00344E3C 80 7E 00 18 */ lwz r3, 0x18(r30)
+/* 80348260 00344E40 80 9E 00 14 */ lwz r4, 0x14(r30)
+/* 80348264 00344E44 38 03 00 1F */ addi r0, r3, 0x1f
+/* 80348268 00344E48 38 84 00 20 */ addi r4, r4, 0x20
+/* 8034826C 00344E4C 54 1E 00 34 */ rlwinm r30, r0, 0, 0, 0x1a
+/* 80348270 00344E50 48 00 00 04 */ b lbl_80348274
+lbl_80348274:
+/* 80348274 00344E54 48 00 00 04 */ b lbl_80348278
+lbl_80348278:
+/* 80348278 00344E58 80 0D BC F8 */ lwz r0, Prepared(r13)
+/* 8034827C 00344E5C 2C 00 00 00 */ cmpwi r0, 0
+/* 80348280 00344E60 41 82 FF F8 */ beq lbl_80348278
+/* 80348284 00344E64 7F C5 F3 78 */ mr r5, r30
+/* 80348288 00344E68 38 61 00 10 */ addi r3, r1, 0x10
+/* 8034828C 00344E6C 38 C4 24 40 */ addi r6, r4, 0x2440
+/* 80348290 00344E70 3C 80 81 30 */ lis r4, 0x8130
+/* 80348294 00344E74 38 E0 00 00 */ li r7, 0
+/* 80348298 00344E78 4B FF 16 CD */ bl DVDReadAbsAsyncForBS
+/* 8034829C 00344E7C 3F E0 81 80 */ lis r31, 0x8180
+/* 803482A0 00344E80 48 00 00 04 */ b lbl_803482A4
+lbl_803482A4:
+/* 803482A4 00344E84 48 00 00 04 */ b lbl_803482A8
+lbl_803482A8:
+/* 803482A8 00344E88 80 01 00 1C */ lwz r0, 0x1c(r1)
+/* 803482AC 00344E8C 2C 00 00 01 */ cmpwi r0, 1
+/* 803482B0 00344E90 41 82 FF F8 */ beq lbl_803482A8
+/* 803482B4 00344E94 40 80 00 14 */ bge lbl_803482C8
+/* 803482B8 00344E98 2C 00 FF FF */ cmpwi r0, -1
+/* 803482BC 00344E9C 41 82 00 18 */ beq lbl_803482D4
+/* 803482C0 00344EA0 40 80 00 20 */ bge lbl_803482E0
+/* 803482C4 00344EA4 4B FF FF E4 */ b lbl_803482A8
+lbl_803482C8:
+/* 803482C8 00344EA8 2C 00 00 0C */ cmpwi r0, 0xc
+/* 803482CC 00344EAC 40 80 FF DC */ bge lbl_803482A8
+/* 803482D0 00344EB0 48 00 00 04 */ b lbl_803482D4
+lbl_803482D4:
+/* 803482D4 00344EB4 80 7F FF FC */ lwz r3, -4(r31)
+/* 803482D8 00344EB8 48 00 01 2D */ bl __OSDoHotReset
+/* 803482DC 00344EBC 4B FF FF CC */ b lbl_803482A8
+lbl_803482E0:
+/* 803482E0 00344EC0 3C 60 81 30 */ lis r3, 0x8130
+/* 803482E4 00344EC4 7F C4 F3 78 */ mr r4, r30
+/* 803482E8 00344EC8 4B FF C5 ED */ bl ICInvalidateRange
+/* 803482EC 00344ECC 3C 60 81 30 */ lis r3, 0x8130
+/* 803482F0 00344ED0 4B FF FE 09 */ bl Run
+/* 803482F4 00344ED4 80 01 03 4C */ lwz r0, 0x34c(r1)
+/* 803482F8 00344ED8 83 E1 03 44 */ lwz r31, 0x344(r1)
+/* 803482FC 00344EDC 83 C1 03 40 */ lwz r30, 0x340(r1)
+/* 80348300 00344EE0 7C 08 03 A6 */ mtlr r0
+/* 80348304 00344EE4 83 A1 03 3C */ lwz r29, 0x33c(r1)
+/* 80348308 00344EE8 38 21 03 48 */ addi r1, r1, 0x348
+/* 8034830C 00344EEC 4E 80 00 20 */ blr
+} // clang-format on
+#pragma pop
diff --git a/src/Dolphin/os/OSReset.c b/src/Dolphin/os/OSReset.c
index a9cc186..ebd0b04 100644
--- a/src/Dolphin/os/OSReset.c
+++ b/src/Dolphin/os/OSReset.c
@@ -1,5 +1,190 @@
-#include "dolphin/OSReset.h"
+#include "dolphin/OSRtcPriv.h"
+#include "dolphin/os.h"
+#include "dolphin/vi.h"
-void OSResetSystem(int reset, unsigned int resetCode, int forceMenu) {
+volatile u8 DAT_800030e2 : 0x800030e2;
+typedef struct Unk {
+ u8 pad[0x24];
+ u32 resetCode;
+} Unk;
+volatile Unk DAT_cc003000 : 0xcc003000;
+typedef struct Unk2 {
+ u16 _0;
+ u16 _2;
+} Unk2;
+
+volatile Unk2 DAT_cc002000 : 0xcc002000;
+
+typedef struct OSResetQueue {
+ OSResetFunctionInfo* first;
+ OSResetFunctionInfo* last;
+} OSResetQueue;
+
+OSResetQueue ResetFunctionQueue;
+
+void OSRegisterResetFunction(OSResetFunctionInfo* func) {
+ OSResetFunctionInfo* tmp;
+ OSResetFunctionInfo* iter;
+
+ for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next)
+ ;
+
+ if (iter == NULL) {
+ tmp = ResetFunctionQueue.last;
+ if (tmp == NULL) {
+ ResetFunctionQueue.first = func;
+ } else {
+ tmp->next = func;
+ }
+ func->prev = tmp;
+ func->next = NULL;
+ ResetFunctionQueue.last = func;
+ return;
+ }
+
+ func->next = iter;
+ tmp = iter->prev;
+ iter->prev = func;
+ func->prev = tmp;
+ if (tmp == NULL) {
+ ResetFunctionQueue.first = func;
+ return;
+ }
+ tmp->next = func;
+}
+
+BOOL __OSCallResetFunctions(u32 arg0) {
+ OSResetFunctionInfo* iter;
+ s32 retCode = 0;
+
+ for (iter = ResetFunctionQueue.first; iter != NULL; iter = iter->next) {
+ retCode |= !iter->func(arg0);
+ }
+ retCode |= !__OSSyncSram();
+ if (retCode) {
+ return 0;
+ }
+ return 1;
+}
+
+asm void Reset(register s32 resetCode) {
+ // clang-format off
+ nofralloc
+ b lbl_8038315C
+lbl_80383140:
+ mfspr r8, HID0
+ ori r8, r8, 8
+ mtspr HID0, r8
+ isync
+ sync
+ nop
+ b lbl_80383160
+lbl_8038315C:
+ b lbl_8038317C
+lbl_80383160:
+ mftb r5, 268
+lbl_80383164:
+ mftb r6, 268
+ subf r7, r5, r6
+ cmplwi r7, 0x1124
+ blt lbl_80383164
+ nop
+ b lbl_80383180
+lbl_8038317C:
+ b lbl_8038319C
+lbl_80383180:
+ lis r8, 0xCC003000@h
+ ori r8, r8, 0xCC003000@l
+ li r4, 3
+ stw r4, 0x24(r8)
+ stw r3, 0x24(r8)
+ nop
+ b lbl_803831A0
+lbl_8038319C:
+ b lbl_803831A8
+lbl_803831A0:
+ nop
+ b lbl_803831A0
+lbl_803831A8:
+ b lbl_80383140
+ // clang-format on
+}
+
+OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC);
+
+static void KillThreads(void) {
+ OSThread* thread;
+ OSThread* next;
+
+ for (thread = __OSActiveThreadQueue.head; thread; thread = next) {
+ next = thread->linkActive.next;
+ switch (thread->state) {
+ case 1:
+ case 4:
+ OSCancelThread(thread);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void __OSDoHotReset(s32 arg0) {
+ OSDisableInterrupts();
+ __VIRegs[1] = 0;
+ ICFlashInvalidate();
+ Reset(arg0 * 8);
+}
+
+void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) {
+ BOOL rc;
+ BOOL disableRecalibration;
+ u32 unk[3];
+ OSDisableScheduler();
+ __OSStopAudioSystem();
+
+ if (reset == OS_RESET_SHUTDOWN) {
+ disableRecalibration = __PADDisableRecalibration(TRUE);
+ }
+
+ while (!__OSCallResetFunctions(FALSE))
+ ;
+
+ if (reset == OS_RESET_HOTRESET && forceMenu) {
+ OSSram* sram;
+
+ sram = __OSLockSram();
+ sram->flags |= 0x40;
+ __OSUnlockSram(TRUE);
+
+ while (!__OSSyncSram())
+ ;
+ }
+ OSDisableInterrupts();
+ __OSCallResetFunctions(TRUE);
+ LCDisable();
+ if (reset == OS_RESET_HOTRESET) {
+ __OSDoHotReset(resetCode);
+ } else if (reset == OS_RESET_RESTART) {
+ KillThreads();
+ OSEnableScheduler();
+ __OSReboot(resetCode, forceMenu);
+ }
+ KillThreads();
+ memset(OSPhysicalToCached(0x40), 0, 0xcc - 0x40);
+ memset(OSPhysicalToCached(0xd4), 0, 0xe8 - 0xd4);
+ memset(OSPhysicalToCached(0xf4), 0, 0xf8 - 0xf4);
+ memset(OSPhysicalToCached(0x3000), 0, 0xc0);
+ memset(OSPhysicalToCached(0x30c8), 0, 0xd4 - 0xc8);
+ memset(OSPhysicalToCached(0x30e2), 0, 1);
+
+ __PADDisableRecalibration(disableRecalibration);
+}
+
+u32 OSGetResetCode(void) {
+ if (DAT_800030e2 != 0) {
+ return 0x80000000;
+ }
+ return ((DAT_cc003000.resetCode & ~7) >> 3);
}
diff --git a/src/Dolphin/os/OSResetSW.c b/src/Dolphin/os/OSResetSW.c
new file mode 100644
index 0000000..9752213
--- /dev/null
+++ b/src/Dolphin/os/OSResetSW.c
@@ -0,0 +1,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
diff --git a/src/Dolphin/os/OSRtc.c b/src/Dolphin/os/OSRtc.c
new file mode 100644
index 0000000..be14670
--- /dev/null
+++ b/src/Dolphin/os/OSRtc.c
@@ -0,0 +1,544 @@
+#include "dolphin/OSRtcPriv.h"
+#include "dolphin/os.h"
+
+#define RTC_CMD_READ 0x20000000
+#define RTC_CMD_WRITE 0xa0000000
+
+#define RTC_SRAM_ADDR 0x00000100
+#define RTC_SRAM_SIZE 64
+
+#define RTC_CHAN 0
+#define RTC_DEV 1
+#define RTC_FREQ 3 // EXI_FREQ_8M
+
+typedef struct SramControlBlock {
+ u8 sram[RTC_SRAM_SIZE];
+ u32 offset;
+ BOOL enabled;
+ BOOL locked;
+ BOOL sync;
+ void (*callback)(void);
+} SramControlBlock;
+
+static SramControlBlock Scb ATTRIBUTE_ALIGN(32);
+
+static BOOL GetRTC(u32* rtc) {
+ BOOL err;
+ u32 cmd;
+
+ if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
+ return FALSE;
+ }
+ if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
+ EXIUnlock(RTC_CHAN);
+ return FALSE;
+ }
+
+ cmd = RTC_CMD_READ;
+ err = FALSE;
+ err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIImm(RTC_CHAN, &cmd, 4, 0, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIDeselect(RTC_CHAN);
+ EXIUnlock(RTC_CHAN);
+
+ *rtc = cmd;
+
+ return !err;
+}
+
+BOOL __OSGetRTC(u32* rtc) {
+ BOOL err;
+ u32 t0;
+ u32 t1;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ err = FALSE;
+ err |= !GetRTC(&t0);
+ err |= !GetRTC(&t1);
+ if (err) {
+ break;
+ }
+ if (t0 == t1) {
+ *rtc = t0;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL __OSSetRTC(u32 rtc) {
+ BOOL err;
+ u32 cmd;
+
+ if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
+ return FALSE;
+ }
+ if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
+ EXIUnlock(RTC_CHAN);
+ return FALSE;
+ }
+
+ cmd = RTC_CMD_WRITE;
+ err = FALSE;
+ err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIImm(RTC_CHAN, &rtc, 4, 1, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIDeselect(RTC_CHAN);
+ EXIUnlock(RTC_CHAN);
+
+ return !err;
+}
+
+static BOOL ReadSram(void* buffer) {
+ BOOL err;
+ u32 cmd;
+
+ DCInvalidateRange(buffer, RTC_SRAM_SIZE);
+
+ if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
+ return FALSE;
+ }
+ if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
+ EXIUnlock(RTC_CHAN);
+ return FALSE;
+ }
+
+ cmd = RTC_CMD_READ | RTC_SRAM_ADDR;
+ err = FALSE;
+ err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIDma(RTC_CHAN, buffer, RTC_SRAM_SIZE, 0, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIDeselect(RTC_CHAN);
+ EXIUnlock(RTC_CHAN);
+
+ return !err;
+}
+
+BOOL WriteSram(void* buffer, u32 offset, u32 size);
+static void WriteSramCallback(s32 chan, OSContext* context) {
+ Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset);
+ if (Scb.sync) {
+ Scb.offset = RTC_SRAM_SIZE;
+ }
+}
+
+BOOL WriteSram(void* buffer, u32 offset, u32 size) {
+ BOOL err;
+ u32 cmd;
+
+ if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) {
+ return FALSE;
+ }
+ if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
+ EXIUnlock(RTC_CHAN);
+ return FALSE;
+ }
+
+ offset <<= 6;
+ cmd = RTC_CMD_WRITE | RTC_SRAM_ADDR + offset;
+ err = FALSE;
+ err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIImmEx(RTC_CHAN, buffer, (s32)size, 1);
+ err |= !EXIDeselect(RTC_CHAN);
+ EXIUnlock(RTC_CHAN);
+
+ return !err;
+}
+
+void __OSInitSram() {
+ Scb.locked = Scb.enabled = FALSE;
+ Scb.sync = ReadSram(Scb.sram);
+ Scb.offset = RTC_SRAM_SIZE;
+}
+
+static void* LockSram(u32 offset) {
+ BOOL enabled;
+ enabled = OSDisableInterrupts();
+
+ if (Scb.locked != FALSE) {
+ OSRestoreInterrupts(enabled);
+ return NULL;
+ }
+
+ Scb.enabled = enabled;
+ Scb.locked = TRUE;
+
+ return Scb.sram + offset;
+}
+
+#ifdef FULL_FRANK
+OSSram* __OSLockSram() { return LockSram(0); }
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm OSSram* __OSLockSram() {
+ nofralloc
+ mflr r0
+ lis r3, Scb@ha
+ stw r0, 4(r1)
+ stwu r1, -0x10(r1)
+ stw r31, 0xc(r1)
+ addi r31, r3, Scb@l
+ bl OSDisableInterrupts
+ lwz r0, 0x48(r31)
+ addi r4, r31, 0x48
+ cmpwi r0, 0
+ beq lbl_80383B0C
+ bl OSRestoreInterrupts
+ li r31, 0
+ b lbl_80383B18
+lbl_80383B0C:
+ stw r3, 0x44(r31)
+ li r0, 1
+ stw r0, 0(r4)
+lbl_80383B18:
+ mr r3, r31
+ lwz r0, 0x14(r1)
+ lwz r31, 0xc(r1)
+ addi r1, r1, 0x10
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); }
+
+static BOOL UnlockSram(BOOL commit, u32 offset) {
+ u16* p;
+
+ if (commit) {
+ if (offset == 0) {
+ OSSram* sram = (OSSram*)Scb.sram;
+
+ if (2u < (sram->flags & 3)) {
+ sram->flags &= ~3;
+ }
+
+ sram->checkSum = sram->checkSumInv = 0;
+ for (p = (u16*)&sram->counterBias; p < (u16*)(Scb.sram + sizeof(OSSram)); p++) {
+ sram->checkSum += *p;
+ sram->checkSumInv += ~*p;
+ }
+ }
+
+ if (offset < Scb.offset) {
+ Scb.offset = offset;
+ }
+
+ Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset);
+ if (Scb.sync) {
+ Scb.offset = RTC_SRAM_SIZE;
+ }
+ }
+ Scb.locked = FALSE;
+ OSRestoreInterrupts(Scb.enabled);
+ return Scb.sync;
+}
+
+BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); }
+
+BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); }
+
+BOOL __OSSyncSram() { return Scb.sync; }
+
+BOOL __OSReadROM(void* buffer, s32 length, s32 offset) {
+ BOOL err;
+ u32 cmd;
+
+ DCInvalidateRange(buffer, (u32)length);
+
+ if (!EXILock(RTC_CHAN, RTC_DEV, 0)) {
+ return FALSE;
+ }
+ if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) {
+ EXIUnlock(RTC_CHAN);
+ return FALSE;
+ }
+
+ cmd = (u32)(offset << 6);
+ err = FALSE;
+ err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIDma(RTC_CHAN, buffer, length, 0, NULL);
+ err |= !EXISync(RTC_CHAN);
+ err |= !EXIDeselect(RTC_CHAN);
+ EXIUnlock(RTC_CHAN);
+
+ return !err;
+}
+
+inline OSSram* __OSLockSramHACK() { return LockSram(0); }
+#ifdef FULL_FRANK
+u32 OSGetSoundMode() {
+ OSSram* sram;
+ u32 mode;
+
+ sram = __OSLockSramHACK();
+ mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO;
+ __OSUnlockSram(FALSE);
+ return mode;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm u32 OSGetSoundMode() {
+ nofralloc
+ mflr r0
+ lis r3, Scb@ha
+ stw r0, 4(r1)
+ stwu r1, -0x20(r1)
+ stw r31, 0x1c(r1)
+ addi r31, r3, Scb@l
+ bl OSDisableInterrupts
+ lwz r0, 0x48(r31)
+ addi r4, r31, 0x48
+ cmpwi r0, 0
+ beq lbl_80384048
+ bl OSRestoreInterrupts
+ li r31, 0
+ b lbl_80384054
+lbl_80384048:
+ stw r3, 0x44(r31)
+ li r0, 1
+ stw r0, 0(r4)
+lbl_80384054:
+ lbz r0, 0x13(r31)
+ rlwinm. r0, r0, 0, 0x1d, 0x1d
+ beq lbl_80384068
+ li r31, 1
+ b lbl_8038406C
+lbl_80384068:
+ li r31, 0
+lbl_8038406C:
+ li r3, 0
+ li r4, 0
+ bl UnlockSram
+ mr r3, r31
+ lwz r0, 0x24(r1)
+ lwz r31, 0x1c(r1)
+ addi r1, r1, 0x20
+ mtlr r0
+ blr
+
+}
+#pragma pop
+/* clang-format on */
+#endif
+void OSSetSoundMode(u32 mode) {
+ OSSram* sram;
+ mode <<= 2;
+ mode &= 4;
+
+ sram = __OSLockSramHACK();
+ if (mode == (sram->flags & 4)) {
+ __OSUnlockSram(FALSE);
+ return;
+ }
+
+ sram->flags &= ~4;
+ sram->flags |= mode;
+ __OSUnlockSram(TRUE);
+}
+
+#ifdef FULL_FRANK
+u32 OSGetProgressiveMode() {
+ OSSram* sram;
+ u32 mode;
+
+ sram = __OSLockSramHACK();
+ mode = (sram->flags & 0x80) >> 7;
+ __OSUnlockSram(FALSE);
+ return mode;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm u32 OSGetProgressiveMode() {
+ nofralloc
+/* 80384134 00381094 7C 08 02 A6 */ mflr r0
+/* 80384138 00381098 3C 60 80 54 */ lis r3, Scb@ha
+/* 8038413C 0038109C 90 01 00 04 */ stw r0, 4(r1)
+/* 80384140 003810A0 94 21 FF E8 */ stwu r1, -0x18(r1)
+/* 80384144 003810A4 93 E1 00 14 */ stw r31, 0x14(r1)
+/* 80384148 003810A8 3B E3 15 A0 */ addi r31, r3, Scb@l
+/* 8038414C 003810AC 4B FF D5 15 */ bl OSDisableInterrupts
+/* 80384150 003810B0 80 1F 00 48 */ lwz r0, 0x48(r31)
+/* 80384154 003810B4 38 9F 00 48 */ addi r4, r31, 0x48
+/* 80384158 003810B8 2C 00 00 00 */ cmpwi r0, 0
+/* 8038415C 003810BC 41 82 00 10 */ beq lbl_8038416C
+/* 80384160 003810C0 4B FF D5 29 */ bl OSRestoreInterrupts
+/* 80384164 003810C4 3B E0 00 00 */ li r31, 0
+/* 80384168 003810C8 48 00 00 10 */ b lbl_80384178
+lbl_8038416C:
+/* 8038416C 003810CC 90 7F 00 44 */ stw r3, 0x44(r31)
+/* 80384170 003810D0 38 00 00 01 */ li r0, 1
+/* 80384174 003810D4 90 04 00 00 */ stw r0, 0(r4)
+lbl_80384178:
+/* 80384178 003810D8 88 1F 00 13 */ lbz r0, 0x13(r31)
+/* 8038417C 003810DC 38 60 00 00 */ li r3, 0
+/* 80384180 003810E0 38 80 00 00 */ li r4, 0
+/* 80384184 003810E4 54 1F CF FE */ rlwinm r31, r0, 0x19, 0x1f, 0x1f
+/* 80384188 003810E8 4B FF FA 05 */ bl UnlockSram
+/* 8038418C 003810EC 7F E3 FB 78 */ mr r3, r31
+/* 80384190 003810F0 80 01 00 1C */ lwz r0, 0x1c(r1)
+/* 80384194 003810F4 83 E1 00 14 */ lwz r31, 0x14(r1)
+/* 80384198 003810F8 38 21 00 18 */ addi r1, r1, 0x18
+/* 8038419C 003810FC 7C 08 03 A6 */ mtlr r0
+/* 803841A0 00381100 4E 80 00 20 */ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+void OSSetProgressiveMode(u32 mode) {
+ OSSram* sram;
+ mode <<= 7;
+ mode &= 0x80;
+
+ sram = __OSLockSramHACK();
+ if (mode == (sram->flags & 0x80)) {
+ __OSUnlockSram(FALSE);
+ return;
+ }
+
+ sram->flags &= ~0x80;
+ sram->flags |= mode;
+ __OSUnlockSram(TRUE);
+}
+
+#ifdef FULL_FRANK
+u8 OSGetLanguage() {
+ OSSram* sram;
+ u8 language;
+
+ sram = __OSLockSramHACK();
+ language = sram->language;
+ __OSUnlockSram(FALSE);
+ return language;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm u8 OSGetLanguage() {
+ nofralloc
+ mflr r0
+ lis r3, Scb@ha
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ addi r31, r3, Scb@l
+ bl OSDisableInterrupts
+ lwz r0, 0x48(r31)
+ addi r4, r31, 0x48
+ cmpwi r0, 0
+ beq lbl_80384280
+ bl OSRestoreInterrupts
+ li r31, 0
+ b lbl_8038428C
+lbl_80384280:
+ stw r3, 0x44(r31)
+ li r0, 1
+ stw r0, 0(r4)
+lbl_8038428C:
+ lbz r31, 0x12(r31)
+ li r3, 0
+ li r4, 0
+ bl UnlockSram
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+#ifdef FULL_FRANK
+u16 OSGetWirelessID(s32 channel) {
+ OSSramEx* sram;
+ u16 id;
+
+ sram = __OSLockSramEx();
+ id = sram->wirelessPadID[channel];
+ __OSUnlockSramEx(FALSE);
+ return id;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+
+asm u16 OSGetWirelessID(s32 channel) {
+ nofralloc
+ mflr r0
+ lis r4, Scb@ha
+ stw r0, 4(r1)
+ stwu r1, -0x20(r1)
+ stw r31, 0x1c(r1)
+ addi r31, r4, Scb@l
+ stw r30, 0x18(r1)
+ addi r30, r3, 0
+ bl OSDisableInterrupts
+ lwz r0, 0x48(r31)
+ addi r4, r31, 0x48
+ cmpwi r0, 0
+ beq lbl_803842F4
+ bl OSRestoreInterrupts
+ li r3, 0
+ b lbl_80384304
+lbl_803842F4:
+ stw r3, 0x44(r31)
+ li r0, 1
+ addi r3, r31, 0x14
+ stw r0, 0(r4)
+lbl_80384304:
+ slwi r0, r30, 1
+ add r3, r3, r0
+ lhz r31, 0x1c(r3)
+ li r3, 0
+ li r4, 0x14
+ bl UnlockSram
+ mr r3, r31
+ lwz r0, 0x24(r1)
+ lwz r31, 0x1c(r1)
+ lwz r30, 0x18(r1)
+ addi r1, r1, 0x20
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+
+void OSSetWirelessID(s32 channel, u16 id) {
+ OSSramEx* sram;
+
+ sram = __OSLockSramEx();
+ if (sram->wirelessPadID[channel] != id) {
+ sram->wirelessPadID[channel] = id;
+ __OSUnlockSramEx(TRUE);
+ return;
+ }
+
+ __OSUnlockSramEx(FALSE);
+}
diff --git a/src/Dolphin/os/OSSync.c b/src/Dolphin/os/OSSync.c
new file mode 100644
index 0000000..b5aeccf
--- /dev/null
+++ b/src/Dolphin/os/OSSync.c
@@ -0,0 +1,29 @@
+#include "string.h"
+#include "dolphin/PPCArch.h"
+#include "dolphin/os.h"
+
+void __OSSystemCallVectorStart();
+void __OSSystemCallVectorEnd();
+static asm void SystemCallVector() {
+ nofralloc
+entry __OSSystemCallVectorStart
+ mfspr r9, HID0
+ ori r10, r9, 8
+ mtspr HID0, r10
+ isync
+ sync
+ mtspr HID0, r9
+
+ rfi
+
+entry __OSSystemCallVectorEnd
+ nop
+}
+
+void __OSInitSystemCall() {
+ void* addr = OSPhysicalToCached(0x00C00);
+ memcpy(addr, __OSSystemCallVectorStart, (size_t)__OSSystemCallVectorEnd - (size_t)__OSSystemCallVectorStart);
+ DCFlushRangeNoSync(addr, 0x100);
+ __sync();
+ ICInvalidateRange(addr, 0x100);
+}
diff --git a/src/Dolphin/os/OSThread.c b/src/Dolphin/os/OSThread.c
new file mode 100644
index 0000000..3bd1e5d
--- /dev/null
+++ b/src/Dolphin/os/OSThread.c
@@ -0,0 +1,852 @@
+#include "dolphin/os/OSPriv.h"
+
+static vu32 RunQueueBits;
+static volatile BOOL RunQueueHint;
+static vs32 Reschedule;
+
+static OSThreadQueue RunQueue[32];
+static OSThread IdleThread;
+static OSThread DefaultThread;
+static OSContext IdleContext;
+static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to);
+static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback;
+
+OSThread* __OSCurrentThread : OS_BASE_CACHED + 0x00E4;
+OSThreadQueue __OSActiveThreadQueue : OS_BASE_CACHED + 0x00DC;
+volatile OSContext __OSCurrentContext : OS_BASE_CACHED + 0x00D4;
+volatile OSContext* __OSFPUContext : OS_BASE_CACHED + 0x00D8;
+
+static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {}
+
+extern u8 _stack_addr[];
+extern u8 _stack_end[];
+
+#define AddTail(queue, thread, link) \
+ do { \
+ OSThread* prev; \
+ \
+ prev = (queue)->tail; \
+ if (prev == NULL) \
+ (queue)->head = (thread); \
+ else \
+ prev->link.next = (thread); \
+ (thread)->link.prev = prev; \
+ (thread)->link.next = NULL; \
+ (queue)->tail = (thread); \
+ } while (0)
+
+#define AddPrio(queue, thread, link) \
+ do { \
+ OSThread *prev, *next; \
+ \
+ for (next = (queue)->head; next && next->priority <= thread->priority; next = next->link.next) \
+ ; \
+ if (next == NULL) \
+ AddTail(queue, thread, link); \
+ else { \
+ (thread)->link.next = next; \
+ prev = next->link.prev; \
+ next->link.prev = (thread); \
+ (thread)->link.prev = prev; \
+ if (prev == NULL) \
+ (queue)->head = (thread); \
+ else \
+ prev->link.next = (thread); \
+ } \
+ } while (0)
+
+#define RemoveItem(queue, thread, link) \
+ do { \
+ OSThread *next, *prev; \
+ next = (thread)->link.next; \
+ prev = (thread)->link.prev; \
+ if (next == NULL) \
+ (queue)->tail = prev; \
+ else \
+ next->link.prev = prev; \
+ if (prev == NULL) \
+ (queue)->head = next; \
+ else \
+ prev->link.next = next; \
+ } while (0)
+
+#define RemoveHead(queue, thread, link) \
+ do { \
+ OSThread* __next; \
+ (thread) = (queue)->head; \
+ __next = (thread)->link.next; \
+ if (__next == NULL) \
+ (queue)->tail = NULL; \
+ else \
+ __next->link.prev = NULL; \
+ (queue)->head = __next; \
+ } while (0)
+
+static inline void OSInitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; }
+
+static inline void OSSetCurrentThread(OSThread* thread) {
+ SwitchThreadCallback(__OSCurrentThread, thread);
+ __OSCurrentThread = thread;
+}
+
+void __OSThreadInit() {
+ OSThread* thread = &DefaultThread;
+ int prio;
+
+ thread->state = OS_THREAD_STATE_RUNNING;
+ thread->attr = OS_THREAD_ATTR_DETACH;
+ thread->priority = thread->base = 16;
+ thread->suspend = 0;
+ thread->val = (void*)-1;
+ thread->mutex = NULL;
+ OSInitThreadQueue(&thread->queueJoin);
+ OSInitMutexQueue(&thread->queueMutex);
+
+ __OSFPUContext = &thread->context;
+
+ OSClearContext(&thread->context);
+ OSSetCurrentContext(&thread->context);
+ thread->stackBase = (void*)_stack_addr;
+ thread->stackEnd = (void*)_stack_end;
+ *(thread->stackEnd) = OS_THREAD_STACK_MAGIC;
+
+ OSSetCurrentThread(thread);
+ OSClearStack(0);
+
+ RunQueueBits = 0;
+ RunQueueHint = FALSE;
+ for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) {
+ OSInitThreadQueue(&RunQueue[prio]);
+ }
+
+ OSInitThreadQueue(&__OSActiveThreadQueue);
+ AddTail(&__OSActiveThreadQueue, thread, linkActive);
+ OSClearContext(&IdleContext);
+ Reschedule = 0;
+}
+
+void OSInitThreadQueue(OSThreadQueue* queue) { queue->head = queue->tail = NULL; }
+
+OSThread* OSGetCurrentThread() { return __OSCurrentThread; }
+
+#ifdef FULL_FRANK
+/* Code matches, stack epilogue bug*/
+s32 OSDisableScheduler() {
+ BOOL enabled;
+ s32 count;
+
+ enabled = OSDisableInterrupts();
+ count = Reschedule++;
+ OSRestoreInterrupts(enabled);
+ return count;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm s32 OSDisableScheduler() {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x10(r1)
+ stw r31, 0xc(r1)
+ bl OSDisableInterrupts
+ lwz r4, Reschedule
+ addi r0, r4, 1
+ stw r0, Reschedule
+ mr r31, r4
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x14(r1)
+ lwz r31, 0xc(r1)
+ addi r1, r1, 0x10
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+#ifdef FULL_FRANK
+/* Code matches, stack epilogue bug*/
+s32 OSEnableScheduler() {
+ BOOL enabled;
+ s32 count;
+
+ enabled = OSDisableInterrupts();
+ count = Reschedule--;
+ OSRestoreInterrupts(enabled);
+ return count;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level
+#pragma optimizewithasm off
+asm s32 OSEnableScheduler() {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x10(r1)
+ stw r31, 0xc(r1)
+ bl OSDisableInterrupts
+ lwz r4, Reschedule
+ subi r0, r4, 1
+ stw r0, Reschedule
+ mr r31, r4
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x14(r1)
+ lwz r31, 0xc(r1)
+ addi r1, r1, 0x10
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
+
+static void SetRun(OSThread* thread) {
+ thread->queue = &RunQueue[thread->priority];
+ AddTail(thread->queue, thread, link);
+ RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority);
+ RunQueueHint = TRUE;
+}
+#pragma dont_inline on
+static void UnsetRun(OSThread* thread) {
+ OSThreadQueue* queue;
+ queue = thread->queue;
+ RemoveItem(queue, thread, link);
+ if (queue->head == 0)
+ RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority));
+ thread->queue = NULL;
+}
+#pragma dont_inline reset
+
+OSPriority __OSGetEffectivePriority(OSThread* thread) {
+ OSPriority priority;
+ OSMutex* mutex;
+ OSThread* blocked;
+
+ priority = thread->base;
+ for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) {
+ blocked = mutex->queue.head;
+ if (blocked && blocked->priority < priority) {
+ priority = blocked->priority;
+ }
+ }
+ return priority;
+}
+
+static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) {
+ switch (thread->state) {
+ case OS_THREAD_STATE_READY:
+ UnsetRun(thread);
+ thread->priority = priority;
+ SetRun(thread);
+ break;
+ case OS_THREAD_STATE_WAITING:
+ RemoveItem(thread->queue, thread, link);
+ thread->priority = priority;
+ AddPrio(thread->queue, thread, link);
+ if (thread->mutex) {
+ return thread->mutex->thread;
+ }
+ break;
+ case OS_THREAD_STATE_RUNNING:
+ RunQueueHint = TRUE;
+ thread->priority = priority;
+ break;
+ }
+ return NULL;
+}
+
+static void UpdatePriority(OSThread* thread) {
+ OSPriority priority;
+
+ do {
+ if (0 < thread->suspend) {
+ break;
+ }
+ priority = __OSGetEffectivePriority(thread);
+ if (thread->priority == priority) {
+ break;
+ }
+ thread = SetEffectivePriority(thread, priority);
+ } while (thread);
+}
+
+static void __OSSwitchThread(OSThread* nextThread) {
+ OSSetCurrentThread(nextThread);
+ OSSetCurrentContext(&nextThread->context);
+ OSLoadContext(&nextThread->context);
+}
+
+static OSThread* SelectThread(BOOL yield) {
+ OSContext* currentContext;
+ OSThread* currentThread;
+ OSThread* nextThread;
+ OSPriority priority;
+ OSThreadQueue* queue;
+
+ if (0 < Reschedule) {
+ return 0;
+ }
+
+ currentContext = OSGetCurrentContext();
+ currentThread = OSGetCurrentThread();
+ if (currentContext != &currentThread->context) {
+ return 0;
+ }
+
+ if (currentThread) {
+ if (currentThread->state == OS_THREAD_STATE_RUNNING) {
+ if (!yield) {
+ priority = __cntlzw(RunQueueBits);
+ if (currentThread->priority <= priority) {
+ return 0;
+ }
+ }
+ currentThread->state = OS_THREAD_STATE_READY;
+ SetRun(currentThread);
+ }
+
+ if (!(currentThread->context.state & OS_CONTEXT_STATE_EXC) &&
+ OSSaveContext(&currentThread->context)) {
+ return 0;
+ }
+ }
+
+ OSSetCurrentThread(NULL);
+ if (RunQueueBits == 0) {
+ OSSetCurrentContext(&IdleContext);
+ do {
+ OSEnableInterrupts();
+ while (RunQueueBits == 0)
+ ;
+ OSDisableInterrupts();
+ } while (RunQueueBits == 0);
+
+ OSClearContext(&IdleContext);
+ }
+
+ RunQueueHint = FALSE;
+
+ priority = __cntlzw(RunQueueBits);
+ queue = &RunQueue[priority];
+ RemoveHead(queue, nextThread, link);
+ if (queue->head == 0) {
+ RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority));
+ }
+ nextThread->queue = NULL;
+ nextThread->state = OS_THREAD_STATE_RUNNING;
+ __OSSwitchThread(nextThread);
+ return nextThread;
+}
+
+void __OSReschedule() {
+ if (!RunQueueHint) {
+ return;
+ }
+
+ SelectThread(FALSE);
+}
+
+void OSYieldThread(void) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ SelectThread(TRUE);
+ OSRestoreInterrupts(enabled);
+}
+
+void OSCancelThread(OSThread* thread) {
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+
+ switch (thread->state) {
+ case OS_THREAD_STATE_READY:
+ if (!(0 < thread->suspend)) {
+ UnsetRun(thread);
+ }
+ break;
+ case OS_THREAD_STATE_RUNNING:
+ RunQueueHint = TRUE;
+ break;
+ case OS_THREAD_STATE_WAITING:
+ RemoveItem(thread->queue, thread, link);
+ thread->queue = NULL;
+ if (!(0 < thread->suspend) && thread->mutex) {
+ UpdatePriority(thread->mutex->thread);
+ }
+ break;
+ default:
+ OSRestoreInterrupts(enabled);
+ return;
+ }
+
+ OSClearContext(&thread->context);
+ if (thread->attr & OS_THREAD_ATTR_DETACH) {
+ RemoveItem(&__OSActiveThreadQueue, thread, linkActive);
+ thread->state = 0;
+ } else {
+ thread->state = OS_THREAD_STATE_MORIBUND;
+ }
+
+ __OSUnlockAllMutex(thread);
+
+ OSWakeupThread(&thread->queueJoin);
+
+ __OSReschedule();
+ OSRestoreInterrupts(enabled);
+
+ return;
+}
+
+#ifdef FULL_FRANK
+/* Code matches, stack epilogue bug*/
+s32 OSResumeThread(OSThread* thread) {
+ BOOL enabled;
+ s32 suspendCount;
+
+ enabled = OSDisableInterrupts();
+ suspendCount = thread->suspend--;
+ if (thread->suspend < 0) {
+ thread->suspend = 0;
+ } else if (thread->suspend == 0) {
+ switch (thread->state) {
+ case OS_THREAD_STATE_READY:
+ thread->priority = __OSGetEffectivePriority(thread);
+ SetRun(thread);
+ break;
+ case OS_THREAD_STATE_WAITING:
+ RemoveItem(thread->queue, thread, link);
+ thread->priority = __OSGetEffectivePriority(thread);
+ AddPrio(thread->queue, thread, link);
+ if (thread->mutex) {
+ UpdatePriority(thread->mutex->thread);
+ }
+ break;
+ }
+ __OSReschedule();
+ }
+ OSRestoreInterrupts(enabled);
+ return suspendCount;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm s32 OSResumeThread(OSThread* thread) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x28(r1)
+ stw r31, 0x24(r1)
+ stw r30, 0x20(r1)
+ stw r29, 0x1c(r1)
+ mr r29, r3
+ bl OSDisableInterrupts
+ lwz r4, 0x2cc(r29)
+ addi r31, r3, 0
+ addi r0, r4, -1
+ stw r0, 0x2cc(r29)
+ mr r30, r4
+ lwz r0, 0x2cc(r29)
+ cmpwi r0, 0
+ bge lbl_80384D60
+ li r0, 0
+ stw r0, 0x2cc(r29)
+ b lbl_80384F74
+lbl_80384D60:
+ bne lbl_80384F74
+ lhz r0, 0x2c8(r29)
+ cmpwi r0, 4
+ beq lbl_80384E24
+ bge lbl_80384F60
+ cmpwi r0, 1
+ beq lbl_80384D80
+ b lbl_80384F60
+lbl_80384D80:
+ lwz r0, 0x2d4(r29)
+ lwz r3, 0x2f4(r29)
+ b lbl_80384DAC
+lbl_80384D8C:
+ lwz r4, 0(r3)
+ cmplwi r4, 0
+ beq lbl_80384DA8
+ lwz r4, 0x2d0(r4)
+ cmpw r4, r0
+ bge lbl_80384DA8
+ mr r0, r4
+lbl_80384DA8:
+ lwz r3, 0x10(r3)
+lbl_80384DAC:
+ cmplwi r3, 0
+ bne lbl_80384D8C
+ stw r0, 0x2d0(r29)
+ lis r3, RunQueue@ha
+ addi r0, r3, RunQueue@l
+ lwz r3, 0x2d0(r29)
+ slwi r3, r3, 3
+ add r0, r0, r3
+ stw r0, 0x2dc(r29)
+ lwz r4, 0x2dc(r29)
+ lwz r3, 4(r4)
+ cmplwi r3, 0
+ bne lbl_80384DE8
+ stw r29, 0(r4)
+ b lbl_80384DEC
+lbl_80384DE8:
+ stw r29, 0x2e0(r3)
+lbl_80384DEC:
+ stw r3, 0x2e4(r29)
+ li r0, 0
+ li r3, 1
+ stw r0, 0x2e0(r29)
+ lwz r4, 0x2dc(r29)
+ stw r29, 4(r4)
+ lwz r0, 0x2d0(r29)
+ lwz r4, RunQueueBits
+ subfic r0, r0, 0x1f
+ slw r0, r3, r0
+ or r0, r4, r0
+ stw r0, RunQueueBits
+ stw r3, RunQueueHint
+ b lbl_80384F60
+lbl_80384E24:
+ lwz r4, 0x2e0(r29)
+ lwz r5, 0x2e4(r29)
+ cmplwi r4, 0
+ bne lbl_80384E40
+ lwz r3, 0x2dc(r29)
+ stw r5, 4(r3)
+ b lbl_80384E44
+lbl_80384E40:
+ stw r5, 0x2e4(r4)
+lbl_80384E44:
+ cmplwi r5, 0
+ bne lbl_80384E58
+ lwz r3, 0x2dc(r29)
+ stw r4, 0(r3)
+ b lbl_80384E5C
+lbl_80384E58:
+ stw r4, 0x2e0(r5)
+lbl_80384E5C:
+ lwz r0, 0x2d4(r29)
+ lwz r3, 0x2f4(r29)
+ b lbl_80384E88
+lbl_80384E68:
+ lwz r4, 0(r3)
+ cmplwi r4, 0
+ beq lbl_80384E84
+ lwz r4, 0x2d0(r4)
+ cmpw r4, r0
+ bge lbl_80384E84
+ mr r0, r4
+lbl_80384E84:
+ lwz r3, 0x10(r3)
+lbl_80384E88:
+ cmplwi r3, 0
+ bne lbl_80384E68
+ stw r0, 0x2d0(r29)
+ lwz r4, 0x2dc(r29)
+ lwz r5, 0(r4)
+ b lbl_80384EA4
+lbl_80384EA0:
+ lwz r5, 0x2e0(r5)
+lbl_80384EA4:
+ cmplwi r5, 0
+ beq lbl_80384EBC
+ lwz r3, 0x2d0(r5)
+ lwz r0, 0x2d0(r29)
+ cmpw r3, r0
+ ble lbl_80384EA0
+lbl_80384EBC:
+ cmplwi r5, 0
+ bne lbl_80384EF4
+ lwz r3, 4(r4)
+ cmplwi r3, 0
+ bne lbl_80384ED8
+ stw r29, 0(r4)
+ b lbl_80384EDC
+lbl_80384ED8:
+ stw r29, 0x2e0(r3)
+lbl_80384EDC:
+ stw r3, 0x2e4(r29)
+ li r0, 0
+ stw r0, 0x2e0(r29)
+ lwz r3, 0x2dc(r29)
+ stw r29, 4(r3)
+ b lbl_80384F1C
+lbl_80384EF4:
+ stw r5, 0x2e0(r29)
+ lwz r3, 0x2e4(r5)
+ stw r29, 0x2e4(r5)
+ cmplwi r3, 0
+ stw r3, 0x2e4(r29)
+ bne lbl_80384F18
+ lwz r3, 0x2dc(r29)
+ stw r29, 0(r3)
+ b lbl_80384F1C
+lbl_80384F18:
+ stw r29, 0x2e0(r3)
+lbl_80384F1C:
+ lwz r3, 0x2f0(r29)
+ cmplwi r3, 0
+ beq lbl_80384F60
+ lwz r29, 8(r3)
+lbl_80384F2C:
+ lwz r0, 0x2cc(r29)
+ cmpwi r0, 0
+ bgt lbl_80384F60
+ mr r3, r29
+ bl __OSGetEffectivePriority
+ lwz r0, 0x2d0(r29)
+ addi r4, r3, 0
+ cmpw r0, r4
+ beq lbl_80384F60
+ mr r3, r29
+ bl SetEffectivePriority
+ or. r29, r3, r3
+ bne lbl_80384F2C
+lbl_80384F60:
+ lwz r0, RunQueueHint
+ cmpwi r0, 0
+ beq lbl_80384F74
+ li r3, 0
+ bl SelectThread
+lbl_80384F74:
+ mr r3, r31
+ bl OSRestoreInterrupts
+ mr r3, r30
+ lwz r0, 0x2c(r1)
+ lwz r31, 0x24(r1)
+ lwz r30, 0x20(r1)
+ lwz r29, 0x1c(r1)
+ addi r1, r1, 0x28
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+
+#endif
+
+#ifdef FULL_FRANK
+/* Code matches, stack epilogue bug*/
+s32 OSSuspendThread(OSThread* thread) {
+ BOOL enabled;
+ s32 suspendCount;
+
+ enabled = OSDisableInterrupts();
+ suspendCount = thread->suspend++;
+ if (suspendCount == 0) {
+ switch (thread->state) {
+ case OS_THREAD_STATE_RUNNING:
+ RunQueueHint = TRUE;
+ thread->state = OS_THREAD_STATE_READY;
+ break;
+ case OS_THREAD_STATE_READY:
+ UnsetRun(thread);
+ break;
+ case OS_THREAD_STATE_WAITING:
+ RemoveItem(thread->queue, thread, link);
+ thread->priority = 32;
+ AddTail(thread->queue, thread, link);
+ if (thread->mutex) {
+ UpdatePriority(thread->mutex->thread);
+ }
+ break;
+ }
+
+ __OSReschedule();
+ }
+ OSRestoreInterrupts(enabled);
+ return suspendCount;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm s32 OSSuspendThread(OSThread* thread) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x20(r1)
+ stw r31, 0x1c(r1)
+ stw r30, 0x18(r1)
+ stw r29, 0x14(r1)
+ mr r29, r3
+ bl OSDisableInterrupts
+ lwz r4, 0x2cc(r29)
+ addi r31, r3, 0
+ addi r0, r4, 1
+ or. r30, r4, r4
+ stw r0, 0x2cc(r29)
+ bne lbl_803850E4
+ lhz r0, 0x2c8(r29)
+ cmpwi r0, 3
+ beq lbl_803850D0
+ bge lbl_80384FF4
+ cmpwi r0, 1
+ beq lbl_80385010
+ bge lbl_80385000
+ b lbl_803850D0
+lbl_80384FF4:
+ cmpwi r0, 5
+ bge lbl_803850D0
+ b lbl_8038501C
+lbl_80385000:
+ li r0, 1
+ stw r0, RunQueueHint
+ sth r0, 0x2c8(r29)
+ b lbl_803850D0
+lbl_80385010:
+ mr r3, r29
+ bl UnsetRun
+ b lbl_803850D0
+lbl_8038501C:
+ lwz r4, 0x2e0(r29)
+ lwz r5, 0x2e4(r29)
+ cmplwi r4, 0
+ bne lbl_80385038
+ lwz r3, 0x2dc(r29)
+ stw r5, 4(r3)
+ b lbl_8038503C
+lbl_80385038:
+ stw r5, 0x2e4(r4)
+lbl_8038503C:
+ cmplwi r5, 0
+ bne lbl_80385050
+ lwz r3, 0x2dc(r29)
+ stw r4, 0(r3)
+ b lbl_80385054
+lbl_80385050:
+ stw r4, 0x2e0(r5)
+lbl_80385054:
+ li r0, 0x20
+ stw r0, 0x2d0(r29)
+ lwz r4, 0x2dc(r29)
+ lwz r3, 4(r4)
+ cmplwi r3, 0
+ bne lbl_80385074
+ stw r29, 0(r4)
+ b lbl_80385078
+lbl_80385074:
+ stw r29, 0x2e0(r3)
+lbl_80385078:
+ stw r3, 0x2e4(r29)
+ li r0, 0
+ stw r0, 0x2e0(r29)
+ lwz r3, 0x2dc(r29)
+ stw r29, 4(r3)
+ lwz r3, 0x2f0(r29)
+ cmplwi r3, 0
+ beq lbl_803850D0
+ lwz r29, 8(r3)
+lbl_8038509C:
+ lwz r0, 0x2cc(r29)
+ cmpwi r0, 0
+ bgt lbl_803850D0
+ mr r3, r29
+ bl __OSGetEffectivePriority
+ lwz r0, 0x2d0(r29)
+ addi r4, r3, 0
+ cmpw r0, r4
+ beq lbl_803850D0
+ mr r3, r29
+ bl SetEffectivePriority
+ or. r29, r3, r3
+ bne lbl_8038509C
+lbl_803850D0:
+ lwz r0, RunQueueHint
+ cmpwi r0, 0
+ beq lbl_803850E4
+ li r3, 0
+ bl SelectThread
+lbl_803850E4:
+ mr r3, r31
+ bl OSRestoreInterrupts
+ mr r3, r30
+ lwz r0, 0x24(r1)
+ lwz r31, 0x1c(r1)
+ lwz r30, 0x18(r1)
+ lwz r29, 0x14(r1)
+ addi r1, r1, 0x20
+ mtlr r0
+ blr
+}
+#pragma pop
+/* clang-format on */
+#endif
+
+void OSSleepThread(OSThreadQueue* queue) {
+ BOOL enabled;
+ OSThread* currentThread;
+
+ enabled = OSDisableInterrupts();
+ currentThread = OSGetCurrentThread();
+
+ currentThread->state = OS_THREAD_STATE_WAITING;
+ currentThread->queue = queue;
+ AddPrio(queue, currentThread, link);
+ RunQueueHint = TRUE;
+ __OSReschedule();
+ OSRestoreInterrupts(enabled);
+}
+
+void OSWakeupThread(OSThreadQueue* queue) {
+ BOOL enabled;
+ OSThread* thread;
+
+ enabled = OSDisableInterrupts();
+ while (queue->head) {
+ RemoveHead(queue, thread, link);
+ thread->state = OS_THREAD_STATE_READY;
+ if (!(0 < thread->suspend)) {
+ SetRun(thread);
+ }
+ }
+ __OSReschedule();
+ OSRestoreInterrupts(enabled);
+}
+
+BOOL OSSetThreadPriority(OSThread* thread, s32 prio) {
+ BOOL enabled;
+
+ if (prio < OS_PRIORITY_MIN || prio > OS_PRIORITY_MAX) {
+ return FALSE;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ if (thread->base != prio) {
+ thread->base = prio;
+ UpdatePriority(thread);
+ __OSReschedule();
+ }
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+OSPriority OSGetThreadPriority(OSThread *thread) {
+ return thread->base;
+}
+
+void OSClearStack(u8 val) {
+ register u32 sp;
+ register u32* p;
+ register u32 pattern;
+
+ pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val;
+ sp = OSGetStackPointer();
+ for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) {
+ *p = pattern;
+ }
+}
diff --git a/src/Dolphin/os/OSTime.c b/src/Dolphin/os/OSTime.c
new file mode 100644
index 0000000..4250798
--- /dev/null
+++ b/src/Dolphin/os/OSTime.c
@@ -0,0 +1,137 @@
+#include <dolphin/os.h>
+
+#define OS_TIME_MONTH_MAX 12
+#define OS_TIME_WEEK_DAY_MAX 7
+#define OS_TIME_YEAR_DAY_MAX 365
+
+// End of each month in standard year
+static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+// End of each month in leap year
+static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152,
+ 182, 213, 244, 274, 305, 335};
+
+asm OSTime OSGetTime(void) {
+ // clang-format off
+ nofralloc
+
+ mftbu r3
+ mftb r4
+
+ // Check for possible carry from TBL to TBU
+ mftbu r5
+ cmpw r3, r5
+ bne OSGetTime
+
+ blr
+ // clang-format on
+}
+
+asm OSTick OSGetTick(void){
+ // clang-format off
+ nofralloc
+
+ mftb r3
+ blr
+ // clang-format on
+}
+
+#define OS_SYSTEMTIME_BASE 0x30D8
+
+OSTime __OSGetSystemTime(void) {
+ BOOL enabled;
+ OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE);
+ OSTime result;
+
+ enabled = OSDisableInterrupts();
+ result = *timeAdjustAddr + OSGetTime();
+ OSRestoreInterrupts(enabled);
+
+ return result;
+}
+
+OSTime __OSTimeToSystemTime(OSTime time) {
+ BOOL enabled;
+ OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE);
+ OSTime result;
+
+ enabled = OSDisableInterrupts();
+ result = *timeAdjustAddr + time;
+ OSRestoreInterrupts(enabled);
+
+ return result;
+}
+
+static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }
+
+static s32 GetYearDays(s32 year, s32 mon) {
+ return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon];
+}
+
+static s32 GetLeapDays(s32 year) {
+ if (year < 1) {
+ return 0;
+ }
+ return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400;
+}
+
+static void GetDates(s32 days, OSCalendarTime* cal) {
+ s32 year;
+ s32 totalDays;
+ s32* p_days;
+ s32 month;
+ cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX;
+
+ for (year = days / OS_TIME_YEAR_DAY_MAX;
+ days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) {
+ year--;
+ }
+
+ days -= totalDays;
+ cal->year = year;
+ cal->yday = days;
+
+ p_days = IsLeapYear(year) ? LeapYearDays : YearDays;
+ month = OS_TIME_MONTH_MAX;
+ while (days < p_days[--month]) {
+ ;
+ }
+ cal->mon = month;
+ cal->mday = days - p_days[month] + 1;
+}
+
+#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400)
+
+#pragma push
+#pragma dont_inline on
+void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) {
+ int days;
+ int secs;
+ OSTime d;
+
+ d = ticks % OSSecondsToTicks(1);
+ if (d < 0) {
+ d += OSSecondsToTicks(1);
+ }
+ td->usec = (int)(OSTicksToMicroseconds(d) % 1000);
+ td->msec = (int)(OSTicksToMilliseconds(d) % 1000);
+
+ ticks -= d;
+ days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS);
+ secs = (int)(OSTicksToSeconds(ticks) % 86400);
+ if (secs < 0) {
+ days -= 1;
+ secs += 24 * 60 * 60;
+ }
+
+ GetDates(days, td);
+
+ td->hour = secs / 60 / 60;
+ td->min = (secs / 60) % 60;
+ td->sec = secs % 60;
+}
+#pragma dont_inline reset
+
+OSTime OSCalendarTimeToTicks(OSCalendarTime* time) {
+ ;
+ ;
+}
diff --git a/src/Dolphin/os/__ppc_eabi_init.cpp b/src/Dolphin/os/__ppc_eabi_init.cpp
index a0e7574..67c85be 100644
--- a/src/Dolphin/os/__ppc_eabi_init.cpp
+++ b/src/Dolphin/os/__ppc_eabi_init.cpp
@@ -1,5 +1,3 @@
-// This file was taken from the Metroid Prime decompilation project.
-// https://github.com/PrimeDecomp/prime/blob/main/src/Dolphin/os/__ppc_eabi_init.cpp
#include "dolphin/__ppc_eabi_init.h"
#include "dolphin/PPCArch.h"
@@ -10,37 +8,39 @@ void __OSPSInit();
void __OSCacheInit();
asm void __init_hardware(void) {
- nofralloc
- mfmsr r0
- ori r0, r0, 0x2000
- mtmsr r0
+ // clang-format off
+ nofralloc
+ mfmsr r0
+ ori r0, r0, 0x2000
+ mtmsr r0
- mflr r31
- bl __OSPSInit
- bl __OSCacheInit
- mtlr r31
- blr
+ mflr r31
+ bl __OSPSInit
+ bl __OSCacheInit
+ mtlr r31
+ blr
+ // clang-format on
}
asm void __flush_cache(register void* address, register unsigned int size) {
- // clang-format off
- nofralloc
- lis r5, ~0
- ori r5, r5, ~14
- and r5, r5, r3
- subf r3, r5, r3
- add r4, r4, r3
+ // clang-format off
+ nofralloc
+ lis r5, ~0
+ ori r5, r5, ~14
+ and r5, r5, r3
+ subf r3, r5, r3
+ add r4, r4, r3
-loop:
- dcbst r0, r5
- sync
- icbi r0, r5
- addic r5, r5, 8
- subic. r4, r4, 8
- bge loop
- isync
- blr
- // clang-format on
+loop:
+ dcbst r0, r5
+ sync
+ icbi r0, r5
+ addic r5, r5, 8
+ subic. r4, r4, 8
+ bge loop
+ isync
+ blr
+ // clang-format on
}
void __init_user() { __init_cpp(); }
@@ -50,14 +50,14 @@ __declspec(section ".init") extern voidfunctionptr _ctors[];
__declspec(section ".init") extern voidfunctionptr _dtors[];
void __init_cpp(void) {
- voidfunctionptr* constructor;
+ voidfunctionptr* constructor;
- /*
- * call static initializers
- */
- for (constructor = _ctors; *constructor; constructor++) {
- (*constructor)();
- }
+ /*
+ * call static initializers
+ */
+ for (constructor = _ctors; *constructor; constructor++) {
+ (*constructor)();
+ }
}
void _ExitProcess(void) { PPCHalt(); }
diff --git a/src/Dolphin/os/__start.c b/src/Dolphin/os/__start.c
index 4cb44e2..f180de8 100644
--- a/src/Dolphin/os/__start.c
+++ b/src/Dolphin/os/__start.c
@@ -1,54 +1,47 @@
-// This file was taken from the Super Mario Sunshine decompilation project.
-// https://github.com/doldecomp/sms/blob/master/src/os/__start.c
#include "dolphin/__start.h"
+#include "__ppc_eabi_linker.h"
-#pragma section code_type ".init"
-
-void __check_pad3(void)
-{
- if ((Pad3Button & 0x0eef) == 0x0eef) {
- OSResetSystem(OS_RESET_RESTART, 0, FALSE);
- }
- return;
+void __check_pad3(void) {
+ if ((Pad3Button & 0x0eef) == 0x0eef) {
+ OSResetSystem(OS_RESET_RESTART, 0, FALSE);
+ }
+ return;
}
-#ifndef LD_TEST
-// clang-format off
-
-__declspec (weak) asm void __start(void)
-{
- nofralloc
+__declspec(weak) asm void __start(void) {
+ // clang-format off
+ nofralloc
bl __init_registers
- bl __init_hardware
- li r0, -1
- stwu r1, -8(r1)
- stw r0, 4(r1)
- stw r0, 0(r1)
- bl __init_data
- li r0, 0
- lis r6, EXCEPTIONMASK_ADDR@ha
- addi r6, r6, EXCEPTIONMASK_ADDR@l
- stw r0, 0(r6)
- lis r6, BOOTINFO2_ADDR@ha
- addi r6, r6, BOOTINFO2_ADDR@l
- lwz r6, 0(r6)
+ bl __init_hardware
+ li r0, -1
+ stwu r1, -8(r1)
+ stw r0, 4(r1)
+ stw r0, 0(r1)
+ bl __init_data
+ li r0, 0
+ lis r6, EXCEPTIONMASK_ADDR@ha
+ addi r6, r6, EXCEPTIONMASK_ADDR@l
+ stw r0, 0(r6)
+ lis r6, BOOTINFO2_ADDR@ha
+ addi r6, r6, BOOTINFO2_ADDR@l
+ lwz r6, 0(r6)
_check_TRK:
- cmplwi r6, 0
- beq _load_lomem_debug_flag
- lwz r7, OS_BI2_DEBUGFLAG_OFFSET(r6)
- b _check_debug_flag
-
+ cmplwi r6, 0
+ beq _load_lomem_debug_flag
+ lwz r7, OS_BI2_DEBUGFLAG_OFFSET(r6)
+ b _check_debug_flag
+
_load_lomem_debug_flag:
lis r5, ARENAHI_ADDR@ha
addi r5, r5, ARENAHI_ADDR@l
- lwz r5, 0(r5)
- cmplwi r5, 0
- beq _goto_main
- lis r7, DEBUGFLAG_ADDR@ha
- addi r7, r7, DEBUGFLAG_ADDR@l
- lwz r7, 0(r7)
-
+ lwz r5, 0(r5)
+ cmplwi r5, 0
+ beq _goto_main
+ lis r7, DEBUGFLAG_ADDR@ha
+ addi r7, r7, DEBUGFLAG_ADDR@l
+ lwz r7, 0(r7)
+
_check_debug_flag:
li r5, 0
cmplwi r7, 2
@@ -62,7 +55,7 @@ _goto_inittrk:
addi r6, r6, InitMetroTRK@l
mtlr r6
blrl
-
+
_goto_main:
lis r6, BOOTINFO2_ADDR@ha
addi r6, r6, BOOTINFO2_ADDR@l
@@ -105,31 +98,22 @@ _end_of_parseargs:
beq _check_pad3
andi. r3, r3, 0x7fff
cmplwi r3, 1
- bne _skip_crc
+ bne _goto_skip_init_bba
_check_pad3:
bl __check_pad3
-_skip_crc:
+_goto_skip_init_bba:
bl __init_user
mr r3, r14
mr r4, r15
bl main
b exit
+ // clang-format on
}
-#else
-__declspec(weak) void __start() {
- int ret;
- int argc = 0;
- char **argv = NULL;
- __init_user();
- ret = main(argc, argv);
- exit(ret);
-}
-#endif
-asm static void __init_registers(void)
-{
+asm static void __init_registers(void) {
+ // clang-format off
nofralloc
lis r1, _stack_addr@h
ori r1, r1, _stack_addr@l
@@ -138,51 +122,40 @@ asm static void __init_registers(void)
lis r13, _SDA_BASE_@h
ori r13, r13, _SDA_BASE_@l
blr
+ // clang-format on
}
-__declspec(section ".init") extern __rom_copy_info _rom_copy_info[];
-__declspec(section ".init") extern __bss_init_info _bss_init_info[];
-
-// clang-format on
-
-inline static void __copy_rom_section(void* dst, const void* src,
- unsigned long size)
-{
- if (size && (dst != src)) {
- memcpy(dst, src, size);
- __flush_cache(dst, size);
- }
+inline static void __copy_rom_section(void* dst, const void* src, unsigned long size) {
+ if (size && (dst != src)) {
+ memcpy(dst, src, size);
+ __flush_cache(dst, size);
+ }
}
-inline static void __init_bss_section(void* dst, unsigned long size)
-{
- if (size) {
- memset(dst, 0, size);
- }
+inline static void __init_bss_section(void* dst, unsigned long size) {
+ if (size) {
+ memset(dst, 0, size);
+ }
}
#pragma scheduling off
-#pragma peephole off
-// peephole might have been turned off due to the inline asm peephole bug
-// which turns off peephole optimizations after an inline-asm function
-void __init_data(void)
-{
- __rom_copy_info* dci;
- __bss_init_info* bii;
-
- dci = _rom_copy_info;
- while (TRUE) {
- if (dci->size == 0)
- break;
- __copy_rom_section(dci->addr, dci->rom, dci->size);
- dci++;
- }
-
- bii = _bss_init_info;
- while (TRUE) {
- if (bii->size == 0)
- break;
- __init_bss_section(bii->addr, bii->size);
- bii++;
- }
+void __init_data(void) {
+ __rom_copy_info* dci;
+ __bss_init_info* bii;
+
+ dci = _rom_copy_info;
+ while (TRUE) {
+ if (dci->size == 0)
+ break;
+ __copy_rom_section(dci->addr, dci->rom, dci->size);
+ dci++;
+ }
+
+ bii = _bss_init_info;
+ while (TRUE) {
+ if (bii->size == 0)
+ break;
+ __init_bss_section(bii->addr, bii->size);
+ bii++;
+ }
}
diff --git a/src/Dolphin/pad/PadClamp.c b/src/Dolphin/pad/PadClamp.c
new file mode 100644
index 0000000..6b992ec
--- /dev/null
+++ b/src/Dolphin/pad/PadClamp.c
@@ -0,0 +1,166 @@
+#include <dolphin/pad.h>
+
+#include <math.h>
+
+typedef struct PADClampRegion {
+ u8 minTrigger;
+ u8 maxTrigger;
+ s8 minStick;
+ s8 maxStick;
+ s8 xyStick;
+ s8 minSubstick;
+ s8 maxSubstick;
+ s8 xySubstick;
+ s8 radStick;
+ s8 radSubstick;
+} PADClampRegion;
+
+static const PADClampRegion ClampRegion = {
+ // Triggers
+ 30,
+ 180,
+
+ // Left stick
+ 15,
+ 72,
+ 40,
+
+ // Right stick
+ 15,
+ 59,
+ 31,
+
+ // Stick radii
+ 56,
+ 44,
+};
+
+static void ClampCircle(s8* px, s8* py, s8 radius, s8 min) {
+ s32 x = *px;
+ s32 y = *py;
+ s32 squared;
+ s32 length;
+
+ if (-min < x && x < min) {
+ x = 0;
+ } else if (0 < x) {
+ x -= min;
+ } else {
+ x += min;
+ }
+
+ if (-min < y && y < min) {
+ y = 0;
+ } else if (0 < y) {
+ y -= min;
+ } else {
+ y += min;
+ }
+
+ squared = x * x + y * y;
+ if (radius * radius < squared) {
+ length = sqrt(squared);
+ x = (x * radius) / length;
+ y = (y * radius) / length;
+ }
+
+ *px = x;
+ *py = y;
+}
+
+static void ClampStick(s8* px, s8* py, s8 max, s8 xy, s8 min) {
+ int x = *px;
+ int y = *py;
+ int signX;
+ int signY;
+ int d;
+
+ if (0 <= x) {
+ signX = 1;
+ } else {
+ signX = -1;
+ x = -x;
+ }
+
+ if (0 <= y) {
+ signY = 1;
+ } else {
+ signY = -1;
+ y = -y;
+ }
+
+ if (x <= min) {
+ x = 0;
+ } else {
+ x -= min;
+ }
+ if (y <= min) {
+ y = 0;
+ } else {
+ y -= min;
+ }
+
+ if (x == 0 && y == 0) {
+ *px = *py = 0;
+ return;
+ }
+
+ if (xy * y <= xy * x) {
+ d = xy * x + (max - xy) * y;
+ if (xy * max < d) {
+ x = (s8)(xy * max * x / d);
+ y = (s8)(xy * max * y / d);
+ }
+ } else {
+ d = xy * y + (max - xy) * x;
+ if (xy * max < d) {
+ x = (s8)(xy * max * x / d);
+ y = (s8)(xy * max * y / d);
+ }
+ }
+
+ *px = (s8)(signX * x);
+ *py = (s8)(signY * y);
+}
+
+static void ClampTrigger(u8* trigger, u8 min, u8 max) {
+ if (*trigger <= min) {
+ *trigger = 0;
+ } else {
+ if (max < *trigger) {
+ *trigger = max;
+ }
+ *trigger -= min;
+ }
+}
+
+void PADClamp(PADStatus* status) {
+ int i;
+ for (i = 0; i < PAD_CHANMAX; i++, status++) {
+ if (status->err != PAD_ERR_NONE) {
+ continue;
+ }
+
+ ClampStick(&status->stickX, &status->stickY, ClampRegion.maxStick, ClampRegion.xyStick,
+ ClampRegion.minStick);
+ ClampStick(&status->substickX, &status->substickY, ClampRegion.maxSubstick,
+ ClampRegion.xySubstick, ClampRegion.minSubstick);
+ ClampTrigger(&status->triggerL, ClampRegion.minTrigger, ClampRegion.maxTrigger);
+ ClampTrigger(&status->triggerR, ClampRegion.minTrigger, ClampRegion.maxTrigger);
+ }
+}
+
+void PADClampCircle(PADStatus* status) {
+ u32 i;
+ for (i = 0; i < 4; ++i, status++) {
+ if (status->err != PAD_ERR_NONE) {
+ continue;
+ }
+
+ ClampCircle(&status->stickX, &status->stickY, ClampRegion.radStick, ClampRegion.minStick);
+ ClampCircle(&status->substickX, &status->substickY, ClampRegion.radSubstick,
+ ClampRegion.minSubstick);
+ ClampTrigger(&status->triggerL, ClampRegion.minTrigger, ClampRegion.maxTrigger);
+ ClampTrigger(&status->triggerR, ClampRegion.minTrigger, ClampRegion.maxTrigger);
+ }
+}
diff --git a/src/Dolphin/pad/pad.c b/src/Dolphin/pad/pad.c
new file mode 100644
index 0000000..3ccf7d1
--- /dev/null
+++ b/src/Dolphin/pad/pad.c
@@ -0,0 +1,838 @@
+#include <dolphin/pad.h>
+#include <dolphin/sipriv.h>
+
+const char* __PADVersion = "<< Dolphin SDK - PAD\trelease build: Sep 5 2002 05:34:02 (0x2301) >>";
+
+u8 UnkVal : (OS_BASE_CACHED | 0x30e3);
+u16 __OSWirelessPadFixMode : (OS_BASE_CACHED | 0x30E0);
+
+static void PADTypeAndStatusCallback(s32 chan, u32 type);
+static void PADOriginCallback(s32 chan, u32 error, OSContext* context);
+static void PADProbeCallback(s32 chan, u32 error, OSContext* context);
+static void SPEC0_MakeStatus(s32 chan, PADStatus* status, u32 data[2]);
+static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]);
+static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]);
+static void PADTypeAndStatusCallback(s32 chan, u32 type);
+
+static void PADOriginCallback(s32 chan, u32 error, OSContext* context);
+static void PADProbeCallback(s32 chan, u32 error, OSContext* context);
+
+static void SPEC0_MakeStatus(s32 chan, PADStatus* status, u32 data[2]);
+static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]);
+static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]);
+
+static BOOL Initialized;
+
+static u32 EnabledBits;
+static u32 ResettingBits;
+static s32 ResettingChan = 32;
+static u32 RecalibrateBits;
+static u32 WaitingBits;
+static u32 CheckingBits;
+static u32 PendingBits;
+
+static u32 XPatchBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT;
+
+static u32 AnalogMode = 0x00000300u;
+
+u32 __PADSpec;
+static u32 Spec = 5;
+static void (*MakeStatus)(s32, PADStatus*, u32[2]) = SPEC2_MakeStatus;
+
+static u32 Type[SI_MAX_CHAN];
+static PADStatus Origin[SI_MAX_CHAN];
+
+static u32 CmdReadOrigin = 0x41 << 24;
+static u32 CmdCalibrate = 0x42 << 24;
+static u32 CmdProbeDevice[SI_MAX_CHAN];
+
+static BOOL OnReset(BOOL final);
+
+static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 127};
+
+static void (*SamplingCallback)(void);
+
+static void PADEnable(s32 chan) {
+ u32 cmd;
+ u32 chanBit;
+ u32 data[2];
+
+ chanBit = PAD_CHAN0_BIT >> chan;
+ EnabledBits |= chanBit;
+ SIGetResponse(chan, data);
+ cmd = (0x40 << 16) | AnalogMode;
+ SISetCommand(chan, cmd);
+ SIEnablePolling(EnabledBits);
+}
+
+static void PADDisable(s32 chan) {
+ BOOL enabled;
+ u32 chanBit;
+
+ enabled = OSDisableInterrupts();
+
+ chanBit = PAD_CHAN0_BIT >> chan;
+ SIDisablePolling(chanBit);
+ EnabledBits &= ~chanBit;
+ WaitingBits &= ~chanBit;
+ CheckingBits &= ~chanBit;
+ PendingBits &= ~chanBit;
+ OSSetWirelessID(chan, 0);
+
+ OSRestoreInterrupts(enabled);
+}
+
+static void DoReset(void) {
+ u32 chanBit;
+
+ ResettingChan = __cntlzw(ResettingBits);
+ if (ResettingChan == 32) {
+ return;
+ }
+
+ chanBit = PAD_CHAN0_BIT >> ResettingChan;
+ ResettingBits &= ~chanBit;
+
+ memset(&Origin[ResettingChan], 0, sizeof(PADStatus));
+ SIGetTypeAsync(ResettingChan, PADTypeAndStatusCallback);
+}
+
+static void UpdateOrigin(s32 chan) {
+ PADStatus* origin;
+ u32 chanBit = PAD_CHAN0_BIT >> chan;
+
+ origin = &Origin[chan];
+ switch (AnalogMode & 0x00000700u) {
+ case 0x00000000u:
+ case 0x00000500u:
+ case 0x00000600u:
+ case 0x00000700u:
+ origin->triggerL &= ~15;
+ origin->triggerR &= ~15;
+ origin->analogA &= ~15;
+ origin->analogB &= ~15;
+ break;
+ case 0x00000100u:
+ origin->substickX &= ~15;
+ origin->substickY &= ~15;
+ origin->analogA &= ~15;
+ origin->analogB &= ~15;
+ break;
+ case 0x00000200u:
+ origin->substickX &= ~15;
+ origin->substickY &= ~15;
+ origin->triggerL &= ~15;
+ origin->triggerR &= ~15;
+ break;
+ case 0x00000300u:
+ break;
+ case 0x00000400u:
+ break;
+ }
+
+ origin->stickX -= 128;
+ origin->stickY -= 128;
+ origin->substickX -= 128;
+ origin->substickY -= 128;
+
+ if (XPatchBits & chanBit) {
+ if (64 < origin->stickX && (SIGetType(chan) & 0xffff0000) == SI_GC_CONTROLLER) {
+ origin->stickX = 0;
+ }
+ }
+}
+
+static void PADOriginCallback(s32 chan, u32 error, OSContext* context) {
+ if (!(error &
+ (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) {
+ UpdateOrigin(ResettingChan);
+ PADEnable(ResettingChan);
+ }
+ DoReset();
+}
+
+static void PADOriginUpdateCallback(s32 chan, u32 error, OSContext* context) {
+
+ if (!(EnabledBits & (PAD_CHAN0_BIT >> chan))) {
+ return;
+ }
+
+ if (!(error &
+ (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) {
+ UpdateOrigin(chan);
+ }
+
+ if (error & SI_ERROR_NO_RESPONSE) {
+ PADDisable(chan);
+ }
+}
+
+static void PADProbeCallback(s32 chan, u32 error, OSContext* context) {
+ if (!(error &
+ (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION))) {
+ PADEnable(ResettingChan);
+ WaitingBits |= PAD_CHAN0_BIT >> ResettingChan;
+ }
+ DoReset();
+}
+
+static void PADTypeAndStatusCallback(s32 chan, u32 type) {
+ u32 chanBit;
+ u32 recalibrate;
+ BOOL rc = TRUE;
+ u32 error;
+ chanBit = PAD_CHAN0_BIT >> ResettingChan;
+ error = type & 0xFF;
+ recalibrate = RecalibrateBits & chanBit;
+ RecalibrateBits &= ~chanBit;
+
+ if (error &
+ (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) {
+ DoReset();
+ return;
+ }
+
+ type &= ~0xFF;
+
+ Type[ResettingChan] = type;
+
+ if ((type & SI_TYPE_MASK) != SI_TYPE_GC || !(type & SI_GC_STANDARD)) {
+ DoReset();
+ return;
+ }
+
+ if (Spec < PAD_SPEC_2) {
+ PADEnable(ResettingChan);
+ DoReset();
+ return;
+ }
+
+ if (!(type & SI_GC_WIRELESS) || (type & SI_WIRELESS_IR)) {
+ if (recalibrate) {
+ rc = SITransfer(ResettingChan, &CmdCalibrate, 3, &Origin[ResettingChan], 10,
+ PADOriginCallback, 0);
+ } else {
+ rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10,
+ PADOriginCallback, 0);
+ }
+ } else if ((type & SI_WIRELESS_FIX_ID) && (type & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT &&
+ !(type & SI_WIRELESS_LITE)) {
+ if (type & SI_WIRELESS_RECEIVED) {
+ rc = SITransfer(ResettingChan, &CmdReadOrigin, 1, &Origin[ResettingChan], 10,
+ PADOriginCallback, 0);
+ } else {
+ rc = SITransfer(ResettingChan, &CmdProbeDevice[ResettingChan], 3, &Origin[ResettingChan], 8,
+ PADProbeCallback, 0);
+ }
+ }
+ if (!rc) {
+ PendingBits |= chanBit;
+ DoReset();
+ return;
+ }
+}
+
+static void PADReceiveCheckCallback(s32 chan, u32 type) {
+ u32 error;
+ u32 chanBit;
+
+ chanBit = PAD_CHAN0_BIT >> chan;
+ if (!(EnabledBits & chanBit)) {
+ return;
+ }
+
+ error = type & 0xFF;
+ type &= ~0xFF;
+
+ WaitingBits &= ~chanBit;
+ CheckingBits &= ~chanBit;
+
+ if (!(error &
+ (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) &&
+ (type & SI_GC_WIRELESS) && (type & SI_WIRELESS_FIX_ID) && (type & SI_WIRELESS_RECEIVED) &&
+ !(type & SI_WIRELESS_IR) && (type & SI_WIRELESS_CONT_MASK) == SI_WIRELESS_CONT &&
+ !(type & SI_WIRELESS_LITE)) {
+ SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0);
+ } else {
+ PADDisable(chan);
+ }
+}
+
+BOOL PADReset(u32 mask) {
+ BOOL enabled;
+ u32 diableBits;
+
+ enabled = OSDisableInterrupts();
+
+ mask |= PendingBits;
+ PendingBits = 0;
+ mask &= ~(WaitingBits | CheckingBits);
+ ResettingBits |= mask;
+ diableBits = ResettingBits & EnabledBits;
+ EnabledBits &= ~mask;
+
+ if (Spec == PAD_SPEC_4) {
+ RecalibrateBits |= mask;
+ }
+
+ SIDisablePolling(diableBits);
+
+ if (ResettingChan == 32) {
+ DoReset();
+ }
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL PADRecalibrate(u32 mask) {
+ BOOL enabled;
+ u32 disableBits;
+
+ enabled = OSDisableInterrupts();
+
+ mask |= PendingBits;
+ PendingBits = 0;
+ mask &= ~(WaitingBits | CheckingBits);
+ ResettingBits |= mask;
+ disableBits = ResettingBits & EnabledBits;
+ EnabledBits &= ~mask;
+
+ if (!(UnkVal & 0x40)) {
+ RecalibrateBits |= mask;
+ }
+
+ SIDisablePolling(disableBits);
+ if (ResettingChan == 32) {
+ DoReset();
+ }
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+BOOL PADInit() {
+ s32 chan;
+ if (Initialized) {
+ return TRUE;
+ }
+
+ OSRegisterVersion(__PADVersion);
+
+ if (__PADSpec) {
+ PADSetSpec(__PADSpec);
+ }
+
+ Initialized = TRUE;
+
+ if (__PADFixBits != 0) {
+ OSTime time = OSGetTime();
+ __OSWirelessPadFixMode = (u16)((((time)&0xffff) + ((time >> 16) & 0xffff) +
+ ((time >> 32) & 0xffff) + ((time >> 48) & 0xffff)) &
+ 0x3fffu);
+ RecalibrateBits = PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT;
+ }
+
+ for (chan = 0; chan < SI_MAX_CHAN; ++chan) {
+ CmdProbeDevice[chan] = (0x4D << 24) | (chan << 22) | ((__OSWirelessPadFixMode & 0x3fffu) << 8);
+ }
+
+ SIRefreshSamplingRate();
+ OSRegisterResetFunction(&ResetFunctionInfo);
+
+ return PADReset(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT);
+}
+
+#define offsetof(type, memb) ((u32) & ((type*)0)->memb)
+
+u32 PADRead(PADStatus* status) {
+ BOOL enabled;
+ s32 chan;
+ u32 data[2];
+ u32 chanBit;
+ u32 sr;
+ int chanShift;
+ u32 motor;
+
+ enabled = OSDisableInterrupts();
+
+ motor = 0;
+ for (chan = 0; chan < SI_MAX_CHAN; chan++, status++) {
+ chanBit = PAD_CHAN0_BIT >> chan;
+ chanShift = 8 * (SI_MAX_CHAN - 1 - chan);
+
+ if (PendingBits & chanBit) {
+ PADReset(0);
+ status->err = PAD_ERR_NOT_READY;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ if ((ResettingBits & chanBit) || ResettingChan == chan) {
+ status->err = PAD_ERR_NOT_READY;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ if (!(EnabledBits & chanBit)) {
+ status->err = (s8)PAD_ERR_NO_CONTROLLER;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ if (SIIsChanBusy(chan)) {
+ status->err = PAD_ERR_TRANSFER;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ sr = SIGetStatus(chan);
+ if (sr & SI_ERROR_NO_RESPONSE) {
+ SIGetResponse(chan, data);
+
+ if (WaitingBits & chanBit) {
+ status->err = (s8)PAD_ERR_NONE;
+ memset(status, 0, offsetof(PADStatus, err));
+
+ if (!(CheckingBits & chanBit)) {
+ CheckingBits |= chanBit;
+ SIGetTypeAsync(chan, PADReceiveCheckCallback);
+ }
+ continue;
+ }
+
+ PADDisable(chan);
+
+ status->err = (s8)PAD_ERR_NO_CONTROLLER;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ if (!(SIGetType(chan) & SI_GC_NOMOTOR)) {
+ motor |= chanBit;
+ }
+
+ if (!SIGetResponse(chan, data)) {
+ status->err = PAD_ERR_TRANSFER;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ if (data[0] & 0x80000000) {
+ status->err = PAD_ERR_TRANSFER;
+ memset(status, 0, offsetof(PADStatus, err));
+ continue;
+ }
+
+ MakeStatus(chan, status, data);
+
+ // Check and clear PAD_ORIGIN bit
+ if (status->button & 0x2000) {
+ status->err = PAD_ERR_TRANSFER;
+ memset(status, 0, offsetof(PADStatus, err));
+
+ // Get origin. It is okay if the following transfer fails
+ // since the PAD_ORIGIN bit remains until the read origin
+ // command complete.
+ SITransfer(chan, &CmdReadOrigin, 1, &Origin[chan], 10, PADOriginUpdateCallback, 0);
+ continue;
+ }
+
+ status->err = PAD_ERR_NONE;
+
+ // Clear PAD_INTERFERE bit
+ status->button &= ~0x0080;
+ }
+
+ OSRestoreInterrupts(enabled);
+ return motor;
+}
+
+void PADControlAllMotors(const u32* commandArray) {
+ BOOL enabled;
+ int chan;
+ u32 command;
+ BOOL commit;
+ u32 chanBit;
+
+ enabled = OSDisableInterrupts();
+ commit = FALSE;
+ for (chan = 0; chan < SI_MAX_CHAN; chan++, commandArray++) {
+ chanBit = PAD_CHAN0_BIT >> chan;
+ if ((EnabledBits & chanBit) && !(SIGetType(chan) & SI_GC_NOMOTOR)) {
+ command = *commandArray;
+ if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) {
+ command = PAD_MOTOR_STOP;
+ }
+
+ SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002)));
+ commit = TRUE;
+ }
+ }
+ if (commit) {
+ SITransferCommands();
+ }
+ OSRestoreInterrupts(enabled);
+}
+
+void PADControlMotor(s32 chan, u32 command) {
+ BOOL enabled;
+ u32 chanBit;
+
+ enabled = OSDisableInterrupts();
+ chanBit = PAD_CHAN0_BIT >> chan;
+ if ((EnabledBits & chanBit) && !(SIGetType(chan) & SI_GC_NOMOTOR)) {
+ if (Spec < PAD_SPEC_2 && command == PAD_MOTOR_STOP_HARD) {
+ command = PAD_MOTOR_STOP;
+ }
+
+ SISetCommand(chan, (0x40 << 16) | AnalogMode | (command & (0x00000001 | 0x00000002)));
+ SITransferCommands();
+ }
+ OSRestoreInterrupts(enabled);
+}
+
+void PADSetSpec(u32 spec) {
+ __PADSpec = 0;
+ switch (spec) {
+ case PAD_SPEC_0:
+ MakeStatus = SPEC0_MakeStatus;
+ break;
+ case PAD_SPEC_1:
+ MakeStatus = SPEC1_MakeStatus;
+ break;
+ case PAD_SPEC_2:
+ case PAD_SPEC_3:
+ case PAD_SPEC_4:
+ case PAD_SPEC_5:
+ MakeStatus = SPEC2_MakeStatus;
+ break;
+ }
+ Spec = spec;
+}
+
+u32 PADGetSpec(void) { return Spec; }
+
+static void SPEC0_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) {
+ status->button = 0;
+ status->button |= ((data[0] >> 16) & 0x0008) ? PAD_BUTTON_A : 0;
+ status->button |= ((data[0] >> 16) & 0x0020) ? PAD_BUTTON_B : 0;
+ status->button |= ((data[0] >> 16) & 0x0100) ? PAD_BUTTON_X : 0;
+ status->button |= ((data[0] >> 16) & 0x0001) ? PAD_BUTTON_Y : 0;
+ status->button |= ((data[0] >> 16) & 0x0010) ? PAD_BUTTON_START : 0;
+ status->stickX = (s8)(data[1] >> 16);
+ status->stickY = (s8)(data[1] >> 24);
+ status->substickX = (s8)(data[1]);
+ status->substickY = (s8)(data[1] >> 8);
+ status->triggerL = (u8)(data[0] >> 8);
+ status->triggerR = (u8)data[0];
+ status->analogA = 0;
+ status->analogB = 0;
+ if (170 <= status->triggerL) {
+ status->button |= PAD_TRIGGER_L;
+ }
+ if (170 <= status->triggerR) {
+ status->button |= PAD_TRIGGER_R;
+ }
+ status->stickX -= 128;
+ status->stickY -= 128;
+ status->substickX -= 128;
+ status->substickY -= 128;
+}
+
+static void SPEC1_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) {
+
+ status->button = 0;
+ status->button |= ((data[0] >> 16) & 0x0080) ? PAD_BUTTON_A : 0;
+ status->button |= ((data[0] >> 16) & 0x0100) ? PAD_BUTTON_B : 0;
+ status->button |= ((data[0] >> 16) & 0x0020) ? PAD_BUTTON_X : 0;
+ status->button |= ((data[0] >> 16) & 0x0010) ? PAD_BUTTON_Y : 0;
+ status->button |= ((data[0] >> 16) & 0x0200) ? PAD_BUTTON_START : 0;
+
+ status->stickX = (s8)(data[1] >> 16);
+ status->stickY = (s8)(data[1] >> 24);
+ status->substickX = (s8)(data[1]);
+ status->substickY = (s8)(data[1] >> 8);
+
+ status->triggerL = (u8)(data[0] >> 8);
+ status->triggerR = (u8)data[0];
+
+ status->analogA = 0;
+ status->analogB = 0;
+
+ if (170 <= status->triggerL) {
+ status->button |= PAD_TRIGGER_L;
+ }
+ if (170 <= status->triggerR) {
+ status->button |= PAD_TRIGGER_R;
+ }
+
+ status->stickX -= 128;
+ status->stickY -= 128;
+ status->substickX -= 128;
+ status->substickY -= 128;
+}
+
+static s8 ClampS8(s8 var, s8 org) {
+ if (0 < org) {
+ s8 min = (s8)(-128 + org);
+ if (var < min) {
+ var = min;
+ }
+ } else if (org < 0) {
+ s8 max = (s8)(127 + org);
+ if (max < var) {
+ var = max;
+ }
+ }
+ return var -= org;
+}
+
+static u8 ClampU8(u8 var, u8 org) {
+ if (var < org) {
+ var = org;
+ }
+ return var -= org;
+}
+
+#define PAD_ALL \
+ (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_DOWN | PAD_BUTTON_UP | PAD_TRIGGER_Z | \
+ PAD_TRIGGER_R | PAD_TRIGGER_L | PAD_BUTTON_A | PAD_BUTTON_B | PAD_BUTTON_X | PAD_BUTTON_Y | \
+ PAD_BUTTON_MENU | 0x2000 | 0x0080)
+
+static void SPEC2_MakeStatus(s32 chan, PADStatus* status, u32 data[2]) {
+ PADStatus* origin;
+
+ status->button = (u16)((data[0] >> 16) & PAD_ALL);
+ status->stickX = (s8)(data[0] >> 8);
+ status->stickY = (s8)(data[0]);
+
+ switch (AnalogMode & 0x00000700) {
+ case 0x00000000:
+ case 0x00000500:
+ case 0x00000600:
+ case 0x00000700:
+ status->substickX = (s8)(data[1] >> 24);
+ status->substickY = (s8)(data[1] >> 16);
+ status->triggerL = (u8)(((data[1] >> 12) & 0x0f) << 4);
+ status->triggerR = (u8)(((data[1] >> 8) & 0x0f) << 4);
+ status->analogA = (u8)(((data[1] >> 4) & 0x0f) << 4);
+ status->analogB = (u8)(((data[1] >> 0) & 0x0f) << 4);
+ break;
+ case 0x00000100:
+ status->substickX = (s8)(((data[1] >> 28) & 0x0f) << 4);
+ status->substickY = (s8)(((data[1] >> 24) & 0x0f) << 4);
+ status->triggerL = (u8)(data[1] >> 16);
+ status->triggerR = (u8)(data[1] >> 8);
+ status->analogA = (u8)(((data[1] >> 4) & 0x0f) << 4);
+ status->analogB = (u8)(((data[1] >> 0) & 0x0f) << 4);
+ break;
+ case 0x00000200:
+ status->substickX = (s8)(((data[1] >> 28) & 0x0f) << 4);
+ status->substickY = (s8)(((data[1] >> 24) & 0x0f) << 4);
+ status->triggerL = (u8)(((data[1] >> 20) & 0x0f) << 4);
+ status->triggerR = (u8)(((data[1] >> 16) & 0x0f) << 4);
+ status->analogA = (u8)(data[1] >> 8);
+ status->analogB = (u8)(data[1] >> 0);
+ break;
+ case 0x00000300:
+ status->substickX = (s8)(data[1] >> 24);
+ status->substickY = (s8)(data[1] >> 16);
+ status->triggerL = (u8)(data[1] >> 8);
+ status->triggerR = (u8)(data[1] >> 0);
+ status->analogA = 0;
+ status->analogB = 0;
+ break;
+ case 0x00000400:
+ status->substickX = (s8)(data[1] >> 24);
+ status->substickY = (s8)(data[1] >> 16);
+ status->triggerL = 0;
+ status->triggerR = 0;
+ status->analogA = (u8)(data[1] >> 8);
+ status->analogB = (u8)(data[1] >> 0);
+ break;
+ }
+
+ status->stickX -= 128;
+ status->stickY -= 128;
+ status->substickX -= 128;
+ status->substickY -= 128;
+
+ origin = &Origin[chan];
+ status->stickX = ClampS8(status->stickX, origin->stickX);
+ status->stickY = ClampS8(status->stickY, origin->stickY);
+ status->substickX = ClampS8(status->substickX, origin->substickX);
+ status->substickY = ClampS8(status->substickY, origin->substickY);
+ status->triggerL = ClampU8(status->triggerL, origin->triggerL);
+ status->triggerR = ClampU8(status->triggerR, origin->triggerR);
+}
+
+BOOL PADGetType(s32 chan, u32* type) {
+ u32 chanBit;
+
+ *type = SIGetType(chan);
+ chanBit = PAD_CHAN0_BIT >> chan;
+ if ((ResettingBits & chanBit) || ResettingChan == chan || !(EnabledBits & chanBit)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL PADSync(void) { return ResettingBits == 0 && ResettingChan == 32 && !SIBusy(); }
+
+void PADSetAnalogMode(u32 mode) {
+ BOOL enabled;
+ u32 mask;
+
+ enabled = OSDisableInterrupts();
+ AnalogMode = mode << 8;
+ mask = EnabledBits;
+
+ EnabledBits &= ~mask;
+ WaitingBits &= ~mask;
+ CheckingBits &= ~mask;
+
+ SIDisablePolling(mask);
+ OSRestoreInterrupts(enabled);
+}
+
+static BOOL OnReset(BOOL f) {
+ static BOOL recalibrated = FALSE;
+ BOOL sync;
+
+ if (SamplingCallback) {
+ PADSetSamplingCallback(NULL);
+ }
+
+ if (!f) {
+ sync = PADSync();
+ if (!recalibrated && sync) {
+ recalibrated = PADRecalibrate(PAD_CHAN0_BIT | PAD_CHAN1_BIT | PAD_CHAN2_BIT | PAD_CHAN3_BIT);
+ return FALSE;
+ }
+ return sync;
+ } else {
+ recalibrated = FALSE;
+ }
+
+ return TRUE;
+}
+
+void __PADDisableXPatch(void) { XPatchBits = 0; }
+
+static void SamplingHandler(__OSInterrupt interrupt, OSContext* context) {
+ OSContext exceptionContext;
+
+ if (SamplingCallback) {
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(&exceptionContext);
+ SamplingCallback();
+ OSClearContext(&exceptionContext);
+ OSSetCurrentContext(context);
+ }
+}
+
+#ifdef FULL_FRANK
+PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) {
+ PADSamplingCallback prev;
+
+ prev = SamplingCallback;
+ SamplingCallback = callback;
+ if (callback) {
+ SIRegisterPollingHandler(SamplingHandler);
+ } else {
+ SIUnregisterPollingHandler(SamplingHandler);
+ }
+ return prev;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm PADSamplingCallback PADSetSamplingCallback(PADSamplingCallback callback) {
+ nofralloc
+ mflr r0
+ cmplwi r3, 0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ lwz r31, SamplingCallback
+ stw r3, SamplingCallback
+ beq lbl_803875E4
+ lis r3, SamplingHandler@ha
+ addi r3, r3, SamplingHandler@l
+ bl SIRegisterPollingHandler
+ b lbl_803875F0
+lbl_803875E4:
+ lis r3, SamplingHandler@ha
+ addi r3, r3, SamplingHandler@l
+ bl SIUnregisterPollingHandler
+lbl_803875F0:
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+#endif
+
+#ifdef FULL_FRANK
+BOOL __PADDisableRecalibration(BOOL disable) {
+ BOOL enabled;
+ BOOL prev;
+
+ enabled = OSDisableInterrupts();
+ prev = (UnkVal & 0x40) ? TRUE : FALSE;
+ UnkVal &= (u8)~0x40;
+ if (disable) {
+ UnkVal |= 0x40;
+ }
+ OSRestoreInterrupts(enabled);
+ return prev;
+}
+#else
+/* clang-format off */
+#pragma push
+#pragma optimization_level 0
+#pragma optimizewithasm off
+asm BOOL __PADDisableRecalibration(BOOL disable) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ bl OSDisableInterrupts
+ lis r4, UnkVal@ha
+ lbz r0, UnkVal@l(r4)
+ rlwinm. r0, r0, 0, 0x19, 0x19
+ beq lbl_8038763C
+ li r31, 1
+ b lbl_80387640
+lbl_8038763C:
+ li r31, 0
+lbl_80387640:
+ lis r4, UnkVal@ha
+ lbz r0, UnkVal@l(r4)
+ andi. r0, r0, 0xbf
+ cmpwi r30, 0
+ stb r0, UnkVal@l(r4)
+ beq lbl_80387664
+ lbz r0, UnkVal@l(r4)
+ ori r0, r0, 0x40
+ stb r0, UnkVal@l(r4)
+lbl_80387664:
+ bl OSRestoreInterrupts
+ mr r3, r31
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+/* clang-format on */
+#pragma pop
+#endif
diff --git a/src/Dolphin/si/SIBios.c b/src/Dolphin/si/SIBios.c
new file mode 100644
index 0000000..00c6447
--- /dev/null
+++ b/src/Dolphin/si/SIBios.c
@@ -0,0 +1,772 @@
+#include <dolphin/OSRtcPriv.h>
+#include <dolphin/os.h>
+#include <dolphin/sipriv.h>
+
+vu32 __SIRegs[64] : 0xCC006400;
+
+extern OSTime __OSGetSystemTime();
+
+const char* __SIVersion = "<< Dolphin SDK - SI\trelease build: Sep 5 2002 05:33:08 (0x2301) >>";
+
+typedef struct SIControl {
+ s32 chan;
+ u32 poll;
+ u32 inputBytes;
+ void* input;
+ SICallback callback;
+} SIControl;
+
+static SIControl Si = {
+ -1, 0, 0, NULL, NULL,
+};
+
+typedef struct SIComm_s {
+ u32 tcint : 1;
+ u32 tcintmsk : 1;
+ u32 comerr : 1;
+ u32 rdstint : 1;
+ u32 rdstintmsk : 1;
+ u32 pad0 : 4;
+ u32 outlngth : 7;
+ u32 pad1 : 1;
+ u32 inlngth : 7;
+ u32 pad2 : 5;
+ u32 channel : 2;
+ u32 tstart : 1;
+} SIComm_s;
+
+typedef union SIComm_u {
+ u32 val;
+ SIComm_s f;
+} SIComm_u;
+
+static SIPacket Packet[SI_MAX_CHAN];
+static OSAlarm Alarm[SI_MAX_CHAN];
+static u32 Type[SI_MAX_CHAN] = {
+ SI_ERROR_NO_RESPONSE,
+ SI_ERROR_NO_RESPONSE,
+ SI_ERROR_NO_RESPONSE,
+ SI_ERROR_NO_RESPONSE,
+};
+
+static OSTime TypeTime[SI_MAX_CHAN];
+static OSTime XferTime[SI_MAX_CHAN];
+
+static SITypeAndStatusCallback TypeCallback[SI_MAX_CHAN][4];
+static __OSInterruptHandler RDSTHandler[4];
+
+u32 __PADFixBits;
+
+static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
+ SICallback callback);
+
+static BOOL InputBufferValid[SI_MAX_CHAN];
+static u32 InputBuffer[SI_MAX_CHAN][2];
+static vu32 InputBufferVcount[SI_MAX_CHAN];
+
+static BOOL SIGetResponseRaw(s32 chan);
+static void GetTypeCallback(s32 chan, u32 error, OSContext* context);
+
+BOOL SIBusy() { return Si.chan != -1 ? TRUE : FALSE; }
+
+BOOL SIIsChanBusy(s32 chan) { return (Packet[chan].chan != -1 || Si.chan == chan); }
+
+static void SIClearTCInterrupt() {
+ u32 reg;
+
+ reg = __SIRegs[13];
+ reg |= 0x80000000;
+ reg &= ~0x00000001;
+ __SIRegs[13] = reg;
+}
+
+static u32 CompleteTransfer() {
+ u32 sr;
+ u32 i;
+ u32 rLen;
+ u8* input;
+
+ sr = __SIRegs[14];
+
+ SIClearTCInterrupt();
+
+ if (Si.chan != -1) {
+ XferTime[Si.chan] = __OSGetSystemTime();
+
+ input = Si.input;
+
+ rLen = Si.inputBytes / 4;
+ for (i = 0; i < rLen; i++) {
+ *(u32*)input = __SIRegs[32 + i];
+ input += 4;
+ }
+
+ rLen = Si.inputBytes & 3;
+ if (rLen) {
+ u32 temp = __SIRegs[32 + i];
+ for (i = 0; i < rLen; i++) {
+ *input++ = (u8)((temp >> ((3 - i) * 8)) & 0xff);
+ }
+ }
+
+ if (__SIRegs[13] & 0x20000000) {
+ sr >>= 8 * (3 - Si.chan);
+ sr &= 0xf;
+
+ if ((sr & SI_ERROR_NO_RESPONSE) && !(Type[Si.chan] & SI_ERROR_BUSY)) {
+ Type[Si.chan] = SI_ERROR_NO_RESPONSE;
+ }
+ if (sr == 0) {
+ sr = SI_ERROR_COLLISION;
+ }
+ } else {
+ TypeTime[Si.chan] = __OSGetSystemTime();
+ sr = 0;
+ }
+
+ Si.chan = -1;
+ }
+ return sr;
+}
+
+static void SITransferNext(s32 chan) {
+ int i;
+ SIPacket* packet;
+
+ for (i = 0; i < SI_MAX_CHAN; ++i) {
+ ++chan;
+ chan %= SI_MAX_CHAN;
+ packet = &Packet[chan];
+ if (packet->chan != -1 && packet->fire <= __OSGetSystemTime()) {
+ if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input,
+ packet->inputBytes, packet->callback)) {
+ OSCancelAlarm(&Alarm[chan]);
+ packet->chan = -1;
+ }
+ break;
+ }
+ }
+}
+
+static void SIInterruptHandler(__OSInterrupt interrupt, OSContext* context) {
+ u32 reg;
+
+ reg = __SIRegs[13];
+
+ if ((reg & 0xc0000000) == 0xc0000000) {
+ s32 chan;
+ u32 sr;
+ SICallback callback;
+
+ chan = Si.chan;
+ sr = CompleteTransfer();
+ callback = Si.callback;
+ Si.callback = 0;
+
+ SITransferNext(chan);
+
+ if (callback) {
+ callback(chan, sr, context);
+ }
+
+ sr = __SIRegs[14];
+ sr &= 0xf000000 >> (8 * chan);
+ __SIRegs[14] = sr;
+
+ if (Type[chan] == SI_ERROR_BUSY && !SIIsChanBusy(chan)) {
+ static u32 cmdTypeAndStatus = 0 << 24;
+ SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback,
+ OSMicrosecondsToTicks(65));
+ }
+ }
+
+ if ((reg & 0x18000000) == 0x18000000) {
+
+ int i;
+ u32 vcount;
+ u32 x;
+
+ vcount = VIGetCurrentLine() + 1;
+ x = (Si.poll & 0x03ff0000) >> 16;
+
+ for (i = 0; i < SI_MAX_CHAN; ++i) {
+ if (SIGetResponseRaw(i)) {
+ InputBufferVcount[i] = vcount;
+ }
+ }
+
+ for (i = 0; i < SI_MAX_CHAN; ++i) {
+ if (!(Si.poll & (SI_CHAN0_BIT >> (31 - 7 + i)))) {
+ continue;
+ }
+ if (InputBufferVcount[i] == 0 || InputBufferVcount[i] + (x / 2) < vcount) {
+ return;
+ }
+ }
+
+ for (i = 0; i < SI_MAX_CHAN; ++i) {
+ InputBufferVcount[i] = 0;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ if (RDSTHandler[i]) {
+ RDSTHandler[i](interrupt, context);
+ }
+ }
+ }
+}
+
+static BOOL SIEnablePollingInterrupt(BOOL enable) {
+ BOOL enabled;
+ BOOL rc;
+ u32 reg;
+ int i;
+
+ enabled = OSDisableInterrupts();
+ reg = __SIRegs[13];
+ rc = (reg & 0x08000000) ? TRUE : FALSE;
+ if (enable) {
+ reg |= 0x08000000;
+ for (i = 0; i < SI_MAX_CHAN; ++i) {
+ InputBufferVcount[i] = 0;
+ }
+ } else {
+ reg &= ~0x08000000;
+ }
+ reg &= ~0x80000001;
+ __SIRegs[13] = reg;
+ OSRestoreInterrupts(enabled);
+ return rc;
+}
+
+BOOL SIRegisterPollingHandler(__OSInterruptHandler handler) {
+ BOOL enabled;
+ int i;
+
+ enabled = OSDisableInterrupts();
+ for (i = 0; i < 4; ++i) {
+ if (RDSTHandler[i] == handler) {
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+ }
+ }
+ for (i = 0; i < 4; ++i) {
+ if (RDSTHandler[i] == 0) {
+ RDSTHandler[i] = handler;
+ SIEnablePollingInterrupt(TRUE);
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+ }
+ }
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+}
+
+BOOL SIUnregisterPollingHandler(__OSInterruptHandler handler) {
+ BOOL enabled;
+ int i;
+
+ enabled = OSDisableInterrupts();
+ for (i = 0; i < 4; ++i) {
+ if (RDSTHandler[i] == handler) {
+ RDSTHandler[i] = 0;
+ for (i = 0; i < 4; ++i) {
+ if (RDSTHandler[i]) {
+ break;
+ }
+ }
+ if (i == 4) {
+ SIEnablePollingInterrupt(FALSE);
+ }
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+ break;
+ }
+ }
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+}
+
+void SIInit(void) {
+ OSRegisterVersion(__SIVersion);
+
+ Packet[0].chan = Packet[1].chan = Packet[2].chan = Packet[3].chan = -1;
+
+ Si.poll = 0;
+ SISetSamplingRate(0);
+
+ while (__SIRegs[13] & 1)
+ ;
+
+ __SIRegs[13] = 0x80000000;
+
+ __OSSetInterruptHandler(__OS_INTERRUPT_PI_SI, SIInterruptHandler);
+ __OSUnmaskInterrupts(OS_INTERRUPTMASK_PI_SI);
+
+ SIGetType(0);
+ SIGetType(1);
+ SIGetType(2);
+ SIGetType(3);
+}
+
+#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1))
+
+static BOOL __SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
+ SICallback callback) {
+ BOOL enabled;
+ u32 rLen;
+ u32 i;
+ u32 sr;
+ SIComm_u comcsr;
+
+ enabled = OSDisableInterrupts();
+ if (Si.chan != -1) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ sr = __SIRegs[14];
+ sr &= (0xf000000) >> (8 * chan);
+ __SIRegs[14] = sr;
+
+ Si.chan = chan;
+ Si.callback = callback;
+ Si.inputBytes = inputBytes;
+ Si.input = input;
+
+ rLen = ROUND(outputBytes, 4) / 4;
+ for (i = 0; i < rLen; i++) {
+ __SIRegs[32 + i] = ((u32*)output)[i];
+ }
+
+ comcsr.val = __SIRegs[13];
+ comcsr.f.tcint = 1;
+ comcsr.f.tcintmsk = callback ? 1 : 0;
+ comcsr.f.outlngth = (outputBytes == SI_MAX_COMCSR_OUTLNGTH) ? 0 : outputBytes;
+ comcsr.f.inlngth = (inputBytes == SI_MAX_COMCSR_INLNGTH) ? 0 : inputBytes;
+ comcsr.f.channel = chan;
+ comcsr.f.tstart = 1;
+ __SIRegs[13] = comcsr.val;
+
+ OSRestoreInterrupts(enabled);
+
+ return TRUE;
+}
+
+u32 SISync(void) {
+ BOOL enabled;
+ u32 sr;
+
+ while (__SIRegs[13] & 1)
+ ;
+
+ enabled = OSDisableInterrupts();
+ sr = CompleteTransfer();
+
+ SITransferNext(SI_MAX_CHAN);
+
+ OSRestoreInterrupts(enabled);
+
+ return sr;
+}
+
+u32 SIGetStatus(s32 chan) {
+ BOOL enabled;
+ u32 sr;
+ int chanShift;
+
+ enabled = OSDisableInterrupts();
+ sr = __SIRegs[14];
+ chanShift = 8 * (SI_MAX_CHAN - 1 - chan);
+ sr >>= chanShift;
+ if (sr & SI_ERROR_NO_RESPONSE) {
+ if (!(Type[chan] & SI_ERROR_BUSY)) {
+ Type[chan] = SI_ERROR_NO_RESPONSE;
+ }
+ }
+ OSRestoreInterrupts(enabled);
+ return sr;
+}
+
+void SISetCommand(s32 chan, u32 command) { __SIRegs[3 * chan] = command; }
+
+u32 SIGetCommand(s32 chan) { return __SIRegs[3 * chan]; }
+
+void SITransferCommands(void) { __SIRegs[14] = 0x80000000; }
+
+u32 SISetXY(u32 x, u32 y) {
+ u32 poll;
+ BOOL enabled;
+
+ poll = x << 16;
+ poll |= y << 8;
+
+ enabled = OSDisableInterrupts();
+ Si.poll &= ~(0x03ff0000 | 0x0000ff00);
+ Si.poll |= poll;
+ poll = Si.poll;
+ __SIRegs[12] = poll;
+ OSRestoreInterrupts(enabled);
+ return poll;
+}
+
+u32 SIEnablePolling(u32 poll) {
+ BOOL enabled;
+ u32 en;
+
+ if (poll == 0) {
+ return Si.poll;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ poll >>= (31 - 7);
+ en = poll & 0xf0;
+
+ poll &= (en >> 4) | 0x03fffff0;
+
+ poll &= ~0x03ffff00;
+
+ Si.poll &= ~(en >> 4);
+
+ Si.poll |= poll;
+
+ poll = Si.poll;
+
+ SITransferCommands();
+
+ __SIRegs[12] = poll;
+
+ OSRestoreInterrupts(enabled);
+
+ return poll;
+}
+
+u32 SIDisablePolling(u32 poll) {
+ BOOL enabled;
+
+ if (poll == 0) {
+ return Si.poll;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ poll >>= (31 - 7);
+ poll &= 0xf0;
+
+ poll = Si.poll & ~poll;
+
+ __SIRegs[12] = poll;
+ Si.poll = poll;
+
+ OSRestoreInterrupts(enabled);
+ return poll;
+}
+
+static BOOL SIGetResponseRaw(s32 chan) {
+ u32 sr;
+
+ sr = SIGetStatus(chan);
+ if (sr & SI_ERROR_RDST) {
+ InputBuffer[chan][0] = __SIRegs[3 * chan + 1];
+ InputBuffer[chan][1] = __SIRegs[3 * chan + 2];
+ InputBufferValid[chan] = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL SIGetResponse(s32 chan, void* data) {
+ BOOL rc;
+ BOOL enabled;
+
+ enabled = OSDisableInterrupts();
+ SIGetResponseRaw(chan);
+ rc = InputBufferValid[chan];
+ InputBufferValid[chan] = FALSE;
+ if (rc) {
+ ((u32*)data)[0] = InputBuffer[chan][0];
+ ((u32*)data)[1] = InputBuffer[chan][1];
+ }
+ OSRestoreInterrupts(enabled);
+ return rc;
+}
+
+static void AlarmHandler(OSAlarm* alarm, OSContext* context) {
+#pragma unused(context)
+ s32 chan;
+ SIPacket* packet;
+
+ chan = alarm - Alarm;
+ packet = &Packet[chan];
+ if (packet->chan != -1) {
+ if (__SITransfer(packet->chan, packet->output, packet->outputBytes, packet->input,
+ packet->inputBytes, packet->callback)) {
+ packet->chan = -1;
+ }
+ }
+}
+
+BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes,
+ SICallback callback, OSTime delay) {
+ BOOL enabled;
+ SIPacket* packet = &Packet[chan];
+ OSTime now;
+ OSTime fire;
+
+ enabled = OSDisableInterrupts();
+ if (packet->chan != -1 || Si.chan == chan) {
+ OSRestoreInterrupts(enabled);
+ return FALSE;
+ }
+
+ now = __OSGetSystemTime();
+ if (delay == 0) {
+ fire = now;
+ } else {
+ fire = XferTime[chan] + delay;
+ }
+ if (now < fire) {
+ delay = fire - now;
+ OSSetAlarm(&Alarm[chan], delay, AlarmHandler);
+ } else if (__SITransfer(chan, output, outputBytes, input, inputBytes, callback)) {
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+ }
+
+ packet->chan = chan;
+ packet->output = output;
+ packet->outputBytes = outputBytes;
+ packet->input = input;
+ packet->inputBytes = inputBytes;
+ packet->callback = callback;
+ packet->fire = fire;
+
+ OSRestoreInterrupts(enabled);
+ return TRUE;
+}
+
+static void CallTypeAndStatusCallback(s32 chan, u32 type) {
+ SITypeAndStatusCallback callback;
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ callback = TypeCallback[chan][i];
+ if (callback) {
+ TypeCallback[chan][i] = 0;
+ callback(chan, type);
+ }
+ }
+}
+
+static void GetTypeCallback(s32 chan, u32 error, OSContext* context) {
+ static u32 cmdFixDevice[SI_MAX_CHAN];
+ u32 type;
+ u32 chanBit;
+ BOOL fix;
+ u32 id;
+
+ Type[chan] &= ~SI_ERROR_BUSY;
+ Type[chan] |= error;
+ TypeTime[chan] = __OSGetSystemTime();
+
+ type = Type[chan];
+
+ chanBit = SI_CHAN0_BIT >> chan;
+ fix = (BOOL)(__PADFixBits & chanBit);
+ __PADFixBits &= ~chanBit;
+
+ if ((error &
+ (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_NO_RESPONSE | SI_ERROR_COLLISION)) ||
+ (type & SI_TYPE_MASK) != SI_TYPE_DOLPHIN || !(type & SI_GC_WIRELESS) ||
+ (type & SI_WIRELESS_IR)) {
+ OSSetWirelessID(chan, 0);
+ CallTypeAndStatusCallback(chan, Type[chan]);
+ return;
+ }
+
+ id = (u32)(OSGetWirelessID(chan) << 8);
+
+ if (fix && (id & SI_WIRELESS_FIX_ID)) {
+ cmdFixDevice[chan] = 0x4Eu << 24 | (id & SI_WIRELESS_TYPE_ID) | SI_WIRELESS_FIX_ID;
+ Type[chan] = SI_ERROR_BUSY;
+ SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0);
+ return;
+ }
+
+ if (type & SI_WIRELESS_FIX_ID) {
+ if ((id & SI_WIRELESS_TYPE_ID) != (type & SI_WIRELESS_TYPE_ID)) {
+ if (!(id & SI_WIRELESS_FIX_ID)) {
+ id = type & SI_WIRELESS_TYPE_ID;
+ id |= SI_WIRELESS_FIX_ID;
+ OSSetWirelessID(chan, (u16)((id >> 8) & 0xffff));
+ }
+
+ cmdFixDevice[chan] = 0x4E << 24 | id;
+ Type[chan] = SI_ERROR_BUSY;
+ SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0);
+ return;
+ }
+ } else if (type & SI_WIRELESS_RECEIVED) {
+ id = type & SI_WIRELESS_TYPE_ID;
+ id |= SI_WIRELESS_FIX_ID;
+
+ OSSetWirelessID(chan, (u16)((id >> 8) & 0xffff));
+
+ cmdFixDevice[chan] = 0x4E << 24 | id;
+ Type[chan] = SI_ERROR_BUSY;
+ SITransfer(chan, &cmdFixDevice[chan], 3, &Type[chan], 3, GetTypeCallback, 0);
+ return;
+ } else {
+ OSSetWirelessID(chan, 0);
+ }
+
+ CallTypeAndStatusCallback(chan, Type[chan]);
+}
+
+u32 SIGetType(s32 chan) {
+ static u32 cmdTypeAndStatus;
+ BOOL enabled;
+ u32 type;
+ OSTime diff;
+
+ enabled = OSDisableInterrupts();
+
+ type = Type[chan];
+ diff = __OSGetSystemTime() - TypeTime[chan];
+ if (Si.poll & (0x80 >> chan)) {
+ if (type != SI_ERROR_NO_RESPONSE) {
+ TypeTime[chan] = __OSGetSystemTime();
+ OSRestoreInterrupts(enabled);
+ return type;
+ } else {
+ type = Type[chan] = SI_ERROR_BUSY;
+ }
+ } else if (diff <= OSMillisecondsToTicks(50) && type != SI_ERROR_NO_RESPONSE) {
+ OSRestoreInterrupts(enabled);
+ return type;
+ } else if (diff <= OSMillisecondsToTicks(75)) {
+ Type[chan] = SI_ERROR_BUSY;
+ } else {
+ type = Type[chan] = SI_ERROR_BUSY;
+ }
+ TypeTime[chan] = __OSGetSystemTime();
+
+ SITransfer(chan, &cmdTypeAndStatus, 1, &Type[chan], 3, GetTypeCallback,
+ OSMicrosecondsToTicks(65));
+
+ OSRestoreInterrupts(enabled);
+ return type;
+}
+
+u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback) {
+ BOOL enabled;
+ u32 type;
+
+ enabled = OSDisableInterrupts();
+ type = SIGetType(chan);
+ if (Type[chan] & SI_ERROR_BUSY) {
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ if (TypeCallback[chan][i] == callback) {
+ break;
+ }
+ if (TypeCallback[chan][i] == 0) {
+ TypeCallback[chan][i] = callback;
+ break;
+ }
+ }
+ } else {
+ callback(chan, type);
+ }
+ OSRestoreInterrupts(enabled);
+ return type;
+}
+
+u32 SIDecodeType(u32 type) {
+ u32 error;
+
+ error = type & 0xff;
+ type &= ~0xff;
+
+ if (error & SI_ERROR_NO_RESPONSE) {
+ return SI_ERROR_NO_RESPONSE;
+ }
+ if (error & (SI_ERROR_UNDER_RUN | SI_ERROR_OVER_RUN | SI_ERROR_COLLISION | SI_ERROR_UNKNOWN)) {
+ return SI_ERROR_UNKNOWN;
+ }
+ if (error) {
+ return SI_ERROR_BUSY;
+ }
+
+ if ((type & SI_TYPE_MASK) == SI_TYPE_N64) {
+ switch (type & 0xffff0000) {
+ case SI_N64_CONTROLLER:
+ case SI_N64_MIC:
+ case SI_N64_KEYBOARD:
+ case SI_N64_MOUSE:
+ case SI_GBA:
+ return type & 0xffff0000;
+ break;
+ }
+ return SI_ERROR_UNKNOWN;
+ }
+
+ if ((type & SI_TYPE_MASK) != SI_TYPE_GC) {
+
+ return SI_ERROR_UNKNOWN;
+ }
+ switch (type & 0xffff0000) {
+ case SI_GC_CONTROLLER:
+ case SI_GC_STEERING:
+ return type & 0xffff0000;
+ break;
+ }
+
+ if ((type & 0xffe00000) == SI_GC_KEYBOARD) {
+ return SI_GC_KEYBOARD;
+ }
+
+ if ((type & SI_GC_WIRELESS) && !(type & SI_WIRELESS_IR)) {
+ if ((type & SI_GC_WAVEBIRD) == SI_GC_WAVEBIRD) {
+ return SI_GC_WAVEBIRD;
+ } else if (!(type & SI_WIRELESS_STATE)) {
+ return SI_GC_RECEIVER;
+ }
+ }
+
+ if ((type & SI_GC_CONTROLLER) == SI_GC_CONTROLLER) {
+ return SI_GC_CONTROLLER;
+ }
+ return SI_ERROR_UNKNOWN;
+}
+
+u32 SIProbe(s32 chan) { return SIDecodeType(SIGetType(chan)); }
+
+char* SIGetTypeString(u32 type) {
+ switch (SIDecodeType(type)) {
+ case SI_ERROR_NO_RESPONSE:
+ return "No response";
+ case SI_N64_CONTROLLER:
+ return "N64 controller";
+ case SI_N64_MIC:
+ return "N64 microphone";
+ case SI_N64_KEYBOARD:
+ return "N64 keyboard";
+ case SI_N64_MOUSE:
+ return "N64 mouse";
+ case SI_GBA:
+ return "GameBoy Advance";
+ case SI_GC_CONTROLLER:
+ return "Standard controller";
+ case SI_GC_RECEIVER:
+ return "Wireless receiver";
+ case SI_GC_WAVEBIRD:
+ return "WaveBird controller";
+ case SI_GC_KEYBOARD:
+ return "Keyboard";
+ case SI_GC_STEERING:
+ return "Steering";
+ }
+}
diff --git a/src/Dolphin/si/SISamplingRate.c b/src/Dolphin/si/SISamplingRate.c
new file mode 100644
index 0000000..c9b96ca
--- /dev/null
+++ b/src/Dolphin/si/SISamplingRate.c
@@ -0,0 +1,54 @@
+#include "dolphin/sipriv.h"
+#include "dolphin/vi.h"
+#pragma dont_inline on
+static u32 SamplingRate;
+
+typedef struct XY {
+ u16 line;
+ u8 count;
+} XY;
+
+static XY XYNTSC[12] = {
+ {263 - 17, 2}, {15, 18}, {30, 9}, {44, 6}, {52, 5}, {65, 4},
+ {87, 3}, {87, 3}, {87, 3}, {131, 2}, {131, 2}, {131, 2},
+};
+
+static XY XYPAL[12] = {
+ {313 - 17, 2}, {15, 21}, {29, 11}, {45, 7}, {52, 6}, {63, 5},
+ {78, 4}, {104, 3}, {104, 3}, {104, 3}, {104, 3}, {156, 2},
+};
+
+void SISetSamplingRate(u32 msec) {
+ XY* xy;
+ BOOL enabled;
+
+ if (msec > 11) {
+ msec = 11;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ SamplingRate = msec;
+
+ switch (VIGetTvFormat()) {
+ case VI_NTSC:
+ case VI_MPAL:
+ case VI_EURGB60:
+ xy = XYNTSC;
+ break;
+ case VI_PAL:
+ xy = XYPAL;
+ break;
+ default:
+ OSReport("SISetSamplingRate: unknown TV format. Use default.");
+ msec = 0;
+ xy = XYNTSC;
+ break;
+ }
+
+ SISetXY((__VIRegs[54] & 1 ? 2u : 1u) * xy[msec].line, xy[msec].count);
+ OSRestoreInterrupts(enabled);
+}
+
+void SIRefreshSamplingRate() { SISetSamplingRate(SamplingRate); }
+#pragma dont_inline reset