summaryrefslogtreecommitdiff
path: root/arm9/lib/src
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/src
parent6103ab0ca0962682095e58779079cb4c8c054b14 (diff)
parentde389305733545e2b6fac6c8dcb33d76a7446481 (diff)
Merge branch 'master' of github.com:martmists/pokediamond into pikalax_work
Diffstat (limited to 'arm9/lib/src')
-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
16 files changed, 2077 insertions, 5 deletions
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);