diff --git a/asm/link.s b/asm/link.s index 291f71a57..d4b76a96e 100644 --- a/asm/link.s +++ b/asm/link.s @@ -5,141 +5,6 @@ .text - thumb_func_start sub_80093CC -sub_80093CC: @ 80093CC - push {lr} - bl sub_800B488 - bl sub_800E700 - bl sub_800BEC0 - ldr r1, =0x00008001 - cmp r0, r1 - beq _080093F4 - bl sub_800B4A4 - bl sub_80097E8 - bl RestoreSerialTimer3IntrHandlers - movs r0, 0 - b _080093FE - .pool -_080093F4: - bl rfu_REQ_stopMode - bl rfu_waitREQComplete - movs r0, 0x1 -_080093FE: - pop {r1} - bx r1 - thumb_func_end sub_80093CC - - thumb_func_start sub_8009404 -sub_8009404: @ 8009404 - push {lr} - lsls r0, 24 - lsrs r0, 24 - bl DestroyTask - pop {r0} - bx r0 - thumb_func_end sub_8009404 - - thumb_func_start sub_8009414 -sub_8009414: @ 8009414 - push {r4-r7,lr} - mov r7, r8 - push {r7} - adds r5, r0, 0 - ldr r4, [sp, 0x18] - lsls r5, 24 - lsrs r5, 24 - lsls r1, 24 - lsrs r1, 24 - mov r8, r1 - lsls r2, 24 - lsrs r6, r2, 24 - lsls r3, 24 - lsrs r7, r3, 24 - lsls r4, 16 - lsrs r4, 16 - ldr r0, =gLinkTestDigitsPal - lsls r1, r5, 4 - movs r2, 0x20 - bl LoadPalette - ldr r3, =0x040000d4 - ldr r0, =gLinkTestDigitsGfx - str r0, [r3] - lsls r2, r7, 14 - lsls r0, r4, 5 - movs r1, 0xC0 - lsls r1, 19 - adds r0, r1 - adds r2, r0 - str r2, [r3, 0x4] - ldr r0, =0x80000110 - str r0, [r3, 0x8] - ldr r0, [r3, 0x8] - ldr r0, =gUnknown_03003130 - str r6, [r0] - str r5, [r0, 0x4] - str r4, [r0, 0x8] - mov r0, r8 - cmp r0, 0x2 - beq _0800949E - cmp r0, 0x2 - bgt _08009484 - cmp r0, 0x1 - beq _0800948C - b _080094C0 - .pool -_08009484: - mov r0, r8 - cmp r0, 0x3 - beq _080094B0 - b _080094C0 -_0800948C: - lsls r1, r6, 8 - movs r0, 0x1 - orrs r1, r0 - lsls r0, r7, 2 - orrs r1, r0 - movs r0, 0xA - bl SetGpuReg - b _080094C0 -_0800949E: - lsls r1, r6, 8 - movs r0, 0x1 - orrs r1, r0 - lsls r0, r7, 2 - orrs r1, r0 - movs r0, 0xC - bl SetGpuReg - b _080094C0 -_080094B0: - lsls r1, r6, 8 - movs r0, 0x1 - orrs r1, r0 - lsls r0, r7, 2 - orrs r1, r0 - movs r0, 0xE - bl SetGpuReg -_080094C0: - mov r0, r8 - lsls r4, r0, 2 - adds r0, r4, 0 - adds r0, 0x10 - lsls r0, 24 - lsrs r0, 24 - movs r1, 0 - bl SetGpuReg - adds r4, 0x12 - lsls r4, 24 - lsrs r4, 24 - adds r0, r4, 0 - movs r1, 0 - bl SetGpuReg - pop {r3} - mov r8, r3 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_8009414 - thumb_func_start sub_80094EC sub_80094EC: @ 80094EC push {r4-r6,lr} diff --git a/common_syms/link.txt b/common_syms/link.txt new file mode 100644 index 000000000..22e3081ee --- /dev/null +++ b/common_syms/link.txt @@ -0,0 +1 @@ +gUnknown_03003130 diff --git a/data/link.s b/data/link.s index d9cf886c5..578ae0256 100644 --- a/data/link.s +++ b/data/link.s @@ -5,22 +5,6 @@ .section .rodata - .align 2 -gWirelessLinkDisplayPal:: @ 82EC86C - .incbin "graphics/interface/wireless_link_display.gbapal" - -gWirelessLinkDisplayGfx:: @ 82EC88C - .incbin "graphics/interface/wireless_link_display.4bpp.lz" - -gWirelessLinkDisplayTilemap:: @ 82ECD34 - .incbin "graphics/interface/wireless_link_display.bin.lz" - -gLinkTestDigitsPal:: @ 82ECF20 - .incbin "graphics/interface/link_test_digits.gbapal" - -gLinkTestDigitsGfx:: @ 82ECF40 - .incbin "graphics/interface/link_test_digits.4bpp" - .string "{HIGHLIGHT TRANSPARENT}{COLOR WHITE}$" .align 2 diff --git a/include/gba/io_reg.h b/include/gba/io_reg.h index f86f2434c..998e68e16 100644 --- a/include/gba/io_reg.h +++ b/include/gba/io_reg.h @@ -584,6 +584,23 @@ #define TIMER_INTR_ENABLE 0x40 #define TIMER_ENABLE 0x80 +// BGCNT +#define BGCNT_PRIORITY(n) (n) // Values 0 - 3. Lower priority BGs will be drawn on top of higher priority BGs. +#define BGCNT_CHARBASE(n) ((n) << 2) // Values 0 - 3. Base block for tile pixel data. +#define BGCNT_MOSAIC 0x0040 +#define BGCNT_16COLOR 0x0000 // 4 bits per pixel +#define BGCNT_256COLOR 0x0080 // 8 bits per pixel +#define BGCNT_SCREENBASE(n) ((n) << 8) // Values 0 - 31. Base block for tile map. +#define BGCNT_WRAP 0x2000 // Only affects affine BGs. Text BGs wrap by default. +#define BGCNT_TXT256x256 0x0000 // Internal screen size size of text mode BG in pixels. +#define BGCNT_TXT512x256 0x4000 +#define BGCNT_TXT256x512 0x8000 +#define BGCNT_TXT512x512 0xC000 +#define BGCNT_AFF128x128 0x0000 // Internal screen size size of affine mode BG in pixels. +#define BGCNT_AFF256x256 0x4000 +#define BGCNT_AFF512x512 0x8000 +#define BGCNT_AFF1024x1024 0xC000 + // serial #define SIO_ID 0x0030 // Communication ID diff --git a/include/librfu.h b/include/librfu.h index dbc8a41a6..0cf781d73 100644 --- a/include/librfu.h +++ b/include/librfu.h @@ -106,3 +106,5 @@ struct RfuIntrStruct extern struct RfuStruct *gRfuState; void STWI_init_all(struct RfuIntrStruct *interruptStruct, IntrFunc *interrupt, bool8 copyInterruptToRam); +void rfu_REQ_stopMode(void); +void rfu_waitREQComplete(void); diff --git a/include/link.h b/include/link.h index 7a6563144..64bb8ff47 100644 --- a/include/link.h +++ b/include/link.h @@ -193,4 +193,8 @@ u8 sub_800ABAC(void); u8 sub_800ABBC(void); void sub_800AC34(void); +void sub_80097E8(void); + +extern IWRAM_DATA u32 gUnknown_03003130[3]; // common + #endif // GUARD_LINK_H diff --git a/include/main.h b/include/main.h index e283d1754..46c8fd681 100644 --- a/include/main.h +++ b/include/main.h @@ -60,5 +60,6 @@ void SetSerialCallback(IntrCallback callback); void InitFlashTimer(void); void DoSoftReset(void); void ClearPokemonCrySongs(void); +void RestoreSerialTimer3IntrHandlers(void); #endif // GUARD_MAIN_H diff --git a/ld_script.txt b/ld_script.txt index c8d31c846..34b9a7722 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -51,6 +51,7 @@ SECTIONS { src/text.o(.text); src/sprite.o(.text); src/string_util.o(.text); + src/link.o(.text); asm/link.o(.text); src/rtc.o(.text); asm/main_menu.o(.text); @@ -327,6 +328,7 @@ SECTIONS { src/sprite.o(.rodata); data/io_reg.o(.rodata); src/string_util.o(.rodata); + src/link.o(.rodata); data/link.o(.rodata); src/rtc.o(.rodata); data/main_menu.o(.rodata); diff --git a/src/link.c b/src/link.c index ae2cd1992..0b7002124 100644 --- a/src/link.c +++ b/src/link.c @@ -1,6 +1,11 @@ // Includes #include "global.h" +#include "librfu.h" +#include "gpu_regs.h" +#include "palette.h" +#include "task.h" +#include "link.h" // Static type declarations @@ -31,17 +36,17 @@ IWRAM_DATA u32 gUnknown_03000D54; IWRAM_DATA u8 gUnknown_03000D58; IWRAM_DATA u32 gUnknown_03000D5C; IWRAM_DATA u32 gUnknown_03000D60; -IWRAM_DATA u8 gUnknown_03000D64[4]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D68[4]; +IWRAM_DATA u8 gUnknown_03000D64; +ALIGNED() IWRAM_DATA u8 gUnknown_03000D68[4]; IWRAM_DATA u8 gUnknown_03000D6C; IWRAM_DATA bool8 gUnknown_03000D6D; IWRAM_DATA u16 gUnknown_03000D6E; IWRAM_DATA u16 gUnknown_03000D70; IWRAM_DATA u8 gUnknown_03000D72; IWRAM_DATA u8 gUnknown_03000D73; -IWRAM_DATA u8 gUnknown_03000D74[4]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D78[8]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D80[16]; +IWRAM_DATA u8 gUnknown_03000D74; +ALIGNED() IWRAM_DATA u8 gUnknown_03000D78; +ALIGNED(8) IWRAM_DATA u8 gUnknown_03000D80[16]; IWRAM_DATA u16 gUnknown_03000D90[8]; IWRAM_DATA u32 gUnknown_03000DA0; IWRAM_DATA u32 gUnknown_03000DA4; @@ -51,6 +56,60 @@ IWRAM_DATA bool32 gUnknown_03000DB0; // Static ROM declarations +void sub_800E700(void); +u32 sub_800BEC0(void); +void sub_800B4A4(void); + // .rodata +ALIGNED(4) const u16 gWirelessLinkDisplayPal[] = INCBIN_U16("graphics/interface/wireless_link_display.gbapal"); +const u8 gWirelessLinkDisplayGfx[] = INCBIN_U8("graphics/interface/wireless_link_display.4bpp.lz"); +const u8 gWirelessLinkDisplayTilemap[] = INCBIN_U8("graphics/interface/wireless_link_display.bin.lz"); +const u16 gLinkTestDigitsPal[] = INCBIN_U16("graphics/interface/link_test_digits.gbapal"); +const u16 gLinkTestDigitsGfx[] = INCBIN_U16("graphics/interface/link_test_digits.4bpp"); + // .text + +bool8 sub_80093CC(void) +{ + sub_800B488(); + sub_800E700(); + if (sub_800BEC0() == 0x8001) + { + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + return TRUE; + } + sub_800B4A4(); + sub_80097E8(); + RestoreSerialTimer3IntrHandlers(); + return FALSE; +} + +void sub_8009404(u8 taskId) +{ + DestroyTask(taskId); +} + +void sub_8009414(u8 a0, u8 a1, u8 a2, u8 a3, u16 a4) +{ + LoadPalette(gLinkTestDigitsPal, a0 * 16, 0x20); + DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(a3) + (16 * a4), sizeof gLinkTestDigitsGfx); + gUnknown_03003130[0] = a2; + gUnknown_03003130[1] = a0; + gUnknown_03003130[2] = a4; + switch (a1) + { + case 1: + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_SCREENBASE(a2) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(a3)); + break; + case 2: + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_SCREENBASE(a2) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(a3)); + break; + case 3: + SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_SCREENBASE(a2) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(a3)); + break; + } + SetGpuReg(REG_OFFSET_BG0HOFS + a1 * 4, 0); + SetGpuReg(REG_OFFSET_BG0VOFS + a1 * 4, 0); +}