diff options
-rw-r--r-- | asm/gpu_regs.s | 373 | ||||
-rw-r--r-- | ld_script.txt | 2 | ||||
-rw-r--r-- | src/gpu_regs.c | 159 | ||||
-rw-r--r-- | sym_bss.txt | 18 |
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 |