summaryrefslogtreecommitdiff
path: root/arm9/lib
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-05-20 14:59:56 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2020-05-20 14:59:56 -0400
commitd1d3fce4b6be10ed7186a6c36bc27fe575b593db (patch)
tree4f31107f4446b69106acb0673a383dfdaf88473e /arm9/lib
parent6103ab0ca0962682095e58779079cb4c8c054b14 (diff)
parentde389305733545e2b6fac6c8dcb33d76a7446481 (diff)
Merge branch 'master' of github.com:martmists/pokediamond into pikalax_work
Diffstat (limited to 'arm9/lib')
-rw-r--r--arm9/lib/include/CP_context.h18
-rw-r--r--arm9/lib/include/GX_asm.h6
-rw-r--r--arm9/lib/include/GX_bgcnt.h347
-rw-r--r--arm9/lib/include/GX_dma.h53
-rw-r--r--arm9/lib/include/GX_g2.h14
-rw-r--r--arm9/lib/include/GX_g3.h184
-rw-r--r--arm9/lib/include/GX_g3_util.h11
-rw-r--r--arm9/lib/include/GX_g3b.h21
-rw-r--r--arm9/lib/include/GX_g3imm.h10
-rw-r--r--arm9/lib/include/GX_g3x.h69
-rw-r--r--arm9/lib/include/GX_load2d.h41
-rw-r--r--arm9/lib/include/GX_load3d.h15
-rw-r--r--arm9/lib/include/GX_state.h24
-rw-r--r--arm9/lib/include/GX_struct_2d.h243
-rw-r--r--arm9/lib/include/GX_vramcnt.h57
-rw-r--r--arm9/lib/include/GXcommon.h29
-rw-r--r--arm9/lib/include/OS_alarm.h27
-rw-r--r--arm9/lib/include/OS_context.h22
-rw-r--r--arm9/lib/include/OS_init.h4
-rw-r--r--arm9/lib/include/OS_interrupt.h5
-rw-r--r--arm9/lib/include/OS_mutex.h18
-rw-r--r--arm9/lib/include/OS_thread.h63
-rw-r--r--arm9/lib/include/OS_tick.h12
-rw-r--r--arm9/lib/include/fx.h10
-rw-r--r--arm9/lib/include/gx.h179
-rw-r--r--arm9/lib/src/GX.c121
-rw-r--r--arm9/lib/src/GX_asm.c16
-rw-r--r--arm9/lib/src/GX_bgcnt.c195
-rw-r--r--arm9/lib/src/GX_g2.c66
-rw-r--r--arm9/lib/src/GX_g3.c36
-rw-r--r--arm9/lib/src/GX_g3_util.c260
-rw-r--r--arm9/lib/src/GX_g3b.c120
-rw-r--r--arm9/lib/src/GX_g3imm.c18
-rw-r--r--arm9/lib/src/GX_g3x.c235
-rw-r--r--arm9/lib/src/GX_load2d.c223
-rw-r--r--arm9/lib/src/GX_load3d.c125
-rw-r--r--arm9/lib/src/GX_state.c26
-rw-r--r--arm9/lib/src/GX_vramcnt.c579
-rw-r--r--arm9/lib/src/OS_init.c1
-rw-r--r--arm9/lib/src/OS_interrupt.c56
-rw-r--r--arm9/lib/src/OS_reset.c5
41 files changed, 3554 insertions, 10 deletions
diff --git a/arm9/lib/include/CP_context.h b/arm9/lib/include/CP_context.h
new file mode 100644
index 00000000..d1e0062c
--- /dev/null
+++ b/arm9/lib/include/CP_context.h
@@ -0,0 +1,18 @@
+//
+// Created by red031000 on 2020-05-17.
+//
+
+#ifndef POKEDIAMOND_CP_CONTEXT_H
+#define POKEDIAMOND_CP_CONTEXT_H
+
+#include "types.h"
+
+typedef struct CPContext {
+ u64 div_numer;
+ u64 div_denom;
+ u64 sqrt;
+ u16 div_mode;
+ u16 sqrt_mode;
+} CPContext;
+
+#endif //POKEDIAMOND_CP_CONTEXT_H
diff --git a/arm9/lib/include/GX_asm.h b/arm9/lib/include/GX_asm.h
new file mode 100644
index 00000000..d2622508
--- /dev/null
+++ b/arm9/lib/include/GX_asm.h
@@ -0,0 +1,6 @@
+#ifndef GUARD_GX_ASM_H
+#define GUARD_GX_ASM_H
+
+void GX_SendFifo48B(register void *pSrc, register void *pDest);
+
+#endif //GUARD_GX_ASM_H
diff --git a/arm9/lib/include/GX_bgcnt.h b/arm9/lib/include/GX_bgcnt.h
new file mode 100644
index 00000000..a581443e
--- /dev/null
+++ b/arm9/lib/include/GX_bgcnt.h
@@ -0,0 +1,347 @@
+#ifndef GUARD_GX_BGCNT_H
+#define GUARD_GX_BGCNT_H
+
+void *G2_GetBG0ScrPtr();
+void *G2S_GetBG0ScrPtr();
+void *G2_GetBG1ScrPtr();
+void *G2S_GetBG1ScrPtr();
+void *G2_GetBG2ScrPtr();
+void *G2S_GetBG2ScrPtr();
+void *G2_GetBG3ScrPtr();
+void *G2S_GetBG3ScrPtr();
+void *G2_GetBG0CharPtr();
+void *G2S_GetBG0CharPtr();
+void *G2_GetBG1CharPtr();
+void *G2S_GetBG1CharPtr();
+void *G2_GetBG2CharPtr();
+void *G2S_GetBG2CharPtr();
+void *G2_GetBG3CharPtr();
+void *G2S_GetBG3CharPtr();
+
+typedef union
+{
+ u16 raw;
+ struct
+ {
+ u16 priority:2;
+ u16 charBase:4;
+ u16 mosaic:1;
+ u16 colorMode:1;
+ u16 screenBase:5;
+ u16 bgExtPltt:1;
+ u16 screenSize:2;
+ };
+}
+GXBg01Control;
+
+typedef union
+{
+ u16 raw;
+ struct
+ {
+ u16 priority:2;
+ u16 charBase:4;
+ u16 mosaic:1;
+ u16 colorMode:1;
+ u16 screenBase:5;
+ u16 _reserve:1;
+ u16 screenSize:2;
+ };
+}
+GXBg23ControlText;
+
+typedef union
+{
+ u16 raw;
+ struct
+ {
+ u16 priority:2;
+ u16 charBase:4;
+ u16 mosaic:1;
+ u16 _reserve:1;
+ u16 screenBase:5;
+ u16 areaOver:1;
+ u16 screenSize:2;
+ };
+}
+GXBg23ControlAffine;
+
+typedef union
+{
+ u16 raw;
+ struct
+ {
+ u16 priority:2;
+ u16 _reserve1:1;
+ u16 charBase:3;
+ u16 mosaic:1;
+ u16 _reserve2:1;
+ u16 screenBase:5;
+ u16 areaOver:1;
+ u16 screenSize:2;
+ };
+}
+GXBg23Control256x16Pltt;
+
+
+typedef union
+{
+ u16 raw;
+ struct
+ {
+ u16 priority:2;
+ u16 _reserve1:4;
+ u16 mosaic:1;
+ u16 _reserve2:1;
+ u16 screenBase:5;
+ u16 areaOver:1;
+ u16 screenSize:2;
+ };
+}
+GXBg23Control256Bmp, GXBg23ControlDCBmp;
+
+typedef union
+{
+ u16 raw;
+ struct
+ {
+ u16 priority:2;
+ u16 _reserve1:4;
+ u16 mosaic:1;
+ u16 _reserve2:6;
+ u16 areaOver:1;
+ u16 screenSize:2;
+ };
+}
+GXBg2ControlLargeBmp;
+
+
+
+typedef enum
+{
+ GX_BG_SCRSIZE_TEXT_256x256 = 0,
+ GX_BG_SCRSIZE_TEXT_512x256 = 1,
+ GX_BG_SCRSIZE_TEXT_256x512 = 2,
+ GX_BG_SCRSIZE_TEXT_512x512 = 3
+}
+GXBGScrSizeText;
+
+typedef enum
+{
+ GX_BG_SCRSIZE_AFFINE_128x128 = 0,
+ GX_BG_SCRSIZE_AFFINE_256x256 = 1,
+ GX_BG_SCRSIZE_AFFINE_512x512 = 2,
+ GX_BG_SCRSIZE_AFFINE_1024x1024 = 3
+}
+GXBGScrSizeAffine;
+
+typedef enum
+{
+ GX_BG_SCRSIZE_256x16PLTT_128x128 = 0,
+ GX_BG_SCRSIZE_256x16PLTT_256x256 = 1,
+ GX_BG_SCRSIZE_256x16PLTT_512x512 = 2,
+ GX_BG_SCRSIZE_256x16PLTT_1024x1024 = 3
+}
+GXBGScrSize256x16Pltt;
+
+typedef enum
+{
+ GX_BG_SCRSIZE_256BMP_128x128 = 0,
+ GX_BG_SCRSIZE_256BMP_256x256 = 1,
+ GX_BG_SCRSIZE_256BMP_512x256 = 2,
+ GX_BG_SCRSIZE_256BMP_512x512 = 3
+}
+GXBGScrSize256Bmp;
+
+typedef enum
+{
+ GX_BG_SCRSIZE_DCBMP_128x128 = 0,
+ GX_BG_SCRSIZE_DCBMP_256x256 = 1,
+ GX_BG_SCRSIZE_DCBMP_512x256 = 2,
+ GX_BG_SCRSIZE_DCBMP_512x512 = 3
+}
+GXBGScrSizeDcBmp;
+
+typedef enum
+{
+ GX_BG_SCRSIZE_LARGEBMP_512x1024 = 0,
+ GX_BG_SCRSIZE_LARGEBMP_1024x512 = 1
+}
+GXBGScrSizeLargeBmp;
+
+typedef enum
+{
+ GX_BG_COLORMODE_16 = 0,
+ GX_BG_COLORMODE_256 = 1
+}
+GXBGColorMode;
+
+typedef enum
+{
+ GX_BG_AREAOVER_XLU = 0,
+ GX_BG_AREAOVER_REPEAT = 1
+}
+GXBGAreaOver;
+
+typedef enum
+{
+ GX_BG_CHARBASE_0x00000 = 0,
+ GX_BG_CHARBASE_0x04000 = 1,
+ GX_BG_CHARBASE_0x08000 = 2,
+ GX_BG_CHARBASE_0x0c000 = 3,
+ GX_BG_CHARBASE_0x10000 = 4,
+ GX_BG_CHARBASE_0x14000 = 5,
+ GX_BG_CHARBASE_0x18000 = 6,
+ GX_BG_CHARBASE_0x1c000 = 7,
+ GX_BG_CHARBASE_0x20000 = 8,
+ GX_BG_CHARBASE_0x24000 = 9,
+ GX_BG_CHARBASE_0x28000 = 10,
+ GX_BG_CHARBASE_0x2c000 = 11,
+ GX_BG_CHARBASE_0x30000 = 12,
+ GX_BG_CHARBASE_0x34000 = 13,
+ GX_BG_CHARBASE_0x38000 = 14,
+ GX_BG_CHARBASE_0x3c000 = 15
+}
+GXBGCharBase;
+
+typedef enum
+{
+ GX_BG_SCRBASE_0x0000 = 0,
+ GX_BG_SCRBASE_0x0800 = 1,
+ GX_BG_SCRBASE_0x1000 = 2,
+ GX_BG_SCRBASE_0x1800 = 3,
+ GX_BG_SCRBASE_0x2000 = 4,
+ GX_BG_SCRBASE_0x2800 = 5,
+ GX_BG_SCRBASE_0x3000 = 6,
+ GX_BG_SCRBASE_0x3800 = 7,
+ GX_BG_SCRBASE_0x4000 = 8,
+ GX_BG_SCRBASE_0x4800 = 9,
+ GX_BG_SCRBASE_0x5000 = 10,
+ GX_BG_SCRBASE_0x5800 = 11,
+ GX_BG_SCRBASE_0x6000 = 12,
+ GX_BG_SCRBASE_0x6800 = 13,
+ GX_BG_SCRBASE_0x7000 = 14,
+ GX_BG_SCRBASE_0x7800 = 15,
+ GX_BG_SCRBASE_0x8000 = 16,
+ GX_BG_SCRBASE_0x8800 = 17,
+ GX_BG_SCRBASE_0x9000 = 18,
+ GX_BG_SCRBASE_0x9800 = 19,
+ GX_BG_SCRBASE_0xa000 = 20,
+ GX_BG_SCRBASE_0xa800 = 21,
+ GX_BG_SCRBASE_0xb000 = 22,
+ GX_BG_SCRBASE_0xb800 = 23,
+ GX_BG_SCRBASE_0xc000 = 24,
+ GX_BG_SCRBASE_0xc800 = 25,
+ GX_BG_SCRBASE_0xd000 = 26,
+ GX_BG_SCRBASE_0xd800 = 27,
+ GX_BG_SCRBASE_0xe000 = 28,
+ GX_BG_SCRBASE_0xe800 = 29,
+ GX_BG_SCRBASE_0xf000 = 30,
+ GX_BG_SCRBASE_0xf800 = 31
+}
+GXBGScrBase;
+
+typedef enum
+{
+ GX_BG_BMPSCRBASE_0x00000 = 0,
+ GX_BG_BMPSCRBASE_0x04000 = 1,
+ GX_BG_BMPSCRBASE_0x08000 = 2,
+ GX_BG_BMPSCRBASE_0x0c000 = 3,
+ GX_BG_BMPSCRBASE_0x10000 = 4,
+ GX_BG_BMPSCRBASE_0x14000 = 5,
+ GX_BG_BMPSCRBASE_0x18000 = 6,
+ GX_BG_BMPSCRBASE_0x1c000 = 7,
+ GX_BG_BMPSCRBASE_0x20000 = 8,
+ GX_BG_BMPSCRBASE_0x24000 = 9,
+ GX_BG_BMPSCRBASE_0x28000 = 10,
+ GX_BG_BMPSCRBASE_0x2c000 = 11,
+ GX_BG_BMPSCRBASE_0x30000 = 12,
+ GX_BG_BMPSCRBASE_0x34000 = 13,
+ GX_BG_BMPSCRBASE_0x38000 = 14,
+ GX_BG_BMPSCRBASE_0x3c000 = 15,
+ GX_BG_BMPSCRBASE_0x40000 = 16,
+ GX_BG_BMPSCRBASE_0x44000 = 17,
+ GX_BG_BMPSCRBASE_0x48000 = 18,
+ GX_BG_BMPSCRBASE_0x4c000 = 19,
+ GX_BG_BMPSCRBASE_0x50000 = 20,
+ GX_BG_BMPSCRBASE_0x54000 = 21,
+ GX_BG_BMPSCRBASE_0x58000 = 22,
+ GX_BG_BMPSCRBASE_0x5c000 = 23,
+ GX_BG_BMPSCRBASE_0x60000 = 24,
+ GX_BG_BMPSCRBASE_0x64000 = 25,
+ GX_BG_BMPSCRBASE_0x68000 = 26,
+ GX_BG_BMPSCRBASE_0x6c000 = 27,
+ GX_BG_BMPSCRBASE_0x70000 = 28,
+ GX_BG_BMPSCRBASE_0x74000 = 29,
+ GX_BG_BMPSCRBASE_0x78000 = 30,
+ GX_BG_BMPSCRBASE_0x7c000 = 31
+}
+GXBGBmpScrBase;
+
+typedef enum
+{
+ GX_BG_EXTPLTT_01 = 0,
+ GX_BG_EXTPLTT_23 = 1
+}
+GXBGExtPltt;
+
+//GX_capture
+typedef enum
+{
+ GX_CAPTURE_DEST_VRAM_A_0x00000 = 0,
+ GX_CAPTURE_DEST_VRAM_B_0x00000 = 1,
+ GX_CAPTURE_DEST_VRAM_C_0x00000 = 2,
+ GX_CAPTURE_DEST_VRAM_D_0x00000 = 3,
+
+ GX_CAPTURE_DEST_VRAM_A_0x08000 = 4,
+ GX_CAPTURE_DEST_VRAM_B_0x08000 = 5,
+ GX_CAPTURE_DEST_VRAM_C_0x08000 = 6,
+ GX_CAPTURE_DEST_VRAM_D_0x08000 = 7,
+
+ GX_CAPTURE_DEST_VRAM_A_0x10000 = 8,
+ GX_CAPTURE_DEST_VRAM_B_0x10000 = 9,
+ GX_CAPTURE_DEST_VRAM_C_0x10000 = 10,
+ GX_CAPTURE_DEST_VRAM_D_0x10000 = 11,
+
+ GX_CAPTURE_DEST_VRAM_A_0x18000 = 12,
+ GX_CAPTURE_DEST_VRAM_B_0x18000 = 13,
+ GX_CAPTURE_DEST_VRAM_C_0x18000 = 14,
+ GX_CAPTURE_DEST_VRAM_D_0x18000 = 15
+}
+GXCaptureDest;
+
+typedef enum
+{
+ GX_CAPTURE_SIZE_128x128 = 0,
+ GX_CAPTURE_SIZE_256x64 = 1,
+ GX_CAPTURE_SIZE_256x128 = 2,
+ GX_CAPTURE_SIZE_256x192 = 3
+}
+GXCaptureSize;
+
+typedef enum
+{
+ GX_CAPTURE_SRCA_2D3D = 0,
+ GX_CAPTURE_SRCA_3D = 1
+}
+GXCaptureSrcA;
+
+typedef enum
+{
+ GX_CAPTURE_SRCB_VRAM_0x00000 = 0,
+ GX_CAPTURE_SRCB_MRAM = 1,
+ GX_CAPTURE_SRCB_VRAM_0x08000 = 2,
+ GX_CAPTURE_SRCB_VRAM_0x10000 = 4,
+ GX_CAPTURE_SRCB_VRAM_0x18000 = 6
+}
+GXCaptureSrcB;
+
+typedef enum
+{
+ GX_CAPTURE_MODE_A = 0,
+ GX_CAPTURE_MODE_B = 1,
+ GX_CAPTURE_MODE_AB = 2
+}
+GXCaptureMode;
+
+#endif //GUARD_GX_BGCNT_H
diff --git a/arm9/lib/include/GX_dma.h b/arm9/lib/include/GX_dma.h
new file mode 100644
index 00000000..98f6a4a2
--- /dev/null
+++ b/arm9/lib/include/GX_dma.h
@@ -0,0 +1,53 @@
+#ifndef GUARD_GX_DMA_H
+#define GUARD_GX_DMA_H
+
+#define GX_DMA_NOT_USE -1
+#define GX_CPU_FASTER32_SIZE 0x30
+#define GX_CPU_FASTER16_SIZE 0x1C
+
+static inline void GXi_DmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ if (dmaNo != GX_DMA_NOT_USE && size > GX_CPU_FASTER32_SIZE)
+ {
+ MI_DmaCopy32(dmaNo, src, dest, size);
+ }
+ else
+ {
+ MIi_CpuCopy32(src, dest, size);
+ }
+}
+
+static inline void GXi_DmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size)
+{
+ if (dmaNo != GX_DMA_NOT_USE && size > GX_CPU_FASTER16_SIZE)
+ {
+ MI_DmaCopy16(dmaNo, src, dest, size);
+ }
+ else
+ {
+ MIi_CpuCopy16(src, dest, size);
+ }
+}
+
+static inline void GXi_DmaCopy32Async(u32 dmaNo, const void *src, void *dest, u32 size,
+ MIDmaCallback callback, void *arg)
+{
+ if (dmaNo != GX_DMA_NOT_USE)
+ {
+ MI_DmaCopy32Async(dmaNo, src, dest, size, callback, arg);
+ }
+ else
+ {
+ MIi_CpuCopy32(src, dest, size);
+ }
+}
+
+static inline void GXi_WaitDma(u32 dmaNo)
+{
+ if (dmaNo != GX_DMA_NOT_USE)
+ {
+ MI_WaitDma(dmaNo);
+ }
+}
+
+#endif //GUARD_GX_DMA_H
diff --git a/arm9/lib/include/GX_g2.h b/arm9/lib/include/GX_g2.h
new file mode 100644
index 00000000..f8d86df0
--- /dev/null
+++ b/arm9/lib/include/GX_g2.h
@@ -0,0 +1,14 @@
+#ifndef GUARD_GX_G2_H
+#define GUARD_GX_G2_H
+
+#include "fx.h"
+
+void G2x_SetBGyAffine_(u32 *ptr, struct Mtx22 *mtx, fx32 a, fx32 b, fx32 c, fx32 d);
+void G2x_SetBlendAlpha_(u32 *ptr, fx32 a, fx32 b, fx32 c, fx32 d);
+void G2x_SetBlendBrightness_(u16 *ptr, fx32 a, fx32 brightness);
+void G2x_SetBlendBrightnessExt_(u16 *ptr, fx32 a, fx32 b, fx32 c, fx32 d, fx32 brightness);
+void *G2x_ChangeBlendBrightness_(u16 *ptr, fx32 brightness);
+
+//The g2 and g2_oam headers contain a lot of inline functions and enums that may want to be ported over at some point
+
+#endif //GUARD_GX_G2_H
diff --git a/arm9/lib/include/GX_g3.h b/arm9/lib/include/GX_g3.h
new file mode 100644
index 00000000..765ecc64
--- /dev/null
+++ b/arm9/lib/include/GX_g3.h
@@ -0,0 +1,184 @@
+#ifndef GUARD_GX_G3_H
+#define GUARD_GX_G3_H
+
+struct GXDLInfo
+{
+ u8 *curr_cmd;
+ u32 *curr_param;
+ u32 *bottom;
+ u32 length;
+ BOOL param0_cmd_flg;
+};
+
+void G3_BeginMakeDL(struct GXDLInfo *displaylist, void *r1, u32 r2);
+s32 G3_EndMakeDL(struct GXDLInfo *displaylist);
+
+typedef enum
+{
+ GX_MTXMODE_PROJECTION = 0,
+ GX_MTXMODE_POSITION = 1,
+ GX_MTXMODE_POSITION_VECTOR = 2,
+ GX_MTXMODE_TEXTURE = 3
+}
+GXMtxMode;
+
+typedef enum
+{
+ GX_BEGIN_TRIANGLES = 0,
+ GX_BEGIN_QUADS = 1,
+ GX_BEGIN_TRIANGLE_STRIP = 2,
+ GX_BEGIN_QUAD_STRIP = 3
+}
+GXBegin;
+
+typedef enum
+{
+ GX_SORTMODE_AUTO = 0,
+ GX_SORTMODE_MANUAL = 1
+}
+GXSortMode;
+
+typedef enum
+{
+ GX_BUFFERMODE_Z = 0,
+ GX_BUFFERMODE_W = 1
+}
+GXBufferMode;
+
+typedef enum
+{
+ GX_LIGHTMASK_NONE = 0,
+ GX_LIGHTMASK_0 = 1,
+ GX_LIGHTMASK_1 = 2,
+ GX_LIGHTMASK_01 = 3,
+ GX_LIGHTMASK_2 = 4,
+ GX_LIGHTMASK_02 = 5,
+ GX_LIGHTMASK_12 = 6,
+ GX_LIGHTMASK_012 = 7,
+ GX_LIGHTMASK_3 = 8,
+ GX_LIGHTMASK_03 = 9,
+ GX_LIGHTMASK_13 = 10,
+ GX_LIGHTMASK_013 = 11,
+ GX_LIGHTMASK_23 = 12,
+ GX_LIGHTMASK_023 = 13,
+ GX_LIGHTMASK_123 = 14,
+ GX_LIGHTMASK_0123 = 15
+}
+GXLightMask;
+
+typedef enum
+{
+ GX_POLYGONMODE_MODULATE = 0,
+ GX_POLYGONMODE_DECAL = 1,
+ GX_POLYGONMODE_TOON = 2,
+ GX_POLYGONMODE_SHADOW = 3
+}
+GXPolygonMode;
+
+typedef enum
+{
+ GX_CULL_ALL = 0,
+ GX_CULL_FRONT = 1,
+ GX_CULL_BACK = 2,
+ GX_CULL_NONE = 3
+}
+GXCull;
+
+typedef enum
+{
+ GX_TEXREPEAT_NONE = 0,
+ GX_TEXREPEAT_S = 1,
+ GX_TEXREPEAT_T = 2,
+ GX_TEXREPEAT_ST = 3
+}
+GXTexRepeat;
+
+typedef enum
+{
+ GX_TEXFLIP_NONE = 0,
+ GX_TEXFLIP_S = 1,
+ GX_TEXFLIP_T = 2,
+ GX_TEXFLIP_ST = 3
+}
+GXTexFlip;
+
+typedef enum
+{
+ GX_TEXSIZE_S8 = 0,
+ GX_TEXSIZE_S16 = 1,
+ GX_TEXSIZE_S32 = 2,
+ GX_TEXSIZE_S64 = 3,
+ GX_TEXSIZE_S128 = 4,
+ GX_TEXSIZE_S256 = 5,
+ GX_TEXSIZE_S512 = 6,
+ GX_TEXSIZE_S1024 = 7
+}
+GXTexSizeS;
+
+typedef enum
+{
+ GX_TEXSIZE_T8 = 0,
+ GX_TEXSIZE_T16 = 1,
+ GX_TEXSIZE_T32 = 2,
+ GX_TEXSIZE_T64 = 3,
+ GX_TEXSIZE_T128 = 4,
+ GX_TEXSIZE_T256 = 5,
+ GX_TEXSIZE_T512 = 6,
+ GX_TEXSIZE_T1024 = 7
+}
+GXTexSizeT;
+
+typedef enum
+{
+ GX_TEXFMT_NONE = 0,
+ GX_TEXFMT_A3I5 = 1,
+ GX_TEXFMT_PLTT4 = 2,
+ GX_TEXFMT_PLTT16 = 3,
+ GX_TEXFMT_PLTT256 = 4,
+ GX_TEXFMT_COMP4x4 = 5,
+ GX_TEXFMT_A5I3 = 6,
+ GX_TEXFMT_DIRECT = 7
+}
+GXTexFmt;
+
+typedef enum
+{
+ GX_TEXPLTTCOLOR0_USE = 0,
+ GX_TEXPLTTCOLOR0_TRNS = 1
+}
+GXTexPlttColor0;
+
+typedef enum
+{
+ GX_TEXGEN_NONE = 0,
+ GX_TEXGEN_TEXCOORD = 1,
+ GX_TEXGEN_NORMAL = 2,
+ GX_TEXGEN_VERTEX = 3
+}
+GXTexGen;
+
+typedef enum
+{
+ GX_LIGHTID_0 = 0,
+ GX_LIGHTID_1 = 1,
+ GX_LIGHTID_2 = 2,
+ GX_LIGHTID_3 = 3
+}
+GXLightId;
+
+typedef union
+{
+ u32 val[3];
+ struct
+ {
+ fx16 x;
+ fx16 y;
+ fx16 z;
+ fx16 width;
+ fx16 height;
+ fx16 depth;
+ };
+}
+GXBoxTestParam;
+
+#endif //GUARD_GX_G3_H
diff --git a/arm9/lib/include/GX_g3_util.h b/arm9/lib/include/GX_g3_util.h
new file mode 100644
index 00000000..a9bc4c17
--- /dev/null
+++ b/arm9/lib/include/GX_g3_util.h
@@ -0,0 +1,11 @@
+#ifndef GUARD_GX_G3_UTIL_H
+#define GUARD_GX_G3_UTIL_H
+
+void G3i_PerspectiveW_(fx32 fovsin, fx32 fovcos, fx32 ratio, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx);
+void G3i_OrthoW_(fx32 top, fx32 bottom, fx32 left, fx32 right, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx);
+void G3i_LookAt_(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *c, u32 load, struct Mtx44 *mtx);
+void G3_RotX(fx32 sinphi, fx32 cosphi);
+void G3_RotY(fx32 sinphi, fx32 cosphi);
+void G3_RotZ(fx32 sinphi, fx32 cosphi);
+
+#endif //GUARD_GX_G3_UTIL_H
diff --git a/arm9/lib/include/GX_g3b.h b/arm9/lib/include/GX_g3b.h
new file mode 100644
index 00000000..d299ea34
--- /dev/null
+++ b/arm9/lib/include/GX_g3b.h
@@ -0,0 +1,21 @@
+#ifndef GUARD_GX_G3B_H
+#define GUARD_GX_G3B_H
+
+#include "GX_g3.h"
+
+void G3BS_LoadMtx44(struct GXDLInfo *displaylist, struct Mtx44 *mtx);
+void G3B_PushMtx(struct GXDLInfo *displaylist);
+void G3B_PopMtx(struct GXDLInfo *displaylist, void *mtx);
+void G3B_LoadMtx44(struct GXDLInfo *displaylist, struct Mtx44 *mtx);
+void G3B_Color(struct GXDLInfo * displaylist, u32 vtx_col);
+void G3B_Normal(struct GXDLInfo * displaylist, fx16 x, fx16 y, fx16 z);
+void G3B_Vtx(struct GXDLInfo * displaylist, fx32 x, fx32 y, fx32 z);
+void G3B_PolygonAttr(struct GXDLInfo *displaylist, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6);
+void G3B_MaterialColorDiffAmb(struct GXDLInfo *displaylist, u32 diffuse_col, u32 ambient_col, u32 replace);
+void G3B_MaterialColorSpecEmi(struct GXDLInfo *displaylist, u32 specular_col, u32 emission_col, u32 shiny_table);
+void G3B_LightVector(struct GXDLInfo * displaylist, u32 light_num, fx16 x, fx16 y, fx16 z);
+void G3B_LightColor(struct GXDLInfo * displaylist, u32 light_num, u32 col);
+void G3B_Begin(struct GXDLInfo * displaylist, u32 type);
+void G3B_End(struct GXDLInfo * displaylist);
+
+#endif //GUARD_GX_G3B_H
diff --git a/arm9/lib/include/GX_g3imm.h b/arm9/lib/include/GX_g3imm.h
new file mode 100644
index 00000000..f811dc68
--- /dev/null
+++ b/arm9/lib/include/GX_g3imm.h
@@ -0,0 +1,10 @@
+#ifndef GUARD_GX_G3IMM_H
+#define GUARD_GX_G3IMM_H
+
+#include "fx.h"
+
+void G3_LoadMtx43(struct Mtx43 *mtx);
+void G3_MultMtx43(struct Mtx43 *mtx);
+void G3_MultMtx33(struct Mtx33 *mtx);
+
+#endif //GUARD_GX_G3IMM_H
diff --git a/arm9/lib/include/GX_g3x.h b/arm9/lib/include/GX_g3x.h
new file mode 100644
index 00000000..4bd55831
--- /dev/null
+++ b/arm9/lib/include/GX_g3x.h
@@ -0,0 +1,69 @@
+#ifndef GUARD_GX_G3X_H
+#define GUARD_GX_G3X_H
+
+void GXi_NopClearFifo128_(void *reg);
+void G3X_Init();
+void G3X_ResetMtxStack();
+void G3X_ClearFifo();
+void G3X_InitMtxStack();
+void G3X_ResetMtxStack_2();
+void G3X_SetFog(u32 enable, u32 alphamode, u32 depth, s32 offset);
+u32 G3X_GetClipMtx(struct Mtx44 *dst);
+u32 G3X_GetVectorMtx(struct Mtx33 *dst);
+void G3X_SetEdgeColorTable(void *tbl_ptr);
+void G3X_SetFogTable(void *tbl_ptr);
+void G3X_SetClearColor(u32 col, u32 alpha, u32 depth, u32 polygon_id, u32 enable_fog);
+void G3X_InitTable();
+u32 G3X_GetMtxStackLevelPV(u32 *level);
+u32 G3X_GetMtxStackLevelPJ(u32 *level);
+u32 G3X_GetBoxTestResult(u32 *result);
+void G3X_SetHOffset(u32 offset);
+
+typedef enum
+{
+ GX_SHADING_TOON = 0,
+ GX_SHADING_HIGHLIGHT = 1
+}
+GXShading;
+
+typedef enum
+{
+ GX_FOGBLEND_COLOR_ALPHA = 0,
+ GX_FOGBLEND_ALPHA = 1
+}
+GXFogBlend;
+
+typedef enum
+{
+ GX_FOGSLOPE_0x8000 = 0,
+ GX_FOGSLOPE_0x4000 = 1,
+ GX_FOGSLOPE_0x2000 = 2,
+ GX_FOGSLOPE_0x1000 = 3,
+ GX_FOGSLOPE_0x0800 = 4,
+ GX_FOGSLOPE_0x0400 = 5,
+ GX_FOGSLOPE_0x0200 = 6,
+ GX_FOGSLOPE_0x0100 = 7,
+ GX_FOGSLOPE_0x0080 = 8,
+ GX_FOGSLOPE_0x0040 = 9,
+ GX_FOGSLOPE_0x0020 = 10
+}
+GXFogSlope;
+
+typedef enum
+{
+ GX_FIFOINTR_COND_DISABLE = 0,
+ GX_FIFOINTR_COND_UNDERHALF = 1,
+ GX_FIFOINTR_COND_EMPTY = 2
+}
+GXFifoIntrCond;
+
+typedef enum
+{
+ GX_FIFOSTAT_EMPTY = 6,
+ GX_FIFOSTAT_UNDERHALF = 2,
+ GX_FIFOSTAT_OVERHALF = 0,
+ GX_FIFOSTAT_FULL = 1
+}
+GXFifoStat;
+
+#endif //GUARD_GX_G3X_H
diff --git a/arm9/lib/include/GX_load2d.h b/arm9/lib/include/GX_load2d.h
new file mode 100644
index 00000000..3c9fb5cb
--- /dev/null
+++ b/arm9/lib/include/GX_load2d.h
@@ -0,0 +1,41 @@
+#ifndef GUARD_GX_LOAD2D_H
+#define GUARD_GX_LOAD2D_H
+
+void GX_LoadBGPltt(void *src, u32 offset, u32 size);
+void GXS_LoadBGPltt(void *src, u32 offset, u32 size);
+void GX_LoadOBJPltt(void *src, u32 offset, u32 size);
+void GXS_LoadOBJPltt(void *src, u32 offset, u32 size);
+void GX_LoadOAM(void *src, u32 offset, u32 size);
+void GXS_LoadOAM(void *src, u32 offset, u32 size);
+void GX_LoadOBJ(void *src, u32 offset, u32 size);
+void GXS_LoadOBJ(void *src, u32 offset, u32 size);
+void GX_LoadBG0Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG0Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG1Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG1Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG2Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG2Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG3Scr(void *src, u32 offset, u32 size);
+void GXS_LoadBG3Scr(void *src, u32 offset, u32 size);
+void GX_LoadBG0Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG0Char(void *src, u32 offset, u32 size);
+void GX_LoadBG1Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG1Char(void *src, u32 offset, u32 size);
+void GX_LoadBG2Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG2Char(void *src, u32 offset, u32 size);
+void GX_LoadBG3Char(void *src, u32 offset, u32 size);
+void GXS_LoadBG3Char(void *src, u32 offset, u32 size);
+void GX_BeginLoadBGExtPltt();
+void GX_LoadBGExtPltt(void *src, u32 offset, u32 size);
+void GX_EndLoadBGExtPltt();
+void GX_BeginLoadOBJExtPltt();
+void GX_LoadOBJExtPltt(void *src, u32 offset, u32 size);
+void GX_EndLoadOBJExtPltt();
+void GXS_BeginLoadBGExtPltt();
+void GXS_LoadBGExtPltt(void *src, u32 offset, u32 size);
+void GXS_EndLoadBGExtPltt();
+void GXS_BeginLoadOBJExtPltt();
+void GXS_LoadOBJExtPltt(void *src, u32 offset, u32 size);
+void GXS_EndLoadOBJExtPltt();
+
+#endif //GUARD_GX_LOAD2D_H
diff --git a/arm9/lib/include/GX_load3d.h b/arm9/lib/include/GX_load3d.h
new file mode 100644
index 00000000..09fd296a
--- /dev/null
+++ b/arm9/lib/include/GX_load3d.h
@@ -0,0 +1,15 @@
+#ifndef GUARD_GX_LOAD3D_H
+#define GUARD_GX_LOAD3D_H
+
+void GX_BeginLoadTex();
+void GX_LoadTex(void *src, u32 offset, u32 size);
+void GX_EndLoadTex();
+void GX_BeginLoadTexPltt();
+void GX_LoadTexPltt(void *src, u32 offset, u32 size);
+void GX_EndLoadTexPltt();
+void GX_BeginLoadClearImage();
+void GX_LoadClearImageColor(void *src, u32 size);
+void GX_LoadClearImageDepth(void *src, u32 size);
+void GX_EndLoadClearImage();
+
+#endif //GUARD_GX_LOAD3D_H
diff --git a/arm9/lib/include/GX_state.h b/arm9/lib/include/GX_state.h
new file mode 100644
index 00000000..c94b6c07
--- /dev/null
+++ b/arm9/lib/include/GX_state.h
@@ -0,0 +1,24 @@
+#ifndef GUARD_GX_STATE_H
+#define GUARD_GX_STATE_H
+
+struct GX_State
+{
+ u16 lcdc;
+ u16 bg;
+ u16 obj;
+ u16 arm7;
+ u16 tex;
+ u16 texPltt;
+ u16 clrImg;
+ u16 bgExtPltt;
+ u16 objExtPltt;
+
+ u16 sub_bg;
+ u16 sub_obj;
+ u16 sub_bgExtPltt;
+ u16 sub_objExtPltt;
+};
+
+void GX_InitGXState();
+
+#endif //GUARD_GX_STATE_H
diff --git a/arm9/lib/include/GX_struct_2d.h b/arm9/lib/include/GX_struct_2d.h
new file mode 100644
index 00000000..3b544927
--- /dev/null
+++ b/arm9/lib/include/GX_struct_2d.h
@@ -0,0 +1,243 @@
+#ifndef GUARD_GX_STRUCT_2D_H
+#define GUARD_GX_STRUCT_2D_H
+
+typedef u16 GXScrFmtText;
+#define GX_SCRFMT_TEXT_CHARNAME_SHIFT (0)
+#define GX_SCRFMT_TEXT_CHARNAME_MASK (0x03ff)
+#define GX_SCRFMT_TEXT_HF_SHIFT (10)
+#define GX_SCRFMT_TEXT_HF_MASK (0x0400)
+#define GX_SCRFMT_TEXT_VF_SHIFT (11)
+#define GX_SCRFMT_TEXT_VF_MASK (0x0800)
+#define GX_SCRFMT_TEXT_COLORPLTT_SHIFT (12)
+#define GX_SCRFMT_TEXT_COLORPLTT_MASK (0xf000)
+#define GX_SCRFMT_TEXT(pltt, vf, hf, name) \
+ ((u16)(((name) << GX_SCRFMT_TEXT_CHARNAME_SHIFT) | \
+ ((hf) << GX_SCRFMT_TEXT_HF_SHIFT) | \
+ ((vf) << GX_SCRFMT_TEXT_VF_SHIFT) | \
+ ((pltt) << GX_SCRFMT_TEXT_COLORPLTT_SHIFT)))
+
+typedef u8 GXScrFmtAffine;
+#define GX_SCRFMT_AFFINE_CHARNAME_SHIFT (0)
+#define GX_SCRFMT_AFFINE_CHARNAME_MASK (0xff)
+
+typedef u8 GXScrFmt256Bmp;
+#define GX_SCRFMT_256BMP_COLORNO_SHIFT (0)
+#define GX_SCRFMT_256BMP_COLORNO_MASK (0xff)
+
+typedef union
+{
+ u32 data32[8];
+ u16 data16[16];
+ u8 data8[32];
+}
+GXCharFmt16;
+
+typedef union
+{
+ u32 data32[16];
+ u16 data16[32];
+ u8 data8[64];
+}
+GXCharFmt256;
+
+typedef union
+{
+ u16 data16[16];
+ u32 data32[8];
+ GXRgb rgb[16];
+}
+GXBGPltt16;
+
+typedef GXBGPltt16 GXOBJPltt16;
+
+typedef union
+{
+ u16 data16[256];
+ u32 data32[128];
+ GXRgb rgb[256];
+}
+GXBGPltt256;
+
+typedef GXBGPltt256 GXOBJPltt256;
+
+typedef union
+{
+ u16 data16[32 * 32];
+ u32 data32[32 * 32 / 2];
+ GXScrFmtText scr[32][32];
+}
+GXScrText32x32;
+
+typedef union
+{
+ u16 data16[64 * 32];
+ u32 data32[64 * 32 / 2];
+ GXScrFmtText scr[64][32];
+}
+GXScrText64x32;
+
+typedef union
+{
+ // 4K bytes
+ u16 data16[32 * 64];
+ u32 data32[32 * 64 / 2];
+ GXScrFmtText scr[32][64];
+}
+GXScrText32x64;
+
+typedef union
+{
+ u16 data16[64 * 64];
+ u32 data32[64 * 64 / 2];
+ GXScrFmtText scr[64][64];
+}
+GXScrText64x64;
+
+typedef union
+{
+ u8 data8[16 * 16];
+ u32 data32[16 * 16 / 4];
+ GXScrFmtAffine scr[16][16];
+}
+GXScrAffine16x16;
+
+typedef union
+{
+ u8 data8[32 * 32];
+ u32 data32[32 * 32 / 4];
+ GXScrFmtAffine scr[32][32];
+}
+GXScrAffine32x32;
+
+typedef union
+{
+ u8 data8[64 * 64];
+ u32 data32[64 * 64 / 4];
+ GXScrFmtAffine scr[64][64];
+}
+GXScrAffine64x64;
+
+typedef union
+{
+ u8 data8[128 * 128];
+ u32 data32[128 * 128 / 4];
+ GXScrFmtAffine scr[128][128];
+}
+GXScrAffine128x128;
+
+typedef union
+{
+ u8 data8[128 * 128];
+ u32 data32[128 * 128 / 4];
+ GXScrFmt256Bmp scr[128][128];
+}
+GXScr256Bmp128x128;
+
+typedef union
+{
+ u8 data8[256 * 256];
+ u32 data32[256 * 256 / 4];
+ GXScrFmt256Bmp scr[256][256];
+}
+GXScr256Bmp256x256;
+
+typedef union
+{
+ u8 data8[512 * 256];
+ u32 data32[512 * 256 / 4];
+ GXScrFmt256Bmp scr[512][256];
+}
+GXScr256Bmp512x256;
+
+typedef union
+{
+ u8 data8[512 * 512];
+ u32 data32[512 * 512 / 4];
+ GXScrFmt256Bmp scr[512][512];
+}
+GXScr256Bmp512x512;
+
+typedef union
+{
+ u16 data16[128 * 128];
+ u32 data32[128 * 128 / 2];
+ GXRgba scr[128][128];
+}
+GXScrDCBmp128x128;
+
+typedef union
+{
+ u16 data16[256 * 256];
+ u32 data32[256 * 256 / 2];
+ GXRgba scr[256][256];
+}
+GXScrDCBmp256x256;
+
+typedef union
+{
+ u16 data16[512 * 256];
+ u32 data32[512 * 256 / 2];
+ GXRgba scr[512][256];
+}
+GXScrDCBmp512x256;
+
+typedef union
+{
+ u16 data16[512 * 512];
+ u32 data32[512 * 512 / 2];
+ GXRgba scr[512][512];
+}
+GXScrDCBmp512x512;
+
+typedef struct
+{
+ GXCharFmt16 ch[1024];
+}
+GXCharBGText16;
+
+typedef struct
+{
+ GXCharFmt256 ch[1024];
+}
+GXCharBGText256;
+
+typedef struct
+{
+ GXCharFmt256 ch[256];
+}
+GXCharBGAffine256;
+
+typedef union
+{
+ GXBGPltt256 pltt256;
+ GXBGPltt16 pltt16[16];
+}
+GXBGStdPlttData;
+
+typedef union
+{
+ GXOBJPltt256 pltt256;
+ GXOBJPltt16 pltt16[16];
+}
+GXOBJStdPlttData;
+
+typedef struct
+{
+ GXBGStdPlttData bgPltt;
+ GXOBJStdPlttData objPltt;
+}
+GXStdPlttData;
+
+typedef struct
+{
+ GXBGPltt256 pltt256[16];
+}
+GXBGExtPlttData;
+
+typedef struct
+{
+ GXOBJPltt256 pltt256[16];
+}
+GXOBJExtPlttData;
+
+#endif //GUARD_GX_STRUCT_2D_H
diff --git a/arm9/lib/include/GX_vramcnt.h b/arm9/lib/include/GX_vramcnt.h
new file mode 100644
index 00000000..6fe677bc
--- /dev/null
+++ b/arm9/lib/include/GX_vramcnt.h
@@ -0,0 +1,57 @@
+#ifndef GUARD_GX_VRAMCNT_H
+#define GUARD_GX_VRAMCNT_H
+
+//some of the symbols don't match what the function does
+void GX_VRAMCNT_SetLCDC_(u32 mask);
+void GX_SetBankForBG(s32 bg);
+void GX_SetBankForOBJ(s32 obj);
+void GX_SetBankForBGExtPltt(s32 bgextpltt);
+void GX_SetBankForOBJExtPltt(s32 objextpltt);
+void GX_SetBankForTex(s32 tex);
+void GX_SetBankForTexPltt(s32 texpltt);
+void GX_SetBankForClearImage(s32 clearimage);
+void GX_SetBankForARM7(s32 arm7);
+void GX_SetBankForLCDC(s32 lcdc);
+void GX_SetBankForSubBG(s32 subbg);
+void GX_SetBankForSubOBJ(s32 subobj);
+void GX_SetBankForSubBGExtPltt(s32 subbgextpltt);
+void GX_SetBankForSubOBJExtPltt(s32 subobjextpltt);
+u32 FUN_020C6130(u16 *ptr);
+u32 GX_ResetBankForBG();
+u32 GX_ResetBankForOBJ();
+u32 GX_ResetBankForBGExtPltt();
+u32 GX_ResetBankForOBJExtPltt();
+u32 GX_ResetBankForTex();
+u32 GX_ResetBankForTexPltt();
+u32 GX_ResetBankForClearImage();
+u32 GX_ResetBankForSubBG();
+u32 FUN_020C605C();
+u32 FUN_020C6034();
+u32 GX_ResetBankForSubOBJ();
+u32 FUN_020C5F28(u16 *ptr);
+u32 disableBankForX_();
+u32 GX_DisableBankForOBJExtPltt_2();
+u32 GX_DisableBankForBGExtPltt();
+u32 GX_DisableBankForOBJExtPltt();
+u32 GX_DisableBankForTexPltt_2();
+u32 GX_DisableBankForTexPltt();
+u32 GX_DisableBankForClearImage();
+u32 GX_DisableBankForARM7();
+u32 GX_DisableBankForLCDC();
+u32 GX_DisableBankForSubBGExtPltt();
+u32 GX_DisableBankForSubOBJExtPltt_2();
+u32 FUN_020C5E04();
+u32 GX_DisableBankForSubOBJExtPltt();
+u32 GX_GetBankForBGExtPltt_2();
+u32 GX_GetBankForOBJ();
+u32 GX_GetBankForBGExtPltt();
+u32 GX_GetBankForOBJExtPltt();
+u32 FUN_020C5D8C();
+u32 GX_GetBankForTexPltt();
+u32 GX_GetBankForLCDC();
+u32 GX_GetBankForSubBGExtPltt_2();
+u32 GX_GetBankForSubOBJ();
+u32 GX_GetBankForSubBGExtPltt();
+u32 GX_GetBankForSubOBJExtPltt();
+
+#endif //GUARD_GX_VRAMCNT_H
diff --git a/arm9/lib/include/GXcommon.h b/arm9/lib/include/GXcommon.h
new file mode 100644
index 00000000..a83f4384
--- /dev/null
+++ b/arm9/lib/include/GXcommon.h
@@ -0,0 +1,29 @@
+#ifndef GUARD_GXCOMMON_H
+#define GUARD_GXCOMMON_H
+
+typedef u16 GXRgb;
+#define GXRGB_ASSERT(gxrgb) SDK_ASSERT(((gxrgb) & 0x8000) == 0)
+#define GX_RGB_R_SHIFT (0)
+#define GX_RGB_R_MASK (0x001f)
+#define GX_RGB_G_SHIFT (5)
+#define GX_RGB_G_MASK (0x03e0)
+#define GX_RGB_B_SHIFT (10)
+#define GX_RGB_B_MASK (0x7c00)
+#define GX_RGB(r, g, b) ((GXRgb)(((r) << GX_RGB_R_SHIFT) | \
+ ((g) << GX_RGB_G_SHIFT) | \
+ ((b) << GX_RGB_B_SHIFT)))
+
+typedef u16 GXRgba;
+#define GX_RGBA_R_SHIFT (0)
+#define GX_RGBA_R_MASK (0x001f)
+#define GX_RGBA_G_SHIFT (5)
+#define GX_RGBA_G_MASK (0x03e0)
+#define GX_RGBA_B_SHIFT (10)
+#define GX_RGBA_B_MASK (0x7c00)
+#define GX_RGBA_A_SHIFT (15)
+#define GX_RGBA_A_MASK (0x8000)
+#define GX_RGBA(r, g, b, a) ((GXRgba)(((r) << GX_RGBA_R_SHIFT) | \
+ ((g) << GX_RGBA_G_SHIFT) | \
+ ((b) << GX_RGBA_B_SHIFT) | \
+ ((a) << GX_RGBA_A_SHIFT)))
+#endif //GUARD_GXCOMMON_H
diff --git a/arm9/lib/include/OS_alarm.h b/arm9/lib/include/OS_alarm.h
new file mode 100644
index 00000000..6971248a
--- /dev/null
+++ b/arm9/lib/include/OS_alarm.h
@@ -0,0 +1,27 @@
+//
+// Created by red031000 on 2020-05-17.
+//
+
+#ifndef POKEDIAMOND_OS_ALARM_H
+#define POKEDIAMOND_OS_ALARM_H
+
+#include "types.h"
+#include "OS_thread.h"
+
+typedef void (*OSAlarmHandler) (void *);
+
+struct OSiAlarm
+{
+ OSAlarmHandler handler;
+ void *arg;
+
+ u32 tag;
+ OSTick fire;
+ OSAlarm *prev;
+ OSAlarm *next;
+
+ OSTick period;
+ OSTick start;
+};
+
+#endif //POKEDIAMOND_OS_ALARM_H
diff --git a/arm9/lib/include/OS_context.h b/arm9/lib/include/OS_context.h
new file mode 100644
index 00000000..c0ab62f1
--- /dev/null
+++ b/arm9/lib/include/OS_context.h
@@ -0,0 +1,22 @@
+//
+// Created by red031000 on 2020-05-17.
+//
+
+#ifndef POKEDIAMOND_OS_CONTEXT_H
+#define POKEDIAMOND_OS_CONTEXT_H
+
+#include "types.h"
+#include "CP_context.h"
+
+typedef struct OSContext
+{
+ u32 cpsr;
+ u32 r[13];
+ u32 sp;
+ u32 lr;
+ u32 pc_plus4;
+ u32 sp_svc;
+ CPContext cp_context;
+} OSContext;
+
+#endif //POKEDIAMOND_OS_CONTEXT_H
diff --git a/arm9/lib/include/OS_init.h b/arm9/lib/include/OS_init.h
index dd2b20c7..a998b45e 100644
--- a/arm9/lib/include/OS_init.h
+++ b/arm9/lib/include/OS_init.h
@@ -9,6 +9,10 @@
#include "consts.h"
#include "OS_tcm.h"
#include "OS_spinLock.h"
+#include "OS_context.h"
+#include "OS_tick.h"
+#include "OS_alarm.h"
+#include "OS_mutex.h"
#include "OS_thread.h"
#include "OS_protectionRegion.h"
#include "OS_entropy.h"
diff --git a/arm9/lib/include/OS_interrupt.h b/arm9/lib/include/OS_interrupt.h
index 21ce2ea0..21ae8079 100644
--- a/arm9/lib/include/OS_interrupt.h
+++ b/arm9/lib/include/OS_interrupt.h
@@ -26,5 +26,10 @@ void OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function);
OSIrqFunction OS_GetIrqFunction(OSIrqMask intrBit);
void OSi_EnterDmaCallback(u32 dmaNo, void (*callback) (void *), void *arg);
void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg);
+OSIrqMask OS_SetIrqMask(OSIrqMask mask);
+OSIrqMask OS_EnableIrqMask(OSIrqMask mask);
+OSIrqMask OS_DisableIrqMask(OSIrqMask mask);
+OSIrqMask OS_ResetRequestIrqMask(OSIrqMask mask);
+void OS_SetIrqStackChecker(void);
#endif //POKEDIAMOND_OS_INTERRUPT_H
diff --git a/arm9/lib/include/OS_mutex.h b/arm9/lib/include/OS_mutex.h
new file mode 100644
index 00000000..5db66fbe
--- /dev/null
+++ b/arm9/lib/include/OS_mutex.h
@@ -0,0 +1,18 @@
+//
+// Created by red031000 on 2020-05-17.
+//
+
+#ifndef POKEDIAMOND_OS_MUTEX_H
+#define POKEDIAMOND_OS_MUTEX_H
+
+#include "types.h"
+#include "OS_thread.h"
+
+struct OSMutex {
+ OSThreadQueue queue;
+ OSThread *thread;
+ s32 count;
+ OSMutexLink link;
+};
+
+#endif //POKEDIAMOND_OS_MUTEX_H
diff --git a/arm9/lib/include/OS_thread.h b/arm9/lib/include/OS_thread.h
index 15cec0c9..adcadf2e 100644
--- a/arm9/lib/include/OS_thread.h
+++ b/arm9/lib/include/OS_thread.h
@@ -5,15 +5,42 @@
#ifndef POKEDIAMOND_OS_THREAD_H
#define POKEDIAMOND_OS_THREAD_H
+#include "types.h"
+#include "OS_context.h"
+
+typedef struct OSiAlarm OSAlarm;
+
typedef struct _OSThread OSThread;
+typedef struct _OSThreadQueue OSThreadQueue;
+typedef struct _OSThreadLink OSThreadLink;
+typedef struct _OSMutexQueue OSMutexQueue;
+typedef struct _OSMutexLink OSMutexLink;
+typedef struct OSMutex OSMutex;
+
struct _OSThreadQueue
{
OSThread *head;
OSThread *tail;
};
-typedef struct _OSThreadQueue OSThreadQueue;
+struct _OSThreadLink
+{
+ OSThread *prev;
+ OSThread *next;
+};
+
+struct _OSMutexQueue
+{
+ OSMutex *head;
+ OSMutex *tail;
+};
+
+struct _OSMutexLink
+{
+ OSMutex *next;
+ OSMutex *prev;
+};
typedef struct OSThreadInfo {
u16 isNeedRescheduling;
@@ -23,9 +50,41 @@ typedef struct OSThreadInfo {
void* switchCallback; // type: OSSwitchThreadCallback
} OSThreadInfo;
+typedef enum {
+ OS_THREAD_STATE_WAITING = 0,
+ OS_THREAD_STATE_READY = 1,
+ OS_THREAD_STATE_TERMINATED = 2
+} OSThreadState;
+
+typedef void (*OSThreadDestructor) (void *);
+
struct _OSThread
{
- u8 padding[0x80]; //todo: not the correct size but idfk
+ OSContext context;
+ OSThreadState state;
+ OSThread *next;
+ u32 id;
+ u32 priority;
+ void *profiler;
+
+ OSThreadQueue *queue;
+ OSThreadLink link;
+
+ OSMutex *mutex;
+ OSMutexQueue mutexQueue;
+
+ u32 stackTop;
+ u32 stackBottom;
+ u32 stackWarningOffset;
+
+ OSThreadQueue joinQueue;
+
+ void *specific[3];
+ OSAlarm *alarmForSleep;
+ OSThreadDestructor destructor;
+ void *userParameter;
+
+ u32 systemErrno;
};
void OS_SleepThread(OSThreadQueue * queue);
diff --git a/arm9/lib/include/OS_tick.h b/arm9/lib/include/OS_tick.h
new file mode 100644
index 00000000..fbb8ce9e
--- /dev/null
+++ b/arm9/lib/include/OS_tick.h
@@ -0,0 +1,12 @@
+//
+// Created by red031000 on 2020-05-17.
+//
+
+#ifndef POKEDIAMOND_OS_TICK_H
+#define POKEDIAMOND_OS_TICK_H
+
+#include "types.h"
+
+typedef u64 OSTick;
+
+#endif //POKEDIAMOND_OS_TICK_H
diff --git a/arm9/lib/include/fx.h b/arm9/lib/include/fx.h
index b1c3aa88..e0ba52f3 100644
--- a/arm9/lib/include/fx.h
+++ b/arm9/lib/include/fx.h
@@ -46,10 +46,14 @@ typedef s64 fx64c;
#define FX64C_INT_ABS(x) FX_INT_ABS(FX64C, x)
#define FX64C_FRAC(x) FX_FRAC(FX64C, x)
-#define FX32_MUL(a, b) ((fx32)(((fx64)a * b) >> FX32_INT_SHIFT))
-#define FX32_MUL_ADD_MUL(a, b, c, d) ((fx32)(((fx64)a * b + (fx64)c * d) >> FX32_INT_SHIFT))
+//TODO: clean up these macros
+#define FX32_MUL_NO_ROUND(a, b) ((fx32)(((fx64)(a) * (b)) >> FX32_INT_SHIFT))
+#define FX32_MUL(a, b) ((fx32)((((fx64)(a) * (b) + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT)))
+#define FX32_MUL_ADD_MUL(a, b, c, d) ((fx32)(((fx64)(a) * (b) + (fx64)c * d) >> FX32_INT_SHIFT))
//the extra term here is for rounding
-#define FX32_MUL_SUB_MUL(a, b, c, d) ((fx32)(((fx64)a * b - (fx64)c * d + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT))
+#define FX32_MUL_SUB_MUL(a, b, c, d) ((fx32)(((fx64)(a) * (b) - (fx64)c * d + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT))
+
+#define FX_MUL_FX32_FX64C(a, b) ((fx32)((((a) * (b) + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT)))
struct Vecx32
{
diff --git a/arm9/lib/include/gx.h b/arm9/lib/include/gx.h
new file mode 100644
index 00000000..8abe4e40
--- /dev/null
+++ b/arm9/lib/include/gx.h
@@ -0,0 +1,179 @@
+#ifndef GUARD_GX_H
+#define GUARD_GX_H
+
+#include "fx.h"
+
+//temporary while other files aren't decompiled
+
+void GXi_NopClearFifo128_(void *);
+void MI_Copy16B(const void *, void *);
+void MI_DmaFill32Async(u32, void *, u32, u32, u32, u32);
+void MI_DmaFill32(u32, void *, u32, u32);
+void MIi_CpuClear32(u32, void *, u32);
+void MI_Copy64B(void *src, void *dst);
+void MI_WaitDma(u32);
+void MI_DmaCopy32Async(u32, const void *, void *, u32, void *, void *);
+void MI_DmaCopy16(u32 unk, const void *src, void *dst, u32 size);
+void MIi_CpuCopy16(const void *src, void *dst, u32 size);
+void MI_DmaCopy32(u32 unk, const void *src, void *dst, u32 size);
+void MIi_CpuCopy32(const void *src, void *dst, u32 size);
+void OSi_UnlockVram(u16, u16);
+void MIi_CpuClear32(u32, void *, u32);
+
+#include "GXcommon.h"
+#include "GX_struct_2d.h"
+#include "GX_g3.h"
+#include "GX_g3_util.h"
+#include "GX_g3x.h"
+#include "GX_g3b.h"
+#include "GX_asm.h"
+#include "GX_vramcnt.h"
+#include "GX_bgcnt.h"
+#include "GX_load2d.h"
+#include "GX_load3d.h"
+#include "GX_g2.h"
+#include "GX_state.h"
+#include "GX_g3imm.h"
+#include "GX_dma.h"
+
+void GX_Init();
+u32 GX_HBlankIntr(u32 enable);
+u32 GX_VBlankIntr(u32 enable);
+void GX_DispOff();
+void GX_DispOn();
+void GX_SetGraphicsMode(u32 mode1, u32 mode2, u32 mode3);
+void GXS_SetGraphicsMode(u32 mode);
+void GXx_SetMasterBrightness_(vu16 *dst, s32 brightness);
+
+typedef union
+{
+ u32 raw;
+ struct
+ {
+ u32 bgMode:3;
+ u32 bg0_2d3d:1;
+ u32 objMapChar:1;
+ u32 objMapBmp:2;
+ u32 blankScr:1;
+ u32 visiblePlane:5;
+ u32 visibleWnd:3;
+ u32 dispMode:4;
+ u32 extObjMapChar:2;
+ u32 extObjMapBmp:1;
+ u32 hBlankObjProc:1;
+ u32 bgCharOffset:3;
+ u32 bgScrOffset:3;
+ u32 bgExtPltt:1;
+ u32 objExtPltt:1;
+ };
+}
+GXDispCnt;
+
+typedef union
+{
+ u32 raw;
+ struct
+ {
+ u32 bgMode:3;
+ u32 _reserve1:1;
+ u32 objMapChar:1;
+ u32 objMapBmp:2;
+ u32 blankScr:1;
+ u32 visiblePlane:5;
+ u32 visibleWnd:3;
+ u32 dispMode:1;
+ u32 _reserve2:3;
+ u32 extObjMapChar:2;
+ u32 _reserve3:1;
+ u32 hBlankObjProc:1;
+ u32 _reserve4:6;
+ u32 bgExtPltt:1;
+ u32 objExtPltt:1;
+ };
+}
+GXSDispCnt;
+
+typedef enum
+{
+ GX_BGMODE_0 = 0,
+ GX_BGMODE_1 = 1,
+ GX_BGMODE_2 = 2,
+ GX_BGMODE_3 = 3,
+ GX_BGMODE_4 = 4,
+ GX_BGMODE_5 = 5,
+ GX_BGMODE_6 = 6
+}
+GXBGMode;
+
+typedef enum
+{
+ GX_BG0_AS_2D = 0,
+ GX_BG0_AS_3D = 1
+}
+GXBG0As;
+
+typedef enum
+{
+ GX_DISPMODE_GRAPHICS = 0x01,
+ GX_DISPMODE_VRAM_A = 0x02,
+ GX_DISPMODE_VRAM_B = 0x06,
+ GX_DISPMODE_VRAM_C = 0x0a,
+ GX_DISPMODE_VRAM_D = 0x0e,
+ GX_DISPMODE_MMEM = 0x03
+}
+GXDispMode;
+
+typedef enum
+{
+ GX_PLANEMASK_NONE = 0x00,
+ GX_PLANEMASK_BG0 = 0x01,
+ GX_PLANEMASK_BG1 = 0x02,
+ GX_PLANEMASK_BG2 = 0x04,
+ GX_PLANEMASK_BG3 = 0x08,
+ GX_PLANEMASK_OBJ = 0x10
+}
+GXPlaneMask;
+
+typedef enum
+{
+ GX_WNDMASK_NONE = 0x00,
+ GX_WNDMASK_W0 = 0x01,
+ GX_WNDMASK_W1 = 0x02,
+ GX_WNDMASK_OW = 0x04
+}
+GXWndMask;
+
+typedef enum
+{
+ GX_BGCHAROFFSET_0x00000 = 0x00,
+ GX_BGCHAROFFSET_0x10000 = 0x01,
+ GX_BGCHAROFFSET_0x20000 = 0x02,
+ GX_BGCHAROFFSET_0x30000 = 0x03,
+ GX_BGCHAROFFSET_0x40000 = 0x04,
+ GX_BGCHAROFFSET_0x50000 = 0x05,
+ GX_BGCHAROFFSET_0x60000 = 0x06,
+ GX_BGCHAROFFSET_0x70000 = 0x07
+}
+GXBGCharOffset;
+
+typedef enum
+{
+ GX_BGSCROFFSET_0x00000 = 0x00,
+ GX_BGSCROFFSET_0x10000 = 0x01,
+ GX_BGSCROFFSET_0x20000 = 0x02,
+ GX_BGSCROFFSET_0x30000 = 0x03,
+ GX_BGSCROFFSET_0x40000 = 0x04,
+ GX_BGSCROFFSET_0x50000 = 0x05,
+ GX_BGSCROFFSET_0x60000 = 0x06,
+ GX_BGSCROFFSET_0x70000 = 0x07
+}
+GXBGScrOffset;
+
+typedef enum
+{
+ GX_DISP_SELECT_SUB_MAIN = 0,
+ GX_DISP_SELECT_MAIN_SUB = 1
+}
+GXDispSelect;
+
+#endif //GUARD_GX_H
diff --git a/arm9/lib/src/GX.c b/arm9/lib/src/GX.c
new file mode 100644
index 00000000..28c3cc01
--- /dev/null
+++ b/arm9/lib/src/GX.c
@@ -0,0 +1,121 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+extern u16 GXi_VRamLockId;
+extern u16 sDispMode;
+extern u32 GXi_DmaId;
+extern u16 sIsDispOn;
+
+ARM_FUNC void GX_Init(){
+ reg_GX_POWCNT |= 0x8000;
+ reg_GX_POWCNT = (reg_GX_POWCNT & ~0x20E) | 0x20E;
+ reg_GX_POWCNT = reg_GX_POWCNT | 0x1;
+ GX_InitGXState();
+ u32 temp;
+ while (GXi_VRamLockId == 0)
+ {
+ temp = OS_GetLockID();
+ if (temp == -3)
+ {
+ OS_Terminate();
+ }
+ GXi_VRamLockId = temp;
+ }
+ reg_GX_DISPSTAT = 0x0;
+ reg_GX_DISPCNT = 0x0;
+ if (GXi_DmaId != -1)
+ {
+ MI_DmaFill32(GXi_DmaId, (void *)&reg_G2_BG0CNT, 0x0, 0x60);
+ reg_GX_MASTER_BRIGHT = 0x0;
+ MI_DmaFill32(GXi_DmaId, (void *)&reg_GXS_DB_DISPCNT, 0x0, 0x70);
+ }
+ else
+ {
+ MIi_CpuClear32(0x0, (void *)&reg_G2_BG0CNT, 0x60);
+ reg_GX_MASTER_BRIGHT = 0x0;
+ MIi_CpuClear32(0x0, (void *)&reg_GXS_DB_DISPCNT, 0x70);
+ }
+ reg_G2_BG2PA = 0x100;
+ reg_G2_BG2PD = 0x100;
+ reg_G2_BG3PA = 0x100;
+ reg_G2_BG3PD = 0x100;
+ reg_G2S_DB_BG2PA = 0x100;
+ reg_G2S_DB_BG2PD = 0x100;
+ reg_G2S_DB_BG3PA = 0x100;
+ reg_G2S_DB_BG3PD = 0x100;
+}
+
+ARM_FUNC u32 GX_HBlankIntr(u32 enable){
+ u32 temp = reg_GX_DISPSTAT & 0x10;
+ if (enable)
+ {
+ reg_GX_DISPSTAT |= 0x10;
+ }
+ else
+ {
+ reg_GX_DISPSTAT &= ~0x10;
+ }
+ return temp;
+}
+
+ARM_FUNC u32 GX_VBlankIntr(u32 enable){
+ u32 temp = reg_GX_DISPSTAT & 0x8;
+ if (enable)
+ {
+ reg_GX_DISPSTAT |= 0x8;
+ }
+ else
+ {
+ reg_GX_DISPSTAT &= ~0x8;
+ }
+ return temp;
+}
+
+ARM_FUNC void GX_DispOff(){
+ u32 temp = reg_GX_DISPCNT;
+ sIsDispOn = 0x0;
+ sDispMode = (temp & 0x30000) >> 0x10;
+ reg_GX_DISPCNT = temp & ~0x30000;
+}
+
+ARM_FUNC void GX_DispOn(){
+ sIsDispOn = 0x1;
+ if (sDispMode)
+ {
+ reg_GX_DISPCNT = reg_GX_DISPCNT & ~0x30000 | (sDispMode << 0x10);
+ }
+ else
+ {
+ reg_GX_DISPCNT = reg_GX_DISPCNT | 0x10000;
+ }
+}
+
+ARM_FUNC void GX_SetGraphicsMode(u32 mode1, u32 mode2, u32 mode3){
+ u32 temp2 = reg_GX_DISPCNT;
+ sDispMode = mode1;
+ if (!sIsDispOn)
+ mode1 = 0;
+ reg_GX_DISPCNT = (mode2 | ((temp2 & 0xFFF0FFF0) | (mode1 << 0x10))) | (mode3 << 0x3);
+ if (!sDispMode)
+ sIsDispOn = 0x0;
+}
+
+ARM_FUNC void GXS_SetGraphicsMode(u32 mode){
+ reg_GXS_DB_DISPCNT = reg_GXS_DB_DISPCNT & ~0x7 | mode;
+}
+
+ARM_FUNC void GXx_SetMasterBrightness_(vu16 *dst, s32 brightness){
+ if (!brightness)
+ {
+ *dst = 0x0;
+ }
+ else if (brightness > 0)
+ {
+ *dst = 0x4000 | brightness;
+ }
+ else
+ {
+ *dst = 0x8000 | -brightness;
+ }
+}
diff --git a/arm9/lib/src/GX_asm.c b/arm9/lib/src/GX_asm.c
new file mode 100644
index 00000000..f40793d8
--- /dev/null
+++ b/arm9/lib/src/GX_asm.c
@@ -0,0 +1,16 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+//looks like asm and says asm on the tin...
+ARM_FUNC asm void GX_SendFifo48B(void *src, void *dst){
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ ldmia r0!, {r2-r3,r12}
+ stmia r1, {r2-r3,r12}
+ bx lr
+}
diff --git a/arm9/lib/src/GX_bgcnt.c b/arm9/lib/src/GX_bgcnt.c
new file mode 100644
index 00000000..2086ad16
--- /dev/null
+++ b/arm9/lib/src/GX_bgcnt.c
@@ -0,0 +1,195 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+ARM_FUNC void *G2_GetBG0ScrPtr(){
+ u32 temp = (((reg_G2_BG0CNT & 0x1F00) >> 0x8) << 0xB);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG0ScrPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG0CNT & 0x1F00) >> 0x8) << 0xB));
+}
+
+ARM_FUNC void *G2_GetBG1ScrPtr(){
+ u32 temp = (((reg_G2_BG1CNT & 0x1F00) >> 0x8) << 0xB);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG1ScrPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG1CNT & 0x1F00) >> 0x8) << 0xB));
+}
+
+ARM_FUNC void *G2_GetBG2ScrPtr(){
+ u32 temp12 = (reg_GX_DISPCNT & 0x7);
+ u32 temp3 = reg_G2_BG2CNT;
+ u32 temp2 = (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6000000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 6:
+ return (void *)0x6000000;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG2ScrPtr(){
+ u32 temp12 = (reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp3 = reg_G2S_DB_BG2CNT;
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6200000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG3ScrPtr(){
+ u32 temp12 = (reg_GX_DISPCNT & 0x7);
+ u32 temp3 = reg_G2_BG3CNT;
+ u32 temp2 = (((reg_GX_DISPCNT & 0x38000000) >> 0x1B) << 0x10);
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 3:
+ case 4:
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6000000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6000000 + temp2 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG3ScrPtr(){
+ u32 temp12 = (reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp3 = reg_G2S_DB_BG3CNT;
+ u32 temp1 = ((temp3 & 0x1F00) >> 0x8);
+ switch (temp12)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 3:
+ case 4:
+ case 5:
+ if (temp3 & 0x80)
+ return (void *)(0x6200000 + (temp1 << 0xE));
+ else
+ return (void *)(0x6200000 + (temp1 << 0xB));
+ case 6:
+ return NULL;
+ default:
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG0CharPtr(){
+ u32 temp = (((reg_G2_BG0CNT & 0x3C) >> 0x2) << 0xE);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG0CharPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG0CNT & 0x3C) >> 0x2) << 0xE));
+}
+
+ARM_FUNC void *G2_GetBG1CharPtr(){
+ u32 temp = (((reg_G2_BG1CNT & 0x3C) >> 0x2) << 0xE);
+ return (void *)(0x6000000 + (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10) + temp);
+}
+
+ARM_FUNC void *G2S_GetBG1CharPtr(){
+ return (void *)(0x6200000 + (((reg_G2S_DB_BG1CNT & 0x3C) >> 0x2) << 0xE));
+}
+
+ARM_FUNC void *G2_GetBG2CharPtr(){
+ s32 temp1 = (reg_GX_DISPCNT & 0x7);
+ u32 temp = reg_G2_BG2CNT;
+ if (temp1 < 5 || !(temp & 0x80))
+ {
+ u32 temp1 = (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10);
+ u32 temp2 = (temp & 0x3C) >> 2;
+ return (void *)(0x6000000 + temp1 + (temp2 << 0xE));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG2CharPtr(){
+ s32 temp1 = (reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp = reg_G2S_DB_BG2CNT;
+ if (temp1 < 5 || !(temp & 0x80))
+ {
+ u32 temp2 = ((temp & 0x3C) >> 2) << 0xE;
+ return (void *)(0x6200000 + temp2);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2_GetBG3CharPtr(){
+ s32 temp1 = (reg_GX_DISPCNT & 0x7);
+ u32 temp = reg_G2_BG3CNT;
+ if (temp1 < 3 || (temp1 < 6 && !(temp & 0x80)))
+ {
+ u32 temp1 = (((reg_GX_DISPCNT & 0x7000000) >> 0x18) << 0x10);
+ u32 temp2 = (temp & 0x3C) >> 2;
+ return (void *)(0x6000000 + temp1 + (temp2 << 0xE));
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ARM_FUNC void *G2S_GetBG3CharPtr(){
+ s32 temp1 = (reg_GXS_DB_DISPCNT & 0x7);
+ u32 temp = reg_G2S_DB_BG3CNT;
+ if (temp1 < 3 || (temp1 < 6 && !(temp & 0x80)))
+ {
+ u32 temp2 = ((temp & 0x3C) >> 2) << 0xE;
+ return (void *)(0x6200000 + temp2);
+ }
+ else
+ {
+ return NULL;
+ }
+}
diff --git a/arm9/lib/src/GX_g2.c b/arm9/lib/src/GX_g2.c
new file mode 100644
index 00000000..66273541
--- /dev/null
+++ b/arm9/lib/src/GX_g2.c
@@ -0,0 +1,66 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+ARM_FUNC void G2x_SetBGyAffine_(u32 *ptr, struct Mtx22 *mtx, fx32 a, fx32 b, fx32 c, fx32 d){
+ fx32 temp0, temp1, temp2, temp3;
+ ptr[0] = ((u16)(fx16)(mtx->_[0] >> 4) | (u16)(fx16)(mtx->_[1] >> 4)<< 0x10);
+ ptr[1] = ((u16)(fx16)(mtx->_[2] >> 4) | (u16)(fx16)(mtx->_[3] >> 4)<< 0x10);
+ temp0 = c - a;
+ temp1 = d - b;
+ temp2 = mtx->_[0] * temp0 + mtx->_[1] * temp1 + (a << 0xC);
+ temp3 = mtx->_[2] * temp0 + mtx->_[3] * temp1 + (b << 0xC);
+ ptr[2] = temp2 >> 4;
+ ptr[3] = temp3 >> 4;
+}
+
+ARM_FUNC void G2x_SetBlendAlpha_(u32 *ptr, fx32 a, fx32 b, fx32 c, fx32 d){
+ *ptr = ((a | 0x40) | (b << 0x8)) | ((c | (d << 0x8)) << 0x10);
+}
+
+ARM_FUNC void G2x_SetBlendBrightness_(u16 *ptr, fx32 a, fx32 brightness){
+ if (brightness < 0)
+ {
+ ptr[0] = a | 0xC0;
+ ptr[2] = -brightness;
+ }
+ else
+ {
+ ptr[0] = a | 0x80;
+ ptr[2] = brightness;
+ }
+}
+
+ARM_FUNC void G2x_SetBlendBrightnessExt_(u16 *ptr, fx32 a, fx32 b, fx32 c, fx32 d, fx32 brightness){
+ ptr[1] = c | (d << 0x8);
+ if (brightness < 0)
+ {
+ ptr[0] = 0xC0 | a | (b << 0x8);
+ ptr[2] = -brightness;
+ }
+ else
+ {
+ ptr[0] = 0x80 | a | (b << 0x8);
+ ptr[2] = brightness;
+ }
+}
+
+ARM_FUNC void *G2x_ChangeBlendBrightness_(u16 *ptr, fx32 brightness){
+ u32 temp = *ptr;
+ if (brightness < 0)
+ {
+ if ((temp & 0xC0) == 0x80)
+ {
+ ptr[0] = temp & ~0xC0 | 0xC0;
+ }
+ ptr[2] = -brightness;
+ }
+ else
+ {
+ if ((temp & 0xC0) == 0xC0)
+ {
+ ptr[0] = temp & ~0xC0 | 0x80;
+ }
+ ptr[2] = brightness;
+ }
+}
diff --git a/arm9/lib/src/GX_g3.c b/arm9/lib/src/GX_g3.c
new file mode 100644
index 00000000..2b5f2941
--- /dev/null
+++ b/arm9/lib/src/GX_g3.c
@@ -0,0 +1,36 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+
+ARM_FUNC void G3_BeginMakeDL(struct GXDLInfo *displaylist, void *r1, u32 r2){
+ displaylist->length = r2;
+ displaylist->bottom = r1;
+ displaylist->curr_cmd = r1;
+ displaylist->curr_param = (u32 *)r1 + 1;
+ displaylist->param0_cmd_flg = 0x0;
+}
+
+ARM_FUNC s32 G3_EndMakeDL(struct GXDLInfo *displaylist){
+ if (displaylist->bottom == (u32 *)displaylist->curr_cmd)
+ return 0;
+ //pads the buffer with 0 to 4byte alignment if needed
+ switch((u32)displaylist->curr_cmd & 0x3)
+ {
+ case 0:
+ return displaylist->curr_cmd - (u8 *)displaylist->bottom;
+ case 1:
+ *displaylist->curr_cmd++ = 0x0;
+ case 2:
+ *displaylist->curr_cmd++ = 0x0;
+ case 3:
+ *displaylist->curr_cmd++ = 0x0;
+ }
+ if (displaylist->param0_cmd_flg)
+ {
+ *displaylist->curr_param++ = 0x0;
+ displaylist->param0_cmd_flg = 0x0;
+ }
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param;
+ return displaylist->curr_cmd - (u8 *)displaylist->bottom;
+}
diff --git a/arm9/lib/src/GX_g3_util.c b/arm9/lib/src/GX_g3_util.c
new file mode 100644
index 00000000..c40a3848
--- /dev/null
+++ b/arm9/lib/src/GX_g3_util.c
@@ -0,0 +1,260 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+
+ARM_FUNC void G3i_PerspectiveW_(fx32 fovsin, fx32 fovcos, fx32 ratio, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx){
+ fx32 fovcot, temp1, temp2;
+ fx64c temp0;
+ vu32 *reg_ptr;
+
+ fovcot = FX_Div(fovcos, fovsin);
+ if (scale != 0x1000) //!= 1.0
+ fovcot = (fovcot * scale) / 0x1000;
+ reg_CP_DIV_NUMER = (s64)fovcot << 0x20;
+ reg_CP_DIV_DENOM = (u32)ratio;
+ if (load)
+ {
+ reg_G3_MTX_MODE = 0x0;
+ reg_ptr = (vu32 *)&reg_G3_MTX_LOAD_4x4;
+ }
+ if (mtx)
+ {
+ mtx->_[1] = 0x0;
+ mtx->_[2] = 0x0;
+ mtx->_[3] = 0x0;
+ mtx->_[4] = 0x0;
+ mtx->_[6] = 0x0;
+ mtx->_[7] = 0x0;
+ mtx->_[8] = 0x0;
+ mtx->_[9] = 0x0;
+ mtx->_[11] = -scale;
+ mtx->_[12] = 0x0;
+ mtx->_[13] = 0x0;
+ mtx->_[15] = 0x0;
+ }
+ temp1 = FX_GetDivResult();
+ reg_CP_DIV_NUMER = (s64)0x1000 << 0x20;
+ reg_CP_DIV_DENOM = (u32)(near - far);
+ if (load)
+ {
+ *reg_ptr = temp1;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = fovcot;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp1;
+ mtx->_[5] = fovcot;
+ }
+ temp0 = FX_GetDivResultFx64c();
+ if (scale != 0x1000)
+ temp0 = (temp0 * scale) / 0x1000;
+ temp1 = ((far + near) * temp0 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ temp2 = (((fx32)(((fx64)(near << 1) * far + (1 << (FX32_INT_SHIFT - 1))) >> FX32_INT_SHIFT)) * temp0 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp1;
+ *reg_ptr = -scale;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = temp2;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[10] = temp1;
+ mtx->_[14] = temp2;
+ }
+}
+
+ARM_FUNC void G3i_OrthoW_(fx32 top, fx32 bottom, fx32 left, fx32 right, fx32 near, fx32 far, fx32 scale, u32 load, struct Mtx44 *mtx){
+ fx64c temp1, temp2, temp3;
+ fx32 temp0, temp4, temp5;
+ vu32 *reg_ptr;
+
+ FX_InvAsync(right - left);
+ if (load)
+ {
+ reg_G3_MTX_MODE = 0x0;
+ reg_ptr = (vu32 *)&reg_G3_MTX_LOAD_4x4;
+ }
+ if (mtx)
+ {
+ mtx->_[1] = 0x0;
+ mtx->_[2] = 0x0;
+ mtx->_[3] = 0x0;
+ mtx->_[4] = 0x0;
+ mtx->_[6] = 0x0;
+ mtx->_[7] = 0x0;
+ mtx->_[8] = 0x0;
+ mtx->_[9] = 0x0;
+ mtx->_[11] = 0x0;
+ mtx->_[15] = scale;
+ }
+ temp1 = FX_GetDivResultFx64c();
+ reg_CP_DIV_NUMER = (s64)0x1000 << 0x20;
+ reg_CP_DIV_DENOM = (u32)(top - bottom);
+ if (scale != 0x1000)
+ temp1 = (temp1 * scale) / 0x1000;
+ temp0 = (0x2000 * temp1 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp0;
+ }
+ temp2 = FX_GetDivResultFx64c();
+ reg_CP_DIV_NUMER = (s64)0x1000 << 0x20;
+ reg_CP_DIV_DENOM = (u32)(near - far);
+ if (scale != 0x1000)
+ temp2 = (temp2 * scale) / 0x1000;
+ temp0 = (0x2000 * temp2 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[5] = temp0;
+ }
+ temp3 = FX_GetDivResultFx64c();
+ if (scale != 0x1000)
+ temp3 = (temp3 * scale) / 0x1000;
+ temp0 = (0x2000 * temp3 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = 0x0;
+ }
+ if (mtx)
+ {
+ mtx->_[10] = temp0;
+ }
+ temp0 = ((-(right + left)) * temp1 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ temp4 = ((-(top + bottom)) * temp2 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ temp5 = ((far + near) * temp3 + ((fx64)1 << (FX64C_INT_SHIFT - 1))) >> FX64C_INT_SHIFT;
+ if (load)
+ {
+ *reg_ptr = temp0;
+ *reg_ptr = temp4;
+ *reg_ptr = temp5;
+ *reg_ptr = scale;
+ }
+ if (mtx)
+ {
+ mtx->_[12] = temp0;
+ mtx->_[13] = temp4;
+ mtx->_[14] = temp5;
+ }
+}
+
+ARM_FUNC void G3i_LookAt_(struct Vecx32 *a, struct Vecx32 *b, struct Vecx32 *c, u32 load, struct Mtx44 *mtx){
+ struct Vecx32 temp, temp1, temp2;
+ fx32 c1, c2, c3;
+ vu32 *reg_ptr;
+ temp.x = a->x - c->x;
+ temp.y = a->y - c->y;
+ temp.z = a->z - c->z;
+ VEC_Normalize(&temp, &temp);
+ VEC_CrossProduct(b, &temp, &temp1);
+ VEC_Normalize(&temp1, &temp1);
+ VEC_CrossProduct(&temp, &temp1, &temp2);
+ if (load)
+ {
+ reg_G3_MTX_MODE = 0x2;
+ reg_ptr = (vu32 *)&reg_G3_MTX_LOAD_4x3;
+ *reg_ptr = temp1.x;
+ *reg_ptr = temp2.x;
+ *reg_ptr = temp.x;
+ *reg_ptr = temp1.y;
+ *reg_ptr = temp2.y;
+ *reg_ptr = temp.y;
+ *reg_ptr = temp1.z;
+ *reg_ptr = temp2.z;
+ *reg_ptr = temp.z;
+ }
+ c1 = -VEC_DotProduct(a, &temp1);
+ c2 = -VEC_DotProduct(a, &temp2);
+ c3 = -VEC_DotProduct(a, &temp);
+ if (load)
+ {
+ *reg_ptr = c1;
+ *reg_ptr = c2;
+ *reg_ptr = c3;
+ }
+ if (mtx)
+ {
+ mtx->_[0] = temp1.x;
+ mtx->_[1] = temp2.x;
+ mtx->_[2] = temp.x;
+ mtx->_[3] = temp1.y;
+ mtx->_[4] = temp2.y;
+ mtx->_[5] = temp.y;
+ mtx->_[6] = temp1.z;
+ mtx->_[7] = temp2.z;
+ mtx->_[8] = temp.z;
+ mtx->_[9] = c1;
+ mtx->_[10] = c2;
+ mtx->_[11] = c3;
+ }
+}
+
+ARM_FUNC void G3_RotX(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)&reg_G3_MTX_MULT_3x3;
+ *reg_ptr = 0x1000;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = cosphi;
+ *reg_ptr = sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = -sinphi;
+ *reg_ptr = cosphi;
+}
+
+ARM_FUNC void G3_RotY(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)&reg_G3_MTX_MULT_3x3;
+ *reg_ptr = cosphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = -sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x1000;
+ *reg_ptr = 0x0;
+ *reg_ptr = sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = cosphi;
+}
+
+ARM_FUNC void G3_RotZ(fx32 sinphi, fx32 cosphi){
+ vu32 *reg_ptr;
+ reg_ptr = (vu32 *)&reg_G3_MTX_MULT_3x3;
+ *reg_ptr = cosphi;
+ *reg_ptr = sinphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = -sinphi;
+ *reg_ptr = cosphi;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x0;
+ *reg_ptr = 0x1000;
+}
diff --git a/arm9/lib/src/GX_g3b.c b/arm9/lib/src/GX_g3b.c
new file mode 100644
index 00000000..21698547
--- /dev/null
+++ b/arm9/lib/src/GX_g3b.c
@@ -0,0 +1,120 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+
+ARM_FUNC void G3BS_LoadMtx44(struct GXDLInfo *displaylist, struct Mtx44 *mtx){
+ *(u32 *)displaylist->curr_cmd = 0x16;
+ MI_Copy64B(mtx, displaylist->curr_param);
+}
+
+ARM_FUNC void G3B_PushMtx(struct GXDLInfo *displaylist){
+ *(u32 *)displaylist->curr_cmd = 0x11;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_PopMtx(struct GXDLInfo *displaylist, void *mtx){
+ *(u32 *)displaylist->curr_cmd = 0x12;
+ *displaylist->curr_param = (u32)mtx;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_LoadMtx44(struct GXDLInfo *displaylist, struct Mtx44 *mtx){
+ G3BS_LoadMtx44(displaylist, mtx);
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + sizeof(struct Mtx44);
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+//color format is RGB555, stored in the lower bits
+ARM_FUNC void G3B_Color(struct GXDLInfo * displaylist, u32 vtx_col){
+ *(u32 *)displaylist->curr_cmd = 0x20;
+ *displaylist->curr_param = vtx_col;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+/*
+Only feed normalized Vectors
+only the fractional part and the sign, which is in the first nonfraction bit
+since the vector is assumed to be normalized, are used
+*/
+ARM_FUNC void G3B_Normal(struct GXDLInfo * displaylist, fx16 x, fx16 y, fx16 z){
+ *(u32 *)displaylist->curr_cmd = 0x21;
+ *displaylist->curr_param = ((x >> 3) & 0x3FF) | (((y >> 3) & 0x3FF) << 0xA) | (((z >> 3) & 0x3FF) << 0x14) ;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_Vtx(struct GXDLInfo * displaylist, fx32 x, fx32 y, fx32 z){
+ *(u32 *)displaylist->curr_cmd = 0x23;
+ displaylist->curr_param[0] = (u32)(u16)x | (u32)(u16)y << 0x10;
+ displaylist->curr_param[1] = (u32)(u16)z;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x8;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+//TODO: name arguments
+ARM_FUNC void G3B_PolygonAttr(struct GXDLInfo *displaylist, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6){
+ *(u32 *)displaylist->curr_cmd = 0x29;
+ *displaylist->curr_param = r1 | r2 << 0x4 | r3 << 0x6 | r6 | r4 << 0x18 | r5 << 0x10;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_MaterialColorDiffAmb(struct GXDLInfo *displaylist, u32 diffuse_col, u32 ambient_col, u32 replace){
+ *(u32 *)displaylist->curr_cmd = 0x30;
+ u32 replace_vtx_color_with_diffuse;
+ if (replace)
+ replace_vtx_color_with_diffuse = TRUE;
+ else
+ replace_vtx_color_with_diffuse = FALSE;
+ *displaylist->curr_param = diffuse_col | ambient_col << 0x10 | replace_vtx_color_with_diffuse << 0xF;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_MaterialColorSpecEmi(struct GXDLInfo *displaylist, u32 specular_col, u32 emission_col, u32 shiny_table){
+ *(u32 *)displaylist->curr_cmd = 0x31;
+ u32 enable_shininess_table;
+ if (shiny_table)
+ enable_shininess_table = TRUE;
+ else
+ enable_shininess_table = FALSE;
+ *displaylist->curr_param = specular_col | emission_col << 0x10 | enable_shininess_table << 0xF;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+/*
+Only feed normalized Vectors
+only the fractional part and the sign, which is in the first nonfraction bit
+since the vector is assumed to be normalized, are used
+*/
+ARM_FUNC void G3B_LightVector(struct GXDLInfo * displaylist, u32 light_num, fx16 x, fx16 y, fx16 z){
+ *(u32 *)displaylist->curr_cmd = 0x32;
+ *displaylist->curr_param = ((x >> 3) & 0x3FF) | (((y >> 3) & 0x3FF) << 0xA) | (((z >> 3) & 0x3FF) << 0x14) | light_num << 0x1E;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_LightColor(struct GXDLInfo * displaylist, u32 light_num, u32 col){
+ *(u32 *)displaylist->curr_cmd = 0x33;
+ *displaylist->curr_param = col | light_num << 0x1E;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_Begin(struct GXDLInfo * displaylist, u32 type){
+ *(u32 *)displaylist->curr_cmd = 0x40;
+ *displaylist->curr_param = type;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param + 0x4;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
+
+ARM_FUNC void G3B_End(struct GXDLInfo * displaylist){
+ *(u32 *)displaylist->curr_cmd = 0x41;
+ displaylist->curr_cmd = (u8 *)displaylist->curr_param;
+ displaylist->curr_param = (u32 *)displaylist->curr_cmd + 1;
+}
diff --git a/arm9/lib/src/GX_g3imm.c b/arm9/lib/src/GX_g3imm.c
new file mode 100644
index 00000000..579032a6
--- /dev/null
+++ b/arm9/lib/src/GX_g3imm.c
@@ -0,0 +1,18 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+ARM_FUNC void G3_LoadMtx43(struct Mtx43 *mtx){
+ reg_G3X_GXFIFO = 0x17;
+ GX_SendFifo48B(mtx, (void *)&reg_G3X_GXFIFO);
+}
+
+ARM_FUNC void G3_MultMtx43(struct Mtx43 *mtx){
+ reg_G3X_GXFIFO = 0x19;
+ GX_SendFifo48B(mtx, (void *)&reg_G3X_GXFIFO);
+}
+
+ARM_FUNC void G3_MultMtx33(struct Mtx33 *mtx){
+ reg_G3X_GXFIFO = 0x1A;
+ MI_Copy36B(mtx, (void *)&reg_G3X_GXFIFO);
+}
diff --git a/arm9/lib/src/GX_g3x.c b/arm9/lib/src/GX_g3x.c
new file mode 100644
index 00000000..31508e06
--- /dev/null
+++ b/arm9/lib/src/GX_g3x.c
@@ -0,0 +1,235 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+extern u32 GXi_DmaId;
+
+ARM_FUNC asm void GXi_NopClearFifo128_(void *reg){
+ mov r1, #0x0
+ mov r2, #0x0
+ mov r3, #0x0
+ mov r12, #0x0
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ stmia r0, {r1-r3,r12}
+ bx lr
+}
+
+ARM_FUNC void G3X_Init(){
+ G3X_ClearFifo();
+ reg_G3_END_VTXS = 0x0;
+ while (reg_G3X_GXSTAT & 0x8000000); //wait for geometry engine to not be busy
+ reg_G3X_DISP3DCNT = 0x0;
+ reg_G3X_GXSTAT = 0x0;
+ reg_G2_BG0OFS = 0x0;
+ reg_G3X_DISP3DCNT |= 0x2000;
+ reg_G3X_DISP3DCNT |= 0x1000;
+ reg_G3X_DISP3DCNT &= ~0x3002;
+ reg_G3X_DISP3DCNT = reg_G3X_DISP3DCNT & ~0x3000 | 0x10;
+ reg_G3X_DISP3DCNT = reg_G3X_DISP3DCNT & (u16)~0x3004;
+ reg_G3X_GXSTAT |= 0x8000;
+ reg_G3X_GXSTAT = reg_G3X_GXSTAT & ~0xC0000000 | 0x80000000;
+ G3X_InitMtxStack();
+ reg_G3X_CLEAR_COLOR = 0x0;
+ reg_G3X_CLEAR_DEPTH = 0x7FFF;
+ reg_G3X_CLRIMAGE_OFFSET = 0x0;
+ reg_G3X_FOG_COLOR = 0x0;
+ reg_G3X_FOG_OFFSET = 0x0;
+ reg_G2_BG0CNT &= ~0x3;
+ G3X_InitTable();
+ reg_G3_POLYGON_ATTR = 0x1F0080;
+ reg_G3_TEXIMAGE_PARAM = 0x0;
+ reg_G3_TEXPLTT_BASE = 0x0;
+}
+
+ARM_FUNC void G3X_ResetMtxStack(){
+ while (reg_G3X_GXSTAT & 0x8000000);
+ reg_G3X_GXSTAT |= 0x8000;
+ reg_G3X_DISP3DCNT |= 0x2000;
+ reg_G3X_DISP3DCNT |= 0x1000;
+ G3X_ResetMtxStack_2();
+ reg_G3_POLYGON_ATTR = 0x1F0080;
+ reg_G3_TEXIMAGE_PARAM = 0x0;
+ reg_G3_TEXPLTT_BASE = 0x0;
+}
+
+ARM_FUNC void G3X_ClearFifo(){
+ GXi_NopClearFifo128_((void *)&reg_G3X_GXFIFO);
+ while (reg_G3X_GXSTAT & 0x8000000);
+}
+
+ARM_FUNC void G3X_InitMtxStack(){
+ u32 PV_level, PJ_level;
+ reg_G3X_GXSTAT |= 0x8000;
+ while (G3X_GetMtxStackLevelPV(&PV_level));
+ while (G3X_GetMtxStackLevelPJ(&PJ_level));
+ reg_G3_MTX_MODE = 0x3;
+ reg_G3_MTX_IDENTITY = 0x0;
+ reg_G3_MTX_MODE = 0x0;
+ if (PJ_level)
+ {
+ reg_G3_MTX_POP = PJ_level;
+ }
+ reg_G3_MTX_IDENTITY = 0x0;
+ reg_G3_MTX_MODE = 0x2;
+ reg_G3_MTX_POP = PV_level;
+ reg_G3_MTX_IDENTITY = 0x0;
+}
+
+ARM_FUNC void G3X_ResetMtxStack_2(){
+ u32 PV_level, PJ_level;
+ reg_G3X_GXSTAT |= 0x8000;
+ while (G3X_GetMtxStackLevelPV(&PV_level));
+ while (G3X_GetMtxStackLevelPJ(&PJ_level));
+ reg_G3_MTX_MODE = 0x3;
+ reg_G3_MTX_IDENTITY = 0x0;
+ reg_G3_MTX_MODE = 0x0;
+ if (PJ_level)
+ {
+ reg_G3_MTX_POP = PJ_level;
+ }
+
+ reg_G3_MTX_MODE = 0x2;
+ reg_G3_MTX_POP = PV_level;
+ reg_G3_MTX_IDENTITY = 0x0;
+
+}
+
+ARM_FUNC void G3X_SetFog(u32 enable, u32 alphamode, u32 depth, s32 offset){
+ if (enable)
+ {
+ reg_G3X_FOG_OFFSET = offset;
+ reg_G3X_DISP3DCNT = (reg_G3X_DISP3DCNT &~0x3f40) | (((depth << 0x8)| (alphamode << 0x6)|0x80 ));
+
+ }
+ else
+ {
+ reg_G3X_DISP3DCNT = reg_G3X_DISP3DCNT & (u16)~0x3080;
+ }
+}
+
+ARM_FUNC u32 G3X_GetClipMtx(struct Mtx44 *dst){
+ if (reg_G3X_GXSTAT & 0x8000000)
+ {
+ return -1;
+ }
+ else
+ {
+ MI_Copy64B((void *)&reg_G3X_CLIPMTX_RESULT_0, dst);
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetVectorMtx(struct Mtx33 *dst){
+ if (reg_G3X_GXSTAT & 0x8000000)
+ {
+ return -1;
+ }
+ else
+ {
+ MI_Copy36B((void *)&reg_G3X_VECMTX_RESULT_0, dst);
+ return 0;
+ }
+}
+
+ARM_FUNC void G3X_SetEdgeColorTable(void *tbl_ptr){
+ MIi_CpuCopy16(tbl_ptr, (void *)&reg_G3X_EDGE_COLOR_0, 0x10);
+}
+
+ARM_FUNC void G3X_SetFogTable(void *tbl_ptr){
+ MI_Copy16B(tbl_ptr, (void *)&reg_G3X_FOG_TABLE_0);
+}
+
+ARM_FUNC void G3X_SetClearColor(u32 col, u32 alpha, u32 depth, u32 polygon_id, u32 enable_fog){
+ u32 temp = col | (alpha << 0x10) | (polygon_id << 0x18);
+ if (enable_fog)
+ temp |= 0x8000;
+ reg_G3X_CLEAR_COLOR = temp;
+ reg_G3X_CLEAR_DEPTH = depth;
+}
+
+ARM_FUNC void G3X_InitTable(){
+ if (GXi_DmaId != -1)
+ {
+ MI_DmaFill32Async(GXi_DmaId, (void *)&reg_G3X_EDGE_COLOR_0, 0x0, 0x10, 0x0, 0x0);
+ MI_DmaFill32(GXi_DmaId, (void *)&reg_G3X_FOG_TABLE_0, 0x0, 0x60);
+ }
+ else
+ {
+ MIi_CpuClear32(0x0, (void *)&reg_G3X_EDGE_COLOR_0, 0x10);
+ MIi_CpuClear32(0x0, (void *)&reg_G3X_FOG_TABLE_0, 0x60);
+ }
+ for (int i = 0; i < 0x20; i++)
+ {
+ reg_G3_SHININESS = 0x0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetMtxStackLevelPV(u32 *level){
+ if (reg_G3X_GXSTAT & 0x4000)
+ {
+ return -1;
+ }
+ else
+ {
+ *level = (reg_G3X_GXSTAT & 0x1F00) >> 0x8;
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetMtxStackLevelPJ(u32 *level){
+ if (reg_G3X_GXSTAT & 0x4000)
+ {
+ return -1;
+ }
+ else
+ {
+ *level = (reg_G3X_GXSTAT & 0x2000) >> 0xD;
+ return 0;
+ }
+}
+
+ARM_FUNC u32 G3X_GetBoxTestResult(u32 *result){
+ if (reg_G3X_GXSTAT & 0x1)
+ {
+ return -1;
+ }
+ else
+ {
+ *result = (reg_G3X_GXSTAT & 0x2);
+ return 0;
+ }
+}
+
+ARM_FUNC void G3X_SetHOffset(u32 offset){
+ reg_G2_BG0OFS = offset;
+}
diff --git a/arm9/lib/src/GX_load2d.c b/arm9/lib/src/GX_load2d.c
new file mode 100644
index 00000000..d4def461
--- /dev/null
+++ b/arm9/lib/src/GX_load2d.c
@@ -0,0 +1,223 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+extern u32 GXi_DmaId;
+
+extern s32 sSubOBJExtPltt;
+extern s32 sBGExtPltt;
+extern u32 sBGExtPlttLCDCBlk;
+extern u32 sBGExtPlttLCDCOffset;
+extern s32 sOBJExtPltt;
+extern u32 sOBJExtPlttLCDCBlk;
+extern s32 sSubBGExtPltt;
+
+
+static inline void *_GX_OBJ_PTR(){
+ return (void *)0x6400000;
+}
+static inline void *_GXS_OBJ_PTR(){
+ return (void *)0x6600000;
+}
+
+ARM_FUNC void GX_LoadBGPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000000 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBGPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000400 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOBJPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000200 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOBJPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(0x5000600 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOAM(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(0x7000000 + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOAM(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(0x7000400 + offset), size);
+}
+
+ARM_FUNC void GX_LoadOBJ(void *src, u32 offset, u32 size){
+ u32 base = (u32)_GX_OBJ_PTR();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadOBJ(void *src, u32 offset, u32 size){
+ u32 base = (u32)_GXS_OBJ_PTR();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG0Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG0ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG0Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG0ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG1Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG1ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG1Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG1ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG2Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG2ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG2Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG2ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG3Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG3ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG3Scr(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG3ScrPtr();
+ GXi_DmaCopy16(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG0Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG0CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG0Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG0CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG1Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG1CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG1Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG1CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG2Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG2CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG2Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG2CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_LoadBG3Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2_GetBG3CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GXS_LoadBG3Char(void *src, u32 offset, u32 size){
+ u32 base = (u32)G2S_GetBG3CharPtr();
+ GXi_DmaCopy32(GXi_DmaId, src, (void *)(base + offset), size);
+}
+
+ARM_FUNC void GX_BeginLoadBGExtPltt(){
+ sBGExtPltt = GX_ResetBankForBGExtPltt();
+ switch (sBGExtPltt)
+ {
+ case 0: //needed to match
+ break;
+ case 0x10:
+ sBGExtPlttLCDCBlk = 0x06880000;
+ sBGExtPlttLCDCOffset = 0x0;
+ break;
+ case 0x40:
+ sBGExtPlttLCDCBlk = 0x06894000;
+ sBGExtPlttLCDCOffset = 0x4000;
+ break;
+ case 0x20:
+ case 0x60:
+ sBGExtPlttLCDCBlk = 0x06890000;
+ sBGExtPlttLCDCOffset = 0x0;
+ break;
+ }
+}
+
+ARM_FUNC void GX_LoadBGExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sBGExtPlttLCDCBlk + offset - sBGExtPlttLCDCOffset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadBGExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForBGExtPltt(sBGExtPltt);
+ sBGExtPltt = 0x0;
+ sBGExtPlttLCDCBlk = 0x0;
+ sBGExtPlttLCDCOffset = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadOBJExtPltt(){
+ sOBJExtPltt = GX_ResetBankForOBJExtPltt();
+ switch (sOBJExtPltt)
+ {
+ case 0: //needed to match
+ break;
+ case 0x40:
+ sOBJExtPlttLCDCBlk = 0x06894000;
+ break;
+ case 0x20:
+ sOBJExtPlttLCDCBlk = 0x06890000;
+ break;
+ }
+}
+
+ARM_FUNC void GX_LoadOBJExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sOBJExtPlttLCDCBlk + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadOBJExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForOBJExtPltt(sOBJExtPltt);
+ sOBJExtPltt = 0x0;
+ sOBJExtPlttLCDCBlk = 0x0;
+}
+
+ARM_FUNC void GXS_BeginLoadBGExtPltt(){
+ sSubBGExtPltt = FUN_020C6034();
+}
+
+ARM_FUNC void GXS_LoadBGExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(0x06898000 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GXS_EndLoadBGExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForSubBGExtPltt(sSubBGExtPltt);
+ sSubBGExtPltt = 0x0;
+}
+
+ARM_FUNC void GXS_BeginLoadOBJExtPltt(){
+ sSubOBJExtPltt = GX_ResetBankForSubOBJ();
+}
+
+ARM_FUNC void GXS_LoadOBJExtPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(0x068A0000 + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GXS_EndLoadOBJExtPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForSubOBJExtPltt(sSubOBJExtPltt);
+ sSubOBJExtPltt = 0x0;
+}
diff --git a/arm9/lib/src/GX_load3d.c b/arm9/lib/src/GX_load3d.c
new file mode 100644
index 00000000..5aa15581
--- /dev/null
+++ b/arm9/lib/src/GX_load3d.c
@@ -0,0 +1,125 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+extern u32 GXi_DmaId;
+
+extern u32 sTex;
+extern u32 sTexLCDCBlk1;
+extern u32 sTexLCDCBlk2;
+extern u32 sSzTexBlk1;
+
+static const struct _TexStartAddrTable
+{
+ u16 blk1; // 12 bit shift
+ u16 blk2; // 12 bit shift
+ u16 szBlk1; // 12 bit shift
+};
+extern struct _TexStartAddrTable sTexStartAddrTable[16];
+
+
+extern u32 sTexPltt;
+extern u32 sTexPlttLCDCBlk;
+extern u16 sTexPlttStartAddrTable[8];
+
+extern s32 sClrImg;
+extern u32 sClrImgLCDCBlk;
+
+ARM_FUNC void GX_BeginLoadTex(){
+ u32 temp = GX_ResetBankForTex();
+ sTex = temp;
+ sTexLCDCBlk1 = sTexStartAddrTable[temp].blk1 << 0xC;
+ sTexLCDCBlk2 = sTexStartAddrTable[temp].blk2 << 0xC;
+ sSzTexBlk1 = sTexStartAddrTable[temp].szBlk1 << 0xC;
+}
+
+ARM_FUNC void GX_LoadTex(void *src, u32 offset, u32 size){
+ void *temp;
+ if (!sTexLCDCBlk2)
+ {
+ temp = (void *)(sTexLCDCBlk1 + offset);
+ }
+ else
+ {
+ if ((offset + size) < sSzTexBlk1)
+ {
+ temp = (void *)(sTexLCDCBlk1 + offset);
+ }
+ else if (offset >= sSzTexBlk1)
+ {
+ temp = (void *)(sTexLCDCBlk2 + offset - sSzTexBlk1);
+ }
+ else
+ {
+ void *temp2 = (void *)sTexLCDCBlk2;
+ u32 temp1 = sSzTexBlk1 - offset;
+ temp = (void *)(sTexLCDCBlk1 + offset);
+ GXi_DmaCopy32(GXi_DmaId, src, temp, temp1);
+ GXi_DmaCopy32Async(GXi_DmaId, (void *)((u8 *)src + temp1), temp2, (size - temp1), NULL, NULL);
+ return;
+ }
+ }
+ GXi_DmaCopy32Async(GXi_DmaId, src, temp, size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadTex(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForTex(sTex);
+ sSzTexBlk1 = 0x0;
+ sTexLCDCBlk2 = 0x0;
+ sTexLCDCBlk1 = 0x0;
+ sTex = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadTexPltt(){
+ s32 temp = GX_ResetBankForTexPltt();
+ sTexPltt = temp;
+ sTexPlttLCDCBlk = sTexPlttStartAddrTable[temp >> 4] << 0xC;
+}
+
+ARM_FUNC void GX_LoadTexPltt(void *src, u32 offset, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sTexPlttLCDCBlk + offset), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadTexPltt(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForTexPltt(sTexPltt);
+ sTexPltt = 0x0;
+ sTexPlttLCDCBlk = 0x0;
+}
+
+ARM_FUNC void GX_BeginLoadClearImage(){
+ s32 temp = GX_ResetBankForClearImage();
+ sClrImg = temp;
+ switch (temp)
+ {
+ case 2:
+ case 3:
+ sClrImgLCDCBlk = 0x6800000;
+ return;
+ case 8:
+ case 12:
+ sClrImgLCDCBlk = 0x6840000;
+ return;
+ case 1:
+ sClrImgLCDCBlk = 0x67E0000;
+ return;
+ case 4:
+ sClrImgLCDCBlk = 0x6820000;
+ }
+}
+
+ARM_FUNC void GX_LoadClearImageColor(void *src, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sClrImgLCDCBlk), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_LoadClearImageDepth(void *src, u32 size){
+ GXi_DmaCopy32Async(GXi_DmaId, src, (void *)(sClrImgLCDCBlk + 0x20000), size, NULL, NULL);
+}
+
+ARM_FUNC void GX_EndLoadClearImage(){
+ GXi_WaitDma(GXi_DmaId);
+ GX_SetBankForClearImage(sClrImg);
+ sClrImg = 0x0;
+ sClrImgLCDCBlk = 0x0;
+}
diff --git a/arm9/lib/src/GX_state.c b/arm9/lib/src/GX_state.c
new file mode 100644
index 00000000..3ca3b266
--- /dev/null
+++ b/arm9/lib/src/GX_state.c
@@ -0,0 +1,26 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+extern struct GX_State gGXState;
+
+ARM_FUNC void GX_InitGXState(){
+ gGXState.lcdc = 0x0;
+ gGXState.bg = 0x0;
+ gGXState.obj = 0x0;
+ gGXState.arm7 = 0x0;
+ gGXState.tex = 0x0;
+ gGXState.texPltt = 0x0;
+ gGXState.clrImg = 0x0;
+ gGXState.bgExtPltt = 0x0;
+ gGXState.objExtPltt = 0x0;
+ gGXState.sub_bg = 0x0;
+ gGXState.sub_obj = 0x0;
+ gGXState.sub_bgExtPltt = 0x0;
+ gGXState.sub_objExtPltt = 0x0;
+ reg_GX_VRAMCNT = 0x0;
+ reg_GX_VRAMCNT_E = 0x0;
+ reg_GX_VRAMCNT_F = 0x0;
+ reg_GX_VRAMCNT_G = 0x0;
+ reg_GX_VRAM_HI_CNT = 0x0;
+}
diff --git a/arm9/lib/src/GX_vramcnt.c b/arm9/lib/src/GX_vramcnt.c
new file mode 100644
index 00000000..67749301
--- /dev/null
+++ b/arm9/lib/src/GX_vramcnt.c
@@ -0,0 +1,579 @@
+#include "global.h"
+#include "main.h"
+#include "GX.h"
+
+extern u16 GXi_VRamLockId;
+extern struct GX_State gGXState;
+
+ARM_FUNC void GX_VRAMCNT_SetLCDC_(u32 mask){
+ if (mask & (0x1 << 0))
+ reg_GX_VRAMCNT_A = 0x80;
+ if (mask & (0x1 << 1))
+ reg_GX_VRAMCNT_B = 0x80;
+ if (mask & (0x1 << 2))
+ reg_GX_VRAMCNT_C = 0x80;
+ if (mask & (0x1 << 3))
+ reg_GX_VRAMCNT_D = 0x80;
+ if (mask & (0x1 << 4))
+ reg_GX_VRAMCNT_E = 0x80;
+ if (mask & (0x1 << 5))
+ reg_GX_VRAMCNT_F = 0x80;
+ if (mask & (0x1 << 6))
+ reg_GX_VRAMCNT_G = 0x80;
+ if (mask & (0x1 << 7))
+ reg_GX_VRAMCNT_H = 0x80;
+ if (mask & (0x1 << 8))
+ reg_GX_VRAMCNT_I = 0x80;
+}
+
+ARM_FUNC void GX_SetBankForBG(s32 bg){
+ gGXState.lcdc = (u16)(~bg & (gGXState.lcdc | gGXState.bg));
+ gGXState.bg = bg;
+ switch (bg)
+ {
+ case 8:
+ reg_GX_VRAMCNT_D = 0x81;
+ break;
+ case 12:
+ reg_GX_VRAMCNT_D = 0x89;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x81;
+ break;
+ case 14:
+ reg_GX_VRAMCNT_D = 0x91;
+ case 6:
+ reg_GX_VRAMCNT_C = 0x89;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x81;
+ break;
+ case 15:
+ reg_GX_VRAMCNT_D = 0x99;
+ case 7:
+ reg_GX_VRAMCNT_C = 0x91;
+ case 3:
+ reg_GX_VRAMCNT_B = 0x89;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x81;
+ break;
+ case 11:
+ reg_GX_VRAMCNT_A = 0x81;
+ reg_GX_VRAMCNT_B = 0x89;
+ reg_GX_VRAMCNT_D = 0x91;
+ break;
+ case 13:
+ reg_GX_VRAMCNT_D = 0x91;
+ case 5:
+ reg_GX_VRAMCNT_A = 0x81;
+ reg_GX_VRAMCNT_C = 0x89;
+ break;
+ case 9:
+ reg_GX_VRAMCNT_A = 0x81;
+ reg_GX_VRAMCNT_D = 0x89;
+ break;
+ case 10:
+ reg_GX_VRAMCNT_B = 0x81;
+ reg_GX_VRAMCNT_D = 0x89;
+ break;
+ case 112:
+ reg_GX_VRAMCNT_G = 0x99;
+ case 48:
+ reg_GX_VRAMCNT_F = 0x91;
+ case 16:
+ reg_GX_VRAMCNT_E = 0x81;
+ break;
+ case 80:
+ reg_GX_VRAMCNT_G = 0x91;
+ reg_GX_VRAMCNT_E = 0x81;
+ break;
+ case 96:
+ reg_GX_VRAMCNT_G = 0x89;
+ case 32:
+ reg_GX_VRAMCNT_F = 0x81;
+ break;
+ case 64:
+ reg_GX_VRAMCNT_G = 0x81;
+ break;
+ default:
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForOBJ(s32 obj){
+ gGXState.lcdc = (u16)(~obj & (gGXState.lcdc | gGXState.obj));
+ gGXState.obj = obj;
+ switch (obj)
+ {
+ case 3:
+ reg_GX_VRAMCNT_B = 0x8A;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x82;
+ case 0: //needed to match
+ break;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x82;
+ break;
+ case 112:
+ reg_GX_VRAMCNT_G = 0x9A;
+ case 48:
+ reg_GX_VRAMCNT_F = 0x92;
+ case 16:
+ reg_GX_VRAMCNT_E = 0x82;
+ break;
+ case 80:
+ reg_GX_VRAMCNT_G = 0x92;
+ reg_GX_VRAMCNT_E = 0x82;
+ break;
+ case 96:
+ reg_GX_VRAMCNT_G = 0x8A;
+ case 32:
+ reg_GX_VRAMCNT_F = 0x82;
+ break;
+ case 64:
+ reg_GX_VRAMCNT_G = 0x82;
+ break;
+ default:
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForBGExtPltt(s32 bgextpltt){
+ gGXState.lcdc = (u16)(~bgextpltt & (gGXState.lcdc | gGXState.bgExtPltt));
+ gGXState.bgExtPltt = bgextpltt;
+ switch (bgextpltt)
+ {
+ case 0x10:
+ reg_GX_DISPCNT |= 0x40000000;
+ reg_GX_VRAMCNT_E = 0x84;
+ break;
+ case 0x40:
+ reg_GX_DISPCNT |= 0x40000000;
+ reg_GX_VRAMCNT_G = 0x8C;
+ break;
+ case 0x60:
+ reg_GX_VRAMCNT_G = 0x8C;
+ case 0x20:
+ reg_GX_VRAMCNT_F = 0x84;
+ reg_GX_DISPCNT |= 0x40000000;
+ break;
+ case 0:
+ reg_GX_DISPCNT &= ~0x40000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForOBJExtPltt(s32 objextpltt){
+ gGXState.lcdc = (u16)(~objextpltt & (gGXState.lcdc | gGXState.objExtPltt));
+ gGXState.objExtPltt = objextpltt;
+ switch (objextpltt)
+ {
+ case 32:
+ reg_GX_DISPCNT |= 0x80000000;
+ reg_GX_VRAMCNT_F = 0x85;
+ break;
+ case 64:
+ reg_GX_DISPCNT |= 0x80000000;
+ reg_GX_VRAMCNT_G = 0x85;
+ break;
+ case 0:
+ reg_GX_DISPCNT &= ~0x80000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForTex(s32 tex){
+ gGXState.lcdc = (u16)(~tex & (gGXState.lcdc | gGXState.tex));
+ gGXState.tex = tex;
+ if (tex == 0)
+ {
+ reg_G3X_DISP3DCNT &= 0x0000CFFE;
+ }
+ else
+ {
+ reg_G3X_DISP3DCNT = (reg_G3X_DISP3DCNT & ~0x3000) | 0x1;
+ switch (tex)
+ {
+ case 5:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_C = 0x8B;
+ break;
+ case 9:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_D = 0x8B;
+ break;
+ case 10:
+ reg_GX_VRAMCNT_B = 0x83;
+ reg_GX_VRAMCNT_D = 0x8B;
+ break;
+ case 11:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_B = 0x8B;
+ reg_GX_VRAMCNT_D = 0x93;
+ break;
+ case 13:
+ reg_GX_VRAMCNT_A = 0x83;
+ reg_GX_VRAMCNT_C = 0x8B;
+ reg_GX_VRAMCNT_D = 0x93;
+ break;
+ case 8:
+ reg_GX_VRAMCNT_D = 0x83;
+ break;
+ case 12:
+ reg_GX_VRAMCNT_D = 0x8B;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x83;
+ break;
+ case 14:
+ reg_GX_VRAMCNT_D = 0x93;
+ case 6:
+ reg_GX_VRAMCNT_C = 0x8B;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x83;
+ break;
+ case 15:
+ reg_GX_VRAMCNT_D = 0x9B;
+ case 7:
+ reg_GX_VRAMCNT_C = 0x93;
+ case 3:
+ reg_GX_VRAMCNT_B = 0x8B;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x83;
+ break;
+ }
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForTexPltt(s32 texpltt){
+ gGXState.lcdc = (u16)(~texpltt & (gGXState.lcdc | gGXState.texPltt));
+ gGXState.texPltt = texpltt;
+ switch (texpltt)
+ {
+ case 0: //needed to match
+ break;
+ case 96:
+ reg_GX_VRAMCNT_G = 0x8B;
+ case 32:
+ reg_GX_VRAMCNT_F = 0x83;
+ break;
+ case 112:
+ reg_GX_VRAMCNT_G = 0x9B;
+ case 48:
+ reg_GX_VRAMCNT_F = 0x93;
+ case 16:
+ reg_GX_VRAMCNT_E = 0x83;
+ break;
+ case 64:
+ reg_GX_VRAMCNT_G = 0x83;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForClearImage(s32 clearimage){
+ gGXState.lcdc = (u16)(~clearimage & (gGXState.lcdc | gGXState.clrImg));
+ gGXState.clrImg = clearimage;
+ switch (clearimage)
+ {
+ case 3:
+ reg_GX_VRAMCNT_A = 0x93;
+ case 2:
+ reg_GX_VRAMCNT_B = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ break;
+ case 12:
+ reg_GX_VRAMCNT_C = 0x93;
+ case 8:
+ reg_GX_VRAMCNT_D = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ break;
+ case 0:
+ reg_G3X_DISP3DCNT &= ~0x4000;
+ break;
+ case 1:
+ reg_GX_VRAMCNT_A = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ break;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x9B;
+ reg_G3X_DISP3DCNT |= 0x4000;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForARM7(s32 arm7){
+ gGXState.lcdc = (u16)(~arm7 & (gGXState.lcdc | gGXState.arm7));
+ gGXState.arm7 = arm7;
+ switch (arm7)
+ {
+ case 0: //needed to match
+ break;
+ case 12:
+ reg_GX_VRAMCNT_D = 0x8A;
+ reg_GX_VRAMCNT_C = 0x82;
+ break;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x82;
+ break;
+ case 8:
+ reg_GX_VRAMCNT_D = 0x82;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForLCDC(s32 lcdc){
+ gGXState.lcdc |= lcdc;
+ GX_VRAMCNT_SetLCDC_(lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubBG(s32 subbg){
+ gGXState.lcdc = (u16)(~subbg & (gGXState.lcdc | gGXState.sub_bg));
+ gGXState.sub_bg = subbg;
+ switch (subbg)
+ {
+ case 0: //needed to match
+ break;
+ case 4:
+ reg_GX_VRAMCNT_C = 0x84;
+ break;
+ case 384:
+ reg_GX_VRAMCNT_I = 0x81;
+ case 128:
+ reg_GX_VRAMCNT_H = 0x81;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+
+ARM_FUNC void GX_SetBankForSubOBJ(s32 subobj){
+ gGXState.lcdc = (u16)(~subobj & (gGXState.lcdc | gGXState.sub_obj));
+ gGXState.sub_obj = subobj;
+ switch (subobj)
+ {
+ case 8:
+ reg_GX_VRAMCNT_D = 0x84;
+ break;
+ case 256:
+ reg_GX_VRAMCNT_I = 0x82;
+ break;
+ case 0: //needed to match
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubBGExtPltt(s32 subbgextpltt){
+ gGXState.lcdc = (u16)(~subbgextpltt & (gGXState.lcdc | gGXState.sub_bgExtPltt));
+ gGXState.sub_bgExtPltt = subbgextpltt;
+ switch (subbgextpltt)
+ {
+ case 128:
+ reg_GXS_DB_DISPCNT |= 0x40000000;
+ reg_GX_VRAMCNT_H = 0x82;
+ break;
+ case 0:
+ reg_GXS_DB_DISPCNT &= ~0x40000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC void GX_SetBankForSubOBJExtPltt(s32 subobjextpltt){
+ gGXState.lcdc = (u16)(~subobjextpltt & (gGXState.lcdc | gGXState.sub_objExtPltt));
+ gGXState.sub_objExtPltt = subobjextpltt;
+ switch (subobjextpltt)
+ {
+ case 256:
+ reg_GXS_DB_DISPCNT |= 0x80000000;
+ reg_GX_VRAMCNT_I = 0x83;
+ break;
+ case 0:
+ reg_GXS_DB_DISPCNT &= ~0x80000000;
+ break;
+ }
+ GX_VRAMCNT_SetLCDC_(gGXState.lcdc);
+}
+
+ARM_FUNC u32 FUN_020C6130(u16 *ptr){
+ u16 temp = *ptr;
+ *ptr = 0;
+ gGXState.lcdc |= temp;
+ GX_VRAMCNT_SetLCDC_(temp);
+ return temp;
+}
+
+ARM_FUNC u32 GX_ResetBankForBG(){
+ return FUN_020C6130(&gGXState.bg);
+}
+
+ARM_FUNC u32 GX_ResetBankForOBJ(){
+ return FUN_020C6130(&gGXState.obj);
+}
+
+ARM_FUNC u32 GX_ResetBankForBGExtPltt(){
+ reg_GX_DISPCNT &= ~0x40000000;
+ return FUN_020C6130(&gGXState.bgExtPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForOBJExtPltt(){
+ reg_GX_DISPCNT &= ~0x80000000;
+ return FUN_020C6130(&gGXState.objExtPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForTex(){
+ return FUN_020C6130(&gGXState.tex);
+}
+
+ARM_FUNC u32 GX_ResetBankForTexPltt(){
+ return FUN_020C6130(&gGXState.texPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForClearImage(){
+ return FUN_020C6130(&gGXState.clrImg);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubBG(){
+ return FUN_020C6130(&gGXState.sub_bg);
+}
+
+ARM_FUNC u32 FUN_020C605C(){
+ return FUN_020C6130(&gGXState.sub_obj);
+}
+
+ARM_FUNC u32 FUN_020C6034(){
+ reg_GXS_DB_DISPCNT &= ~0x40000000;
+ return FUN_020C6130(&gGXState.sub_bgExtPltt);
+}
+
+ARM_FUNC u32 GX_ResetBankForSubOBJ(){
+ reg_GXS_DB_DISPCNT &= ~0x80000000;
+ return FUN_020C6130(&gGXState.sub_objExtPltt);
+}
+
+ARM_FUNC u32 FUN_020C5F28(u16 *ptr){
+ u32 temp = *ptr;
+ *ptr = 0;
+ if (temp & (0x1 << 0))
+ reg_GX_VRAMCNT_A = 0x0;
+ if (temp & (0x1 << 1))
+ reg_GX_VRAMCNT_B = 0x0;
+ if (temp & (0x1 << 2))
+ reg_GX_VRAMCNT_C = 0x0;
+ if (temp & (0x1 << 3))
+ reg_GX_VRAMCNT_D = 0x0;
+ if (temp & (0x1 << 4))
+ reg_GX_VRAMCNT_E = 0x0;
+ if (temp & (0x1 << 5))
+ reg_GX_VRAMCNT_F = 0x0;
+ if (temp & (0x1 << 6))
+ reg_GX_VRAMCNT_G = 0x0;
+ if (temp & (0x1 << 7))
+ reg_GX_VRAMCNT_H = 0x0;
+ if (temp & (0x1 << 8))
+ reg_GX_VRAMCNT_I = 0x0;
+ OSi_UnlockVram((u16)temp, GXi_VRamLockId);
+ return temp;
+}
+
+ARM_FUNC u32 disableBankForX_(){
+ return FUN_020C5F28(&gGXState.bg);
+}
+
+ARM_FUNC u32 GX_DisableBankForOBJExtPltt_2(){
+ return FUN_020C5F28(&gGXState.obj);
+}
+
+ARM_FUNC u32 GX_DisableBankForBGExtPltt(){
+ reg_GX_DISPCNT &= ~0x40000000;
+ return FUN_020C5F28(&gGXState.bgExtPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForOBJExtPltt(){
+ reg_GX_DISPCNT &= ~0x80000000;
+ return FUN_020C5F28(&gGXState.objExtPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForTexPltt_2(){
+ return FUN_020C5F28(&gGXState.tex);
+}
+
+ARM_FUNC u32 GX_DisableBankForTexPltt(){
+ return FUN_020C5F28(&gGXState.texPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForClearImage(){
+ return FUN_020C5F28(&gGXState.clrImg);
+}
+
+ARM_FUNC u32 GX_DisableBankForARM7(){
+ return FUN_020C5F28(&gGXState.arm7);
+}
+
+ARM_FUNC u32 GX_DisableBankForLCDC(){
+ return FUN_020C5F28(&gGXState.lcdc);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubBGExtPltt(){
+ return FUN_020C5F28(&gGXState.sub_bg);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubOBJExtPltt_2(){
+ return FUN_020C5F28(&gGXState.sub_obj);
+}
+
+ARM_FUNC u32 FUN_020C5E04(){
+ reg_GXS_DB_DISPCNT &= ~0x40000000;
+ return FUN_020C5F28(&gGXState.sub_bgExtPltt);
+}
+
+ARM_FUNC u32 GX_DisableBankForSubOBJExtPltt(){
+ reg_GXS_DB_DISPCNT &= ~0x80000000;
+ return FUN_020C5F28(&gGXState.sub_objExtPltt);
+}
+
+ARM_FUNC u32 GX_GetBankForBGExtPltt_2(){
+ return gGXState.bg;
+}
+
+ARM_FUNC u32 GX_GetBankForOBJ(){
+ return gGXState.obj;
+}
+
+ARM_FUNC u32 GX_GetBankForBGExtPltt(){
+ return gGXState.bgExtPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForOBJExtPltt(){
+ return gGXState.objExtPltt;
+}
+
+ARM_FUNC u32 FUN_020C5D8C(){
+ return gGXState.tex;
+}
+
+ARM_FUNC u32 GX_GetBankForTexPltt(){
+ return gGXState.texPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForLCDC(){
+ return gGXState.lcdc;
+}
+
+ARM_FUNC u32 GX_GetBankForSubBGExtPltt_2(){
+ return gGXState.sub_bg;
+}
+
+ARM_FUNC u32 GX_GetBankForSubOBJ(){
+ return gGXState.sub_obj;
+}
+
+ARM_FUNC u32 GX_GetBankForSubBGExtPltt(){
+ return gGXState.sub_bgExtPltt;
+}
+
+ARM_FUNC u32 GX_GetBankForSubOBJExtPltt(){
+ return gGXState.sub_objExtPltt;
+}
diff --git a/arm9/lib/src/OS_init.c b/arm9/lib/src/OS_init.c
index 7467c672..a1db8788 100644
--- a/arm9/lib/src/OS_init.c
+++ b/arm9/lib/src/OS_init.c
@@ -7,7 +7,6 @@
extern void PXI_Init();
extern void OS_InitLock();
-extern void OS_SetIrqStackChecker();
extern void OS_InitException();
extern void MI_Init();
extern void OS_InitVAlarm();
diff --git a/arm9/lib/src/OS_interrupt.c b/arm9/lib/src/OS_interrupt.c
index 1fb43821..76deb069 100644
--- a/arm9/lib/src/OS_interrupt.c
+++ b/arm9/lib/src/OS_interrupt.c
@@ -10,7 +10,6 @@
#pragma optimize_for_size on
extern OSThreadQueue OSi_IrqThreadQueue;
-extern OSIrqMask OS_EnableIrqMask(OSIrqMask intr);
ARM_FUNC void OS_InitIrqTable() {
OS_InitThreadQueue(&OSi_IrqThreadQueue);
@@ -87,3 +86,58 @@ ARM_FUNC void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), voi
(void)OS_EnableIrqMask(mask);
OSi_IrqCallbackInfo[timerNo + 4].enable = TRUE;
}
+
+ARM_FUNC OSIrqMask OS_SetIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIe = reg_OS_IE;
+ reg_OS_IE = mask;
+ u16 unused = reg_OS_IME; //needed because otherwise it doesn't match
+ reg_OS_IME = regIme;
+ return regIe;
+}
+
+ARM_FUNC OSIrqMask OS_EnableIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIe = reg_OS_IE;
+ reg_OS_IE = regIe | mask;
+ u16 unused = reg_OS_IME;
+ reg_OS_IME = regIme;
+ return regIe;
+}
+
+ARM_FUNC OSIrqMask OS_DisableIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIe = reg_OS_IE;
+ reg_OS_IE = regIe & ~mask;
+ u16 unused = reg_OS_IME;
+ reg_OS_IME = regIme;
+ return regIe;
+}
+
+ARM_FUNC OSIrqMask OS_ResetRequestIrqMask(OSIrqMask mask)
+{
+ u16 regIme = reg_OS_IME;
+ reg_OS_IME = 0;
+ OSIrqMask regIf = reg_OS_IF;
+ reg_OS_IF = mask;
+ u16 unused = reg_OS_IME;
+ reg_OS_IME = regIme;
+ return regIf;
+}
+
+extern void SDK_IRQ_STACKSIZE(void);
+
+#define OSi_IRQ_STACK_TOP (HW_DTCM_SVC_STACK - ((s32)SDK_IRQ_STACKSIZE))
+#define OSi_IRQ_STACK_BOTTOM HW_DTCM_SVC_STACK
+
+ARM_FUNC void OS_SetIrqStackChecker(void)
+{
+ *(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32)) = 0xfddb597dUL;
+ *(u32 *)(OSi_IRQ_STACK_TOP) = 0x7bf9dd5bUL;
+}
diff --git a/arm9/lib/src/OS_reset.c b/arm9/lib/src/OS_reset.c
index c21d20ab..d4254ce3 100644
--- a/arm9/lib/src/OS_reset.c
+++ b/arm9/lib/src/OS_reset.c
@@ -6,6 +6,7 @@
#include "OS_reset.h"
#include "MB_mb.h"
#include "OS_terminate_proc.h"
+#include "OS_interrupt.h"
extern u16 OSi_IsInitReset;
extern vu16 OSi_IsResetOccurred;
@@ -15,8 +16,6 @@ extern void PXI_SetFifoRecvCallback(u32 param1, void* callback);
extern u32 PXI_SendWordByFifo(u32 param1, u32 data, u32 param2);
extern void CARD_LockRom(u16 lockId);
extern void MI_StopDma(u32 dma);
-extern void OS_SetIrqMask(u32 mask);
-extern void OS_ResetRequestIrqMask(u32 mask);
extern void OSi_DoResetSystem(); //in itcm, should technically be in this file
ARM_FUNC void OS_InitReset() {
@@ -54,7 +53,7 @@ ARM_FUNC void OS_ResetSystem(u32 parameter) {
MI_StopDma(1);
MI_StopDma(2);
MI_StopDma(3);
- OS_SetIrqMask(0x40000);
+ (void)OS_SetIrqMask(0x40000);
OS_ResetRequestIrqMask((u32)~0);
*(u32 *)HW_RESET_PARAMETER_BUF = parameter;
OSi_SendToPxi(OS_PXI_COMMAND_RESET);