diff --git a/asm/link.s b/asm/link.s index 5e5349f63d..ba7593695a 100644 --- a/asm/link.s +++ b/asm/link.s @@ -5,148 +5,6 @@ .text - thumb_func_start ResetBlockReceivedFlags -ResetBlockReceivedFlags: @ 800A5B4 - push {r4,lr} - ldr r0, =gSerialIsRFU - ldrb r0, [r0] - cmp r0, 0x1 - bne _0800A5D4 - movs r4, 0 -_0800A5C0: - lsls r0, r4, 24 - lsrs r0, 24 - bl sub_800F728 - adds r4, 0x1 - cmp r4, 0x4 - ble _0800A5C0 - b _0800A5E2 - .pool -_0800A5D4: - ldr r1, =gUnknown_0300307C - movs r2, 0 - adds r0, r1, 0x3 -_0800A5DA: - strb r2, [r0] - subs r0, 0x1 - cmp r0, r1 - bge _0800A5DA -_0800A5E2: - pop {r4} - pop {r0} - bx r0 - .pool - thumb_func_end ResetBlockReceivedFlags - - thumb_func_start ResetBlockReceivedFlag -ResetBlockReceivedFlag: @ 800A5EC - push {lr} - lsls r0, 24 - lsrs r1, r0, 24 - ldr r0, =gSerialIsRFU - ldrb r0, [r0] - cmp r0, 0x1 - bne _0800A608 - adds r0, r1, 0 - bl sub_800F728 - b _0800A616 - .pool -_0800A608: - ldr r0, =gUnknown_0300307C - adds r1, r0 - ldrb r0, [r1] - cmp r0, 0 - beq _0800A616 - movs r0, 0 - strb r0, [r1] -_0800A616: - pop {r0} - bx r0 - .pool - thumb_func_end ResetBlockReceivedFlag - - thumb_func_start sub_800A620 -sub_800A620: @ 800A620 - push {lr} - ldr r0, =gUnknown_030030E0 - ldr r1, [r0] - movs r0, 0x20 - ands r0, r1 - cmp r0, 0 - beq _0800A63C - movs r0, 0x1C - ands r1, r0 - cmp r1, 0x4 - bls _0800A63C - ldr r1, =gUnknown_03003144 - movs r0, 0x1 - strb r0, [r1] -_0800A63C: - pop {r0} - bx r0 - .pool - thumb_func_end sub_800A620 - - thumb_func_start sub_800A648 -sub_800A648: @ 800A648 - push {r4,lr} - adds r4, r0, 0 - lsls r1, 16 - movs r3, 0 - movs r2, 0 - lsrs r1, 17 - cmp r3, r1 - bcs _0800A66E -_0800A658: - lsls r0, r2, 1 - adds r0, r4 - ldrh r0, [r0] - adds r0, r3, r0 - lsls r0, 16 - lsrs r3, r0, 16 - adds r0, r2, 0x1 - lsls r0, 16 - lsrs r2, r0, 16 - cmp r2, r1 - bcc _0800A658 -_0800A66E: - adds r0, r3, 0 - pop {r4} - pop {r1} - bx r1 - thumb_func_end sub_800A648 - - thumb_func_start sub_800A678 -sub_800A678: @ 800A678 - push {r4,r5,lr} - lsls r0, 24 - lsrs r0, 24 - lsls r1, 24 - lsrs r1, 24 - lsls r2, 24 - ldr r4, =gUnknown_03003130 - ldr r3, [r4] - lsls r3, 11 - movs r5, 0xC0 - lsls r5, 19 - adds r3, r5 - lsrs r2, 19 - adds r2, r1 - lsls r2, 1 - adds r2, r3 - ldr r3, [r4, 0x4] - lsls r3, 12 - ldr r1, [r4, 0x8] - adds r1, 0x1 - adds r0, r1 - orrs r3, r0 - strh r3, [r2] - pop {r4,r5} - pop {r0} - bx r0 - .pool - thumb_func_end sub_800A678 - thumb_func_start sub_800A6B0 sub_800A6B0: @ 800A6B0 push {r4,r5,lr} diff --git a/include/link.h b/include/link.h index 8ec0431aa6..09e2789f58 100644 --- a/include/link.h +++ b/include/link.h @@ -2,6 +2,7 @@ #define GUARD_LINK_H #define MAX_LINK_PLAYERS 4 +#define MAX_RFU_PLAYERS 5 #define CMD_LENGTH 8 #define QUEUE_CAPACITY 50 #define BLOCK_BUFFER_SIZE 0x100 @@ -26,6 +27,18 @@ #define EXTRACT_RECEIVED_NOTHING(status) \ (((status) >> LINK_STAT_RECEIVED_NOTHING_SHIFT) & 1) +struct LinkStatus +{ + u32 localId:2; + u32 playerCount:3; + u32 master:1; + u32 connEstablished:1; + u32 unused_7:1; + u32 receivedNothing:1; + u32 unused_9:7; + u32 errors:7; +}; + #define MASTER_HANDSHAKE 0x8FFF #define SLAVE_HANDSHAKE 0xB9A0 @@ -138,7 +151,7 @@ extern u8 gUnknown_020228C4[BLOCK_BUFFER_SIZE]; // gBlockSendBuffer extern u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE]; extern u16 gLinkType; extern u32 gLinkStatus; -extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS + 1][BLOCK_BUFFER_SIZE / 2]; +extern u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2]; extern u16 gSendCmd[CMD_LENGTH]; extern u8 gShouldAdvanceLinkState; extern struct LinkPlayer gLinkPlayers[]; diff --git a/include/link_rfu.h b/include/link_rfu.h index ff71c65aad..71b35b25ce 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -9,16 +9,17 @@ u32 sub_800BEC0(void); void sub_800E700(void); void sub_800EDD4(void); +void sub_800F6FC(u8 who); +void sub_800F728(u8 who); bool32 sub_800F7E4(void); void sub_800F804(void); void sub_800F850(void); +u8 sub_800FCD8(void); +bool32 sub_800FE84(const void *src, size_t size); void Rfu_set_zero(void); u8 sub_80104F4(void); u8 rfu_get_multiplayer_id(void); -bool32 sub_800FE84(const void *src, size_t size); bool8 sub_8010100(u8 a0); bool8 sub_8010500(void); -u8 sub_800FCD8(void); -void sub_800F6FC(u8 who); #endif //GUARD_LINK_RFU_H diff --git a/src/link.c b/src/link.c index 68868491be..5320794981 100644 --- a/src/link.c +++ b/src/link.c @@ -97,14 +97,14 @@ u8 gUnknown_03003160; EWRAM_DATA u8 gUnknown_020223BC = 0; EWRAM_DATA u8 gUnknown_020223BD = 0; EWRAM_DATA u32 gUnknown_020223C0 = 0; -EWRAM_DATA u16 gBlockRecvBuffer[MAX_LINK_PLAYERS + 1][BLOCK_BUFFER_SIZE / 2] = {}; +EWRAM_DATA u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2] = {}; EWRAM_DATA u8 gUnknown_020228C4[BLOCK_BUFFER_SIZE] = {}; EWRAM_DATA bool8 gUnknown_020229C4 = FALSE; EWRAM_DATA u16 gUnknown_020229C6 = 0; EWRAM_DATA u16 gUnknown_020229C8 = 0; EWRAM_DATA struct LinkPlayer gUnknown_020229CC = {}; -EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_LINK_PLAYERS + 1] = {}; -EWRAM_DATA struct LinkPlayer gUnknown_02022A74[MAX_LINK_PLAYERS + 1] = {}; +EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS] = {}; +EWRAM_DATA struct LinkPlayer gUnknown_02022A74[MAX_RFU_PLAYERS] = {}; // Static ROM declarations @@ -120,7 +120,7 @@ static void sub_800A388(void); static void sub_800A3EC(void); void task00_link_test(u8 taskId); void sub_800A588(u8 who); -u16 sub_800A648(u16 *src, u16 size); +u16 sub_800A648(const u16 *src, u16 size); void sub_800A6E8(u32 pos, u8 a0, u8 a1, u8 a2); void sub_800A824(void); void c2_800ACD4(void); @@ -449,7 +449,7 @@ u16 sub_80099E0(const u16 *src) gUnknown_03003110[i] = 0; } gUnknown_03003084 = *src; - if (gUnknown_030030E0 & 0x40) + if (gUnknown_030030E0 & LINK_STAT_CONN_ESTABLISHED) { sub_8009AA0(SIO_MULTI_CNT->id); if (gUnknown_03003140 != NULL) @@ -627,7 +627,7 @@ void sub_8009D90(u16 command) u8 i; gUnknown_03003110[0] = 0x7777; - for (i = 0; i < 5; i ++) + for (i = 0; i < MAX_RFU_PLAYERS; i ++) { gUnknown_03003110[i + 1] = 0xEE; } @@ -1071,3 +1071,64 @@ void sub_800A588(u8 who) gUnknown_0300307C[who] = TRUE; } } + +void ResetBlockReceivedFlags(void) +{ + int i; + + if (gSerialIsRFU == TRUE) + { + for (i = 0; i < MAX_RFU_PLAYERS; i ++) + { + sub_800F728(i); + } + } + else + { + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + gUnknown_0300307C[i] = FALSE; + } + } +} + +void ResetBlockReceivedFlag(u8 who) +{ + if (gSerialIsRFU == TRUE) + { + sub_800F728(who); + } + else if (gUnknown_0300307C[who]) + { + gUnknown_0300307C[who] = FALSE; + } +} + +void sub_800A620(void) +{ + if ((gUnknown_030030E0 & LINK_STAT_MASTER) && EXTRACT_PLAYER_COUNT(gUnknown_030030E0) > 1) + { + gUnknown_03003144 = TRUE; + } +} + +u16 sub_800A648(const u16 *data, u16 size) +{ + u16 chksum; + u16 i; + + chksum = 0; + for (i = 0; i < size / 2; i ++) + { + chksum += data[i]; + } + return chksum; +} + +void sub_800A678(u8 a0, u8 a1, u8 a2) +{ + u16 *vAddr; + + vAddr = (u16 *)BG_SCREEN_ADDR(gUnknown_03003130.screenBaseBlock); + vAddr[a2 * 32 + a1] = (gUnknown_03003130.paletteNum << 12) | (a0 + 1 + gUnknown_03003130.dummy_8); +}