summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-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
90 files changed, 5323 insertions, 35 deletions
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