summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/gpu_regs.s373
-rw-r--r--ld_script.txt2
-rw-r--r--src/gpu_regs.c159
-rw-r--r--sym_bss.txt18
4 files changed, 162 insertions, 390 deletions
diff --git a/asm/gpu_regs.s b/asm/gpu_regs.s
deleted file mode 100644
index 999a6b9fc..000000000
--- a/asm/gpu_regs.s
+++ /dev/null
@@ -1,373 +0,0 @@
- .include "asm/macros.inc"
- .include "constants/constants.inc"
-
- .syntax unified
-
- .text
-
- thumb_func_start InitGpuRegManager
-InitGpuRegManager: @ 8000968
- push {r4-r7,lr}
- mov r7, r8
- push {r7}
- movs r2, 0
- ldr r7, _080009AC @ =gUnknown_30000C0
- ldr r0, _080009B0 @ =gUnknown_30000C1
- mov r12, r0
- ldr r1, _080009B4 @ =gUnknown_30000C2
- mov r8, r1
- ldr r6, _080009B8 @ =gUnknown_3000000
- movs r5, 0
- ldr r4, _080009BC @ =gUnknown_3000060
- movs r3, 0xFF
-_08000982:
- adds r0, r2, r6
- strb r5, [r0]
- adds r1, r2, r4
- ldrb r0, [r1]
- orrs r0, r3
- strb r0, [r1]
- adds r2, 0x1
- cmp r2, 0x5F
- ble _08000982
- movs r0, 0
- strb r0, [r7]
- mov r1, r12
- strb r0, [r1]
- movs r0, 0
- mov r1, r8
- strh r0, [r1]
- pop {r3}
- mov r8, r3
- pop {r4-r7}
- pop {r0}
- bx r0
- .align 2, 0
-_080009AC: .4byte gUnknown_30000C0
-_080009B0: .4byte gUnknown_30000C1
-_080009B4: .4byte gUnknown_30000C2
-_080009B8: .4byte gUnknown_3000000
-_080009BC: .4byte gUnknown_3000060
- thumb_func_end InitGpuRegManager
-
- thumb_func_start CopyBufferedValueToGpuReg
-CopyBufferedValueToGpuReg: @ 80009C0
- push {lr}
- lsls r0, 24
- lsrs r2, r0, 24
- cmp r2, 0x4
- bne _080009EC
- ldr r2, _080009E0 @ =0x04000004
- ldrh r1, [r2]
- ldr r0, _080009E4 @ =0x0000ffe7
- ands r0, r1
- strh r0, [r2]
- ldr r1, _080009E8 @ =gUnknown_3000004
- ldrh r0, [r2]
- ldrh r1, [r1]
- orrs r0, r1
- strh r0, [r2]
- b _080009FA
- .align 2, 0
-_080009E0: .4byte 0x04000004
-_080009E4: .4byte 0x0000ffe7
-_080009E8: .4byte gUnknown_3000004
-_080009EC:
- movs r0, 0x80
- lsls r0, 19
- adds r0, r2, r0
- ldr r1, _08000A00 @ =gUnknown_3000000
- adds r1, r2, r1
- ldrh r1, [r1]
- strh r1, [r0]
-_080009FA:
- pop {r0}
- bx r0
- .align 2, 0
-_08000A00: .4byte gUnknown_3000000
- thumb_func_end CopyBufferedValueToGpuReg
-
- thumb_func_start CopyBufferedValuesToGpuRegs
-CopyBufferedValuesToGpuRegs: @ 8000A04
- push {r4,r5,lr}
- ldr r0, _08000A30 @ =gUnknown_30000C0
- ldrb r0, [r0]
- cmp r0, 0
- bne _08000A28
- movs r5, 0
-_08000A10:
- ldr r0, _08000A34 @ =gUnknown_3000060
- adds r4, r5, r0
- ldrb r0, [r4]
- cmp r0, 0xFF
- beq _08000A28
- bl CopyBufferedValueToGpuReg
- movs r0, 0xFF
- strb r0, [r4]
- adds r5, 0x1
- cmp r5, 0x5F
- ble _08000A10
-_08000A28:
- pop {r4,r5}
- pop {r0}
- bx r0
- .align 2, 0
-_08000A30: .4byte gUnknown_30000C0
-_08000A34: .4byte gUnknown_3000060
- thumb_func_end CopyBufferedValuesToGpuRegs
-
- thumb_func_start SetGpuReg
-SetGpuReg: @ 8000A38
- push {r4,r5,lr}
- lsls r0, 24
- lsrs r4, r0, 24
- lsls r1, 16
- lsrs r1, 16
- cmp r4, 0x5F
- bhi _08000AB4
- ldr r0, _08000A74 @ =gUnknown_3000000
- adds r0, r4, r0
- strh r1, [r0]
- ldr r0, _08000A78 @ =0x04000006
- ldrh r1, [r0]
- movs r0, 0xFF
- ands r0, r1
- subs r0, 0xA1
- lsls r0, 16
- lsrs r0, 16
- cmp r0, 0x40
- bls _08000A6C
- movs r0, 0x80
- lsls r0, 19
- ldrh r1, [r0]
- movs r0, 0x80
- ands r0, r1
- cmp r0, 0
- beq _08000A82
-_08000A6C:
- adds r0, r4, 0
- bl CopyBufferedValueToGpuReg
- b _08000AB4
- .align 2, 0
-_08000A74: .4byte gUnknown_3000000
-_08000A78: .4byte 0x04000006
-_08000A7C:
- movs r0, 0
- strb r0, [r5]
- b _08000AB4
-_08000A82:
- ldr r2, _08000ABC @ =gUnknown_30000C0
- movs r0, 0x1
- strb r0, [r2]
- movs r3, 0
- ldr r0, _08000AC0 @ =gUnknown_3000060
- ldrb r1, [r0]
- adds r5, r2, 0
- adds r2, r0, 0
- cmp r1, 0xFF
- beq _08000AAC
- adds r1, r2, 0
-_08000A98:
- ldrb r0, [r1]
- cmp r0, r4
- beq _08000A7C
- adds r1, 0x1
- adds r3, 0x1
- cmp r3, 0x5F
- bgt _08000AAC
- ldrb r0, [r1]
- cmp r0, 0xFF
- bne _08000A98
-_08000AAC:
- adds r0, r3, r2
- movs r1, 0
- strb r4, [r0]
- strb r1, [r5]
-_08000AB4:
- pop {r4,r5}
- pop {r0}
- bx r0
- .align 2, 0
-_08000ABC: .4byte gUnknown_30000C0
-_08000AC0: .4byte gUnknown_3000060
- thumb_func_end SetGpuReg
-
- thumb_func_start GetGpuReg
-GetGpuReg: @ 8000AC4
- push {lr}
- lsls r0, 24
- lsrs r0, 24
- adds r1, r0, 0
- cmp r1, 0x4
- bne _08000AD8
- ldr r0, _08000AD4 @ =0x04000004
- b _08000AEA
- .align 2, 0
-_08000AD4: .4byte 0x04000004
-_08000AD8:
- cmp r1, 0x6
- beq _08000AE8
- ldr r0, _08000AE4 @ =gUnknown_3000000
- adds r0, r1, r0
- ldrh r0, [r0]
- b _08000AEC
- .align 2, 0
-_08000AE4: .4byte gUnknown_3000000
-_08000AE8:
- ldr r0, _08000AF0 @ =0x04000006
-_08000AEA:
- ldrh r0, [r0]
-_08000AEC:
- pop {r1}
- bx r1
- .align 2, 0
-_08000AF0: .4byte 0x04000006
- thumb_func_end GetGpuReg
-
- thumb_func_start SetGpuRegBits
-SetGpuRegBits: @ 8000AF4
- push {lr}
- adds r2, r1, 0
- lsls r0, 24
- lsrs r0, 24
- ldr r1, _08000B10 @ =gUnknown_3000000
- adds r1, r0, r1
- ldrh r1, [r1]
- orrs r1, r2
- lsls r1, 16
- lsrs r1, 16
- bl SetGpuReg
- pop {r0}
- bx r0
- .align 2, 0
-_08000B10: .4byte gUnknown_3000000
- thumb_func_end SetGpuRegBits
-
- thumb_func_start ClearGpuRegBits
-ClearGpuRegBits: @ 8000B14
- push {lr}
- adds r2, r1, 0
- lsls r0, 24
- lsrs r0, 24
- lsls r2, 16
- ldr r1, _08000B30 @ =gUnknown_3000000
- adds r1, r0, r1
- ldrh r1, [r1]
- lsrs r2, 16
- bics r1, r2
- bl SetGpuReg
- pop {r0}
- bx r0
- .align 2, 0
-_08000B30: .4byte gUnknown_3000000
- thumb_func_end ClearGpuRegBits
-
- thumb_func_start SyncRegIE
-SyncRegIE: @ 8000B34
- push {r4,r5,lr}
- ldr r5, _08000B58 @ =gUnknown_30000C1
- ldrb r0, [r5]
- cmp r0, 0
- beq _08000B52
- ldr r2, _08000B5C @ =0x04000208
- ldrh r1, [r2]
- movs r4, 0
- strh r4, [r2]
- ldr r3, _08000B60 @ =0x04000200
- ldr r0, _08000B64 @ =gUnknown_30000C2
- ldrh r0, [r0]
- strh r0, [r3]
- strh r1, [r2]
- strb r4, [r5]
-_08000B52:
- pop {r4,r5}
- pop {r0}
- bx r0
- .align 2, 0
-_08000B58: .4byte gUnknown_30000C1
-_08000B5C: .4byte 0x04000208
-_08000B60: .4byte 0x04000200
-_08000B64: .4byte gUnknown_30000C2
- thumb_func_end SyncRegIE
-
- thumb_func_start EnableInterrupts
-EnableInterrupts: @ 8000B68
- push {r4,lr}
- lsls r0, 16
- lsrs r0, 16
- ldr r4, _08000B8C @ =gUnknown_30000C2
- ldrh r1, [r4]
- orrs r0, r1
- strh r0, [r4]
- ldr r1, _08000B90 @ =gUnknown_30000C1
- movs r0, 0x1
- strb r0, [r1]
- bl SyncRegIE
- ldrh r0, [r4]
- bl UpdateRegDispstatIntrBits
- pop {r4}
- pop {r0}
- bx r0
- .align 2, 0
-_08000B8C: .4byte gUnknown_30000C2
-_08000B90: .4byte gUnknown_30000C1
- thumb_func_end EnableInterrupts
-
- thumb_func_start DisableInterrupts
-DisableInterrupts: @ 8000B94
- push {r4,lr}
- lsls r0, 16
- lsrs r0, 16
- ldr r4, _08000BB8 @ =gUnknown_30000C2
- ldrh r1, [r4]
- bics r1, r0
- strh r1, [r4]
- ldr r1, _08000BBC @ =gUnknown_30000C1
- movs r0, 0x1
- strb r0, [r1]
- bl SyncRegIE
- ldrh r0, [r4]
- bl UpdateRegDispstatIntrBits
- pop {r4}
- pop {r0}
- bx r0
- .align 2, 0
-_08000BB8: .4byte gUnknown_30000C2
-_08000BBC: .4byte gUnknown_30000C1
- thumb_func_end DisableInterrupts
-
- thumb_func_start UpdateRegDispstatIntrBits
-UpdateRegDispstatIntrBits: @ 8000BC0
- push {r4,lr}
- adds r4, r0, 0
- lsls r4, 16
- lsrs r4, 16
- movs r0, 0x4
- bl GetGpuReg
- movs r2, 0x18
- ands r2, r0
- movs r1, 0x1
- ands r1, r4
- negs r0, r1
- orrs r0, r1
- asrs r1, r0, 31
- movs r0, 0x8
- ands r1, r0
- movs r0, 0x2
- ands r0, r4
- cmp r0, 0
- beq _08000BEC
- movs r0, 0x10
- orrs r1, r0
-_08000BEC:
- cmp r2, r1
- beq _08000BF6
- movs r0, 0x4
- bl SetGpuReg
-_08000BF6:
- pop {r4}
- pop {r0}
- bx r0
- thumb_func_end UpdateRegDispstatIntrBits
-
- .align 2, 0 @ Don't pad with nop.
diff --git a/ld_script.txt b/ld_script.txt
index 7968c5b4a..c04338479 100644
--- a/ld_script.txt
+++ b/ld_script.txt
@@ -83,7 +83,7 @@ SECTIONS {
{
asm/crt0.o(.text);
src/main.o(.text);
- asm/gpu_regs.o(.text);
+ src/gpu_regs.o(.text);
asm/dma3_manager.o(.text);
asm/bg.o(.text);
asm/malloc.o(.text);
diff --git a/src/gpu_regs.c b/src/gpu_regs.c
new file mode 100644
index 000000000..a7030732b
--- /dev/null
+++ b/src/gpu_regs.c
@@ -0,0 +1,159 @@
+#include "global.h"
+#include "gpu_regs.h"
+
+#define GPU_REG_BUF_SIZE 0x60
+
+#define GPU_REG_BUF(offset) (*(u16 *)(&sGpuRegBuffer[offset]))
+#define GPU_REG(offset) (*(vu16 *)(REG_BASE + offset))
+
+#define EMPTY_SLOT 0xFF
+
+static u8 sGpuRegBuffer[GPU_REG_BUF_SIZE];
+static u8 sGpuRegWaitingList[GPU_REG_BUF_SIZE];
+static bool8 sGpuRegBufferLocked;
+static bool8 sShouldSyncRegIE;
+static u16 sRegIE;
+
+static void CopyBufferedValueToGpuReg(u8 regOffset);
+static void SyncRegIE(void);
+static void UpdateRegDispstatIntrBits(u16 regIE);
+
+void InitGpuRegManager(void)
+{
+ s32 i;
+
+ for (i = 0; i < GPU_REG_BUF_SIZE; i++)
+ {
+ sGpuRegBuffer[i] = 0;
+ sGpuRegWaitingList[i] = EMPTY_SLOT;
+ }
+
+ sGpuRegBufferLocked = FALSE;
+ sShouldSyncRegIE = FALSE;
+ sRegIE = 0;
+}
+
+static void CopyBufferedValueToGpuReg(u8 regOffset)
+{
+ if (regOffset == REG_OFFSET_DISPSTAT)
+ {
+ REG_DISPSTAT &= ~(DISPSTAT_HBLANK_INTR | DISPSTAT_VBLANK_INTR);
+ REG_DISPSTAT |= GPU_REG_BUF(REG_OFFSET_DISPSTAT);
+ }
+ else
+ {
+ GPU_REG(regOffset) = GPU_REG_BUF(regOffset);
+ }
+}
+
+void CopyBufferedValuesToGpuRegs(void)
+{
+ if (!sGpuRegBufferLocked)
+ {
+ s32 i;
+
+ for (i = 0; i < GPU_REG_BUF_SIZE; i++)
+ {
+ u8 regOffset = sGpuRegWaitingList[i];
+ if (regOffset == EMPTY_SLOT)
+ return;
+ CopyBufferedValueToGpuReg(regOffset);
+ sGpuRegWaitingList[i] = EMPTY_SLOT;
+ }
+ }
+}
+
+void SetGpuReg(u8 regOffset, u16 value)
+{
+ if (regOffset < GPU_REG_BUF_SIZE)
+ {
+ u16 vcount;
+
+ GPU_REG_BUF(regOffset) = value;
+ vcount = REG_VCOUNT & 0xFF;
+
+ if ((vcount >= 161 && vcount <= 225)
+ || (REG_DISPCNT & DISPCNT_FORCED_BLANK)) {
+ CopyBufferedValueToGpuReg(regOffset);
+ } else {
+ s32 i;
+
+ sGpuRegBufferLocked = TRUE;
+
+ for (i = 0; i < GPU_REG_BUF_SIZE && sGpuRegWaitingList[i] != EMPTY_SLOT; i++) {
+ if (sGpuRegWaitingList[i] == regOffset) {
+ sGpuRegBufferLocked = FALSE;
+ return;
+ }
+ }
+
+ sGpuRegWaitingList[i] = regOffset;
+ sGpuRegBufferLocked = FALSE;
+ }
+ }
+}
+
+u16 GetGpuReg(u8 regOffset)
+{
+ if (regOffset == REG_OFFSET_DISPSTAT)
+ return REG_DISPSTAT;
+
+ if (regOffset == REG_OFFSET_VCOUNT)
+ return REG_VCOUNT;
+
+ return GPU_REG_BUF(regOffset);
+}
+
+void SetGpuRegBits(u8 regOffset, u16 mask)
+{
+ u16 regValue = GPU_REG_BUF(regOffset);
+ SetGpuReg(regOffset, regValue | mask);
+}
+
+void ClearGpuRegBits(u8 regOffset, u16 mask)
+{
+ u16 regValue = GPU_REG_BUF(regOffset);
+ SetGpuReg(regOffset, regValue & ~mask);
+}
+
+static void SyncRegIE(void)
+{
+ if (sShouldSyncRegIE) {
+ u16 temp = REG_IME;
+ REG_IME = 0;
+ REG_IE = sRegIE;
+ REG_IME = temp;
+ sShouldSyncRegIE = FALSE;
+ }
+}
+
+void EnableInterrupts(u16 mask)
+{
+ sRegIE |= mask;
+ sShouldSyncRegIE = TRUE;
+ SyncRegIE();
+ UpdateRegDispstatIntrBits(sRegIE);
+}
+
+void DisableInterrupts(u16 mask)
+{
+ sRegIE &= ~mask;
+ sShouldSyncRegIE = TRUE;
+ SyncRegIE();
+ UpdateRegDispstatIntrBits(sRegIE);
+}
+
+static void UpdateRegDispstatIntrBits(u16 regIE)
+{
+ u16 oldValue = GetGpuReg(REG_OFFSET_DISPSTAT) & (DISPSTAT_HBLANK_INTR | DISPSTAT_VBLANK_INTR);
+ u16 newValue = 0;
+
+ if (regIE & INTR_FLAG_VBLANK)
+ newValue |= DISPSTAT_VBLANK_INTR;
+
+ if (regIE & INTR_FLAG_HBLANK)
+ newValue |= DISPSTAT_HBLANK_INTR;
+
+ if (oldValue != newValue)
+ SetGpuReg(REG_OFFSET_DISPSTAT, newValue);
+}
diff --git a/sym_bss.txt b/sym_bss.txt
index 6ae993011..a4d2e870d 100644
--- a/sym_bss.txt
+++ b/sym_bss.txt
@@ -1,20 +1,6 @@
-gUnknown_3000000: @ 3000000
- .space 0x4
-
-gUnknown_3000004: @ 3000004
- .space 0x5C
-
-gUnknown_3000060: @ 3000060
- .space 0x60
-
-gUnknown_30000C0: @ 30000C0
- .space 0x1
-
-gUnknown_30000C1: @ 30000C1
- .space 0x1
+ .include "src/gpu_regs.o"
-gUnknown_30000C2: @ 30000C2
- .space 0x6
+ .space 0x4
gUnknown_30000C8: @ 30000C8
.space 0xC