diff --git a/asm/link.s b/asm/link.s index 3188bcb42..59e307e21 100644 --- a/asm/link.s +++ b/asm/link.s @@ -5,290 +5,6 @@ .text - thumb_func_start sub_800B764 -sub_800B764: @ 800B764 - push {lr} - ldr r0, =0x04000128 - ldr r1, [r0] - movs r0, 0xC - ands r1, r0 - ldr r2, =gLink - cmp r1, 0x8 - bne _0800B788 - ldrb r0, [r2, 0x2] - cmp r0, 0 - bne _0800B788 - strb r1, [r2] - b _0800B78C - .pool -_0800B788: - movs r0, 0 - strb r0, [r2] -_0800B78C: - pop {r0} - bx r0 - thumb_func_end sub_800B764 - - thumb_func_start sub_800B790 -sub_800B790: @ 800B790 - push {lr} - ldr r0, =gLink - ldrb r0, [r0] - cmp r0, 0 - beq _0800B7AE - ldr r1, =0x0400010c - ldr r2, =0x0000ff3b - adds r0, r2, 0 - strh r0, [r1] - adds r1, 0x2 - movs r0, 0x41 - strh r0, [r1] - movs r0, 0x40 - bl EnableInterrupts -_0800B7AE: - pop {r0} - bx r0 - .pool - thumb_func_end sub_800B790 - - thumb_func_start sub_800B7C0 -sub_800B7C0: @ 800B7C0 - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - adds r3, r0, 0 - ldr r2, =gUnknown_03004134 - ldr r1, =0x04000208 - ldrh r0, [r1] - strh r0, [r2] - movs r0, 0 - strh r0, [r1] - ldr r1, =gLink - ldr r4, =0x00000339 - adds r0, r1, r4 - ldrb r4, [r0] - adds r6, r1, 0 - cmp r4, 0x31 - bhi _0800B850 - movs r1, 0xCE - lsls r1, 2 - adds r0, r6, r1 - ldrb r0, [r0] - adds r0, r4, r0 - lsls r0, 24 - lsrs r0, 24 - cmp r0, 0x31 - bls _0800B7FE - subs r0, 0x32 - lsls r0, 24 - lsrs r0, 24 -_0800B7FE: - movs r2, 0 - ldr r4, =gUnknown_03000D6E - mov r9, r4 - ldr r1, =gLastSendQueueCount - mov r10, r1 - lsls r5, r0, 1 - movs r0, 0x18 - adds r0, r6 - mov r8, r0 - mov r12, r2 - movs r7, 0x64 -_0800B814: - ldrh r0, [r4] - ldrh r1, [r3] - orrs r0, r1 - strh r0, [r4] - adds r0, r2, 0 - muls r0, r7 - adds r0, r5, r0 - add r0, r8 - strh r1, [r0] - mov r1, r12 - strh r1, [r3] - adds r3, 0x2 - adds r0, r2, 0x1 - lsls r0, 24 - lsrs r2, r0, 24 - cmp r2, 0x7 - bls _0800B814 - b _0800B85C - .pool -_0800B850: - movs r0, 0x1 - strb r0, [r6, 0x12] - ldr r2, =gUnknown_03000D6E - mov r9, r2 - ldr r4, =gLastSendQueueCount - mov r10, r4 -_0800B85C: - mov r1, r9 - ldrh r0, [r1] - cmp r0, 0 - beq _0800B874 - ldr r2, =0x00000339 - adds r0, r6, r2 - ldrb r1, [r0] - adds r1, 0x1 - movs r2, 0 - strb r1, [r0] - mov r4, r9 - strh r2, [r4] -_0800B874: - ldr r1, =0x04000208 - ldr r2, =gUnknown_03004134 - ldrh r0, [r2] - strh r0, [r1] - ldr r4, =0x00000339 - adds r0, r6, r4 - ldrb r0, [r0] - mov r1, r10 - strb r0, [r1] - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - .pool - thumb_func_end sub_800B7C0 - - thumb_func_start sub_800B8A8 -sub_800B8A8: @ 800B8A8 - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - mov r9, r0 - ldr r2, =gUnknown_03004134 - ldr r1, =0x04000208 - ldrh r0, [r1] - strh r0, [r2] - movs r0, 0 - strh r0, [r1] - ldr r1, =gLink - ldr r3, =0x00000fbd - adds r0, r1, r3 - ldrb r0, [r0] - mov r12, r1 - cmp r0, 0 - bne _0800B914 - movs r3, 0 - ldrb r0, [r1, 0x3] - cmp r3, r0 - bcs _0800B8FA - movs r5, 0 - adds r6, r0, 0 -_0800B8DA: - movs r2, 0 - lsls r1, r3, 4 - adds r4, r3, 0x1 - add r1, r9 -_0800B8E2: - lsls r0, r2, 1 - adds r0, r1 - strh r5, [r0] - adds r0, r2, 0x1 - lsls r0, 24 - lsrs r2, r0, 24 - cmp r2, 0x7 - bls _0800B8E2 - lsls r0, r4, 24 - lsrs r3, r0, 24 - cmp r3, r6 - bcc _0800B8DA -_0800B8FA: - movs r0, 0x1 - mov r7, r12 - strb r0, [r7, 0xC] - b _0800B990 - .pool -_0800B914: - movs r3, 0 - mov r0, r12 - ldrb r1, [r0, 0x3] - cmp r3, r1 - bcs _0800B96A - ldr r0, =0x00000fbc - add r0, r12 - ldrb r0, [r0] - lsls r6, r0, 1 - movs r2, 0xCF - lsls r2, 2 - add r2, r12 - mov r8, r2 - mov r10, r1 -_0800B930: - movs r2, 0 - lsls r1, r3, 4 - adds r4, r3, 0x1 - lsls r0, r3, 1 - mov r7, r9 - adds r5, r1, r7 - adds r0, r3 - lsls r0, 3 - adds r0, r3 - lsls r3, r0, 5 -_0800B944: - lsls r1, r2, 1 - adds r1, r5 - movs r7, 0x64 - adds r0, r2, 0 - muls r0, r7 - adds r0, r6, r0 - adds r0, r3 - add r0, r8 - ldrh r0, [r0] - strh r0, [r1] - adds r0, r2, 0x1 - lsls r0, 24 - lsrs r2, r0, 24 - cmp r2, 0x7 - bls _0800B944 - lsls r0, r4, 24 - lsrs r3, r0, 24 - cmp r3, r10 - bcc _0800B930 -_0800B96A: - mov r2, r12 - ldr r0, =0x00000fbd - adds r1, r2, r0 - ldrb r0, [r1] - subs r0, 0x1 - movs r3, 0 - strb r0, [r1] - ldr r1, =0x00000fbc - adds r2, r1 - ldrb r0, [r2] - adds r0, 0x1 - strb r0, [r2] - lsls r0, 24 - lsrs r0, 24 - cmp r0, 0x31 - bls _0800B98C - strb r3, [r2] -_0800B98C: - mov r2, r12 - strb r3, [r2, 0xC] -_0800B990: - ldr r1, =0x04000208 - ldr r3, =gUnknown_03004134 - ldrh r0, [r3] - strh r0, [r1] - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - .pool - thumb_func_end sub_800B8A8 - thumb_func_start sub_800B9B8 sub_800B9B8: @ 800B9B8 push {r4,lr} diff --git a/asm/link_rfu.s b/asm/link_rfu.s index 1e7f4a182..3641ec1a3 100644 --- a/asm/link_rfu.s +++ b/asm/link_rfu.s @@ -3725,7 +3725,7 @@ _0800FBB0: b _0800FC08 .pool _0800FBF4: - ldr r0, =gUnknown_03003020 + ldr r0, =gLinkPartnersHeldKeys mov r3, r8 lsls r1, r3, 1 adds r1, r0 diff --git a/asm/rom4.s b/asm/rom4.s index 575b18991..0aaea22c8 100644 --- a/asm/rom4.s +++ b/asm/rom4.s @@ -4578,7 +4578,7 @@ c1_link_related: @ 8086BD8 _08086BF2: ldr r0, =gUnknown_03005DB4 ldrb r4, [r0] - ldr r0, =gUnknown_03003020 + ldr r0, =gLinkPartnersHeldKeys adds r1, r4, 0 bl sub_8086F38 ldr r0, =gUnknown_03000E14 @@ -4610,7 +4610,7 @@ sub_8086C2C: @ 8086C2C thumb_func_start sub_8086C40 sub_8086C40: @ 8086C40 push {lr} - ldr r0, =gUnknown_03003020 + ldr r0, =gLinkPartnersHeldKeys bl sub_808709C pop {r0} bx r0 diff --git a/common_syms/link.txt b/common_syms/link.txt index 564802b1a..a6d096116 100644 --- a/common_syms/link.txt +++ b/common_syms/link.txt @@ -1,11 +1,11 @@ -gUnknown_03003020 +gLinkPartnersHeldKeys gLinkDebugSeed gLocalLinkPlayerBlock gLinkErrorOccurred gLinkDebugFlags -gUnknown_03003074 -gUnknown_03003078 -gUnknown_0300307C +gFiller_03003074 +gRemoteLinkPlayersNotReceived +gBlockReceivedStatus gFiller_03003080 gLinkHeldKeys gRecvCmds @@ -32,6 +32,6 @@ gFiller_0300315c gLastSendQueueCount gLink gLastRecvQueueCount -gUnknown_03004134 +gLinkSavedIme gFiller_03004138 gFiller_0300413C diff --git a/include/link.h b/include/link.h index 88f638d78..023d95207 100644 --- a/include/link.h +++ b/include/link.h @@ -7,6 +7,9 @@ #define QUEUE_CAPACITY 50 #define BLOCK_BUFFER_SIZE 0x100 +#define LINK_SLAVE 0 +#define LINK_MASTER 8 + #define LINK_STAT_LOCAL_ID 0x00000003 #define LINK_STAT_PLAYER_COUNT 0x0000001C #define LINK_STAT_PLAYER_COUNT_SHIFT 2 @@ -16,9 +19,24 @@ #define LINK_STAT_CONN_ESTABLISHED_SHIFT 6 #define LINK_STAT_RECEIVED_NOTHING 0x00000100 #define LINK_STAT_RECEIVED_NOTHING_SHIFT 8 +#define LINK_STAT_UNK_FLAG_9 0x00000200 +#define LINK_STAT_UNK_FLAG_9_SHIFT 9 #define LINK_STAT_ERRORS 0x0007F000 #define LINK_STAT_ERRORS_SHIFT 12 +#define LINK_STAT_ERROR_HARDWARE 0x00001000 +#define LINK_STAT_ERROR_HARDWARE_SHIFT 12 +#define LINK_STAT_ERROR_CHECKSUM 0x00002000 +#define LINK_STAT_ERROR_CHECKSUM_SHIFT 13 +#define LINK_STAT_ERROR_QUEUE_FULL 0x00004000 +#define LINK_STAT_ERROR_QUEUE_FULL_SHIFT 14 +#define LINK_STAT_ERROR_LAG_MASTER 0x00010000 +#define LINK_STAT_ERROR_LAG_MASTER_SHIFT 16 +#define LINK_STAT_ERROR_INVALID_ID 0x00020000 +#define LINK_STAT_ERROR_INVALID_ID_SHIFT 17 +#define LINK_STAT_ERROR_LAG_SLAVE 0x00040000 +#define LINK_STAT_ERROR_LAG_SLAVE_SHIFT 18 + #define EXTRACT_PLAYER_COUNT(status) \ (((status) & LINK_STAT_PLAYER_COUNT) >> LINK_STAT_PLAYER_COUNT_SHIFT) #define EXTRACT_MASTER(status) \ @@ -30,6 +48,21 @@ #define EXTRACT_LINK_ERRORS(status) \ (((status) & LINK_STAT_ERRORS) >> LINK_STAT_ERRORS_SHIFT) +#define LINKCMD_SEND_LINK_TYPE 0x2222 +#define LINKCMD_0x2FFE 0x2FFE +#define LINKCMD_SEND_HELD_KEYS 0x4444 +#define LINKCMD_0x5555 0x5555 +#define LINKCMD_0x5566 0x5566 +#define LINKCMD_0x5FFF 0x5FFF +#define LINKCMD_0x6666 0x6666 +#define LINKCMD_0x7777 0x7777 +#define LINKCMD_CONT_BLOCK 0x8888 +#define LINKCMD_0xAAAA 0xAAAA +#define LINKCMD_0xAAAB 0xAAAB +#define LINKCMD_INIT_BLOCK 0xBBBB +#define LINKCMD_SEND_HELD_KEYS_2 0xCAFE +#define LINKCMD_0xCCCC 0xCCCC + struct LinkStatus { u32 localId:2; @@ -215,13 +248,13 @@ void sub_800B524(struct LinkPlayer *linkPlayer); u8 GetSioMultiSI(void); void sub_800B9B8(void); -extern u16 gUnknown_03003020[6]; +extern u16 gLinkPartnersHeldKeys[6]; extern u32 gLinkDebugSeed; extern struct LinkPlayerBlock gLocalLinkPlayerBlock; extern bool8 gLinkErrorOccurred; extern u32 gLinkDebugFlags; -extern bool8 gUnknown_03003078[MAX_LINK_PLAYERS]; -extern u8 gUnknown_0300307C[MAX_LINK_PLAYERS]; +extern bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS]; +extern u8 gBlockReceivedStatus[MAX_LINK_PLAYERS]; extern u16 gLinkHeldKeys; extern u32 gLinkStatus; extern u8 gUnknown_030030E4; @@ -240,8 +273,8 @@ extern u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS]; extern u8 gBlockRequestType; extern u8 gLastSendQueueCount; extern u8 gLastRecvQueueCount; -extern u16 gUnknown_03004134; -extern u32 gUnknown_03003074; +extern u16 gLinkSavedIme; +extern u32 gFiller_03003074; extern u32 gFiller_03003154; extern u32 gFiller_03003158; extern u32 gFiller_0300315c; diff --git a/src/link.c b/src/link.c index 3adfc1b76..eb6d573d5 100644 --- a/src/link.c +++ b/src/link.c @@ -62,20 +62,20 @@ IWRAM_DATA u8 sLinkTestLastBlockSendPos; ALIGNED() IWRAM_DATA u8 sLinkTestLastBlockRecvPos[MAX_LINK_PLAYERS]; IWRAM_DATA u8 gUnknown_03000D6C; IWRAM_DATA bool8 gUnknown_03000D6D; -IWRAM_DATA u16 gUnknown_03000D6E; +IWRAM_DATA u16 sSendNonzeroCheck; IWRAM_DATA u16 gUnknown_03000D70; IWRAM_DATA u8 gUnknown_03000D72; IWRAM_DATA u8 gUnknown_03000D73; IWRAM_DATA u8 gUnknown_03000D74; -u16 gUnknown_03003020[6]; +u16 gLinkPartnersHeldKeys[6]; u32 gLinkDebugSeed; struct LinkPlayerBlock gLocalLinkPlayerBlock; bool8 gLinkErrorOccurred; u32 gLinkDebugFlags; -u32 gUnknown_03003074; -bool8 gUnknown_03003078[MAX_LINK_PLAYERS]; -u8 gUnknown_0300307C[MAX_LINK_PLAYERS]; +u32 gFiller_03003074; +bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS]; +u8 gBlockReceivedStatus[MAX_LINK_PLAYERS]; u32 gFiller_03003080; u16 gLinkHeldKeys; u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH]; @@ -102,7 +102,7 @@ u32 gFiller_0300315c; u8 gLastSendQueueCount; struct Link gLink; u8 gLastRecvQueueCount; -u16 gUnknown_03004134; +u16 gLinkSavedIme; u32 gFiller_03004138; u32 gFiller_0300413C; @@ -128,8 +128,8 @@ EWRAM_DATA void *gUnknown_02022B0C = NULL; // Static ROM declarations -void InitLocalLinkPlayer(void); -void sub_80096BC(void); +static void InitLocalLinkPlayer(void); +static void sub_80096BC(void); static void CB2_LinkTest(void); static void ProcessRecvCmds(u8 unused); static void sub_8009F70(void); @@ -152,15 +152,13 @@ static void sub_800AE5C(void); static void CheckErrorStatus(void); static void CB2_PrintErrorMessage(void); static bool8 IsSioMultiMaster(void); -u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENGTH]); static void sub_800B4A4(void); -void DisableSerial(void); -void EnableSerial(void); - -void sub_800B764(void); -void sub_800B790(void); -void sub_800B7C0(u16 *queue); -void sub_800B8A8(u16 (*queue)[CMD_LENGTH]); +static void DisableSerial(void); +static void EnableSerial(void); +static void CheckMasterOrSlave(void); +static void InitTimer(void); +static void EnqueueSendCmd(u16 *sendCmd); +static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]); // .rodata @@ -300,7 +298,7 @@ void sub_8009628(u8 a0) gLocalLinkPlayer.lp_field_18 = a0; } -void InitLocalLinkPlayer(void) +static void InitLocalLinkPlayer(void) { gLocalLinkPlayer.trainerId = gSaveBlock2Ptr->playerTrainerId[0] | (gSaveBlock2Ptr->playerTrainerId[1] << 8) | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[3] << 24); StringCopy(gLocalLinkPlayer.name, gSaveBlock2Ptr->playerName); @@ -316,14 +314,14 @@ void InitLocalLinkPlayer(void) } } -void sub_80096BC(void) +static void sub_80096BC(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -void InitLink(void) +static void InitLink(void) { int i; @@ -335,7 +333,7 @@ void InitLink(void) EnableSerial(); } -void Task_TriggerHandshake(u8 taskId) +static void Task_TriggerHandshake(u8 taskId) { if (++ gTasks[taskId].data[0] == 5) { @@ -371,7 +369,7 @@ void OpenLink(void) gReceivedRemoteLinkPlayers = 0; for (i = 0; i < MAX_LINK_PLAYERS; i ++) { - gUnknown_03003078[i] = TRUE; + gRemoteLinkPlayersNotReceived[i] = TRUE; gUnknown_030030F0[i] = FALSE; gUnknown_030030EC[i] = FALSE; } @@ -425,7 +423,7 @@ static void TestBlockTransfer(u8 nothing, u8 is, u8 used) } } -void LinkTestProcessKeyInput(void) +static void LinkTestProcessKeyInput(void) { if (gMain.newKeys & A_BUTTON) { @@ -492,16 +490,16 @@ u16 LinkMain2(const u16 *heldKeys) return gLinkStatus; } -void HandleReceiveRemoteLinkPlayer(u8 who) +static void HandleReceiveRemoteLinkPlayer(u8 who) { int i; int count; count = 0; - gUnknown_03003078[who] = FALSE; + gRemoteLinkPlayersNotReceived[who] = FALSE; for (i = 0; i < GetLinkPlayerCount_2(); i ++) { - count += gUnknown_03003078[i]; + count += gRemoteLinkPlayersNotReceived[i]; } if (count == 0 && gReceivedRemoteLinkPlayers == 0) { @@ -515,14 +513,14 @@ static void ProcessRecvCmds(u8 unused) for (i = 0; i < MAX_LINK_PLAYERS; i ++) { - gUnknown_03003020[i] = 0; + gLinkPartnersHeldKeys[i] = 0; if (gRecvCmds[i][0] == 0) { continue; } switch (gRecvCmds[i][0]) { - case 0x2222: + case LINKCMD_SEND_LINK_TYPE: { struct LinkPlayerBlock *block; @@ -534,16 +532,16 @@ static void ProcessRecvCmds(u8 unused) InitBlockSend(block, sizeof(*block)); break; } - case 0x4444: - gUnknown_03003020[i] = gRecvCmds[i][1]; + case LINKCMD_SEND_HELD_KEYS: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; - case 0x5555: + case LINKCMD_0x5555: gUnknown_030030E8 = TRUE; break; - case 0x5566: + case LINKCMD_0x5566: gUnknown_030030E8 = TRUE; break; - case 0xBBBB: + case LINKCMD_INIT_BLOCK: { struct BlockTransfer *blockRecv; @@ -553,7 +551,7 @@ static void ProcessRecvCmds(u8 unused) blockRecv->multiplayerId = gRecvCmds[i][2]; break; } - case 0x8888: + case LINKCMD_CONT_BLOCK: { if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE) { @@ -580,7 +578,7 @@ static void ProcessRecvCmds(u8 unused) if (sBlockRecv[i].pos >= sBlockRecv[i].size) { - if (gUnknown_03003078[i] == TRUE) + if (gRemoteLinkPlayersNotReceived[i] == TRUE) { struct LinkPlayerBlock *block; struct LinkPlayer *linkPlayer; @@ -612,87 +610,87 @@ static void ProcessRecvCmds(u8 unused) } } break; - case 0x5FFF: + case LINKCMD_0x5FFF: gUnknown_030030F0[i] = TRUE; break; - case 0x2FFE: + case LINKCMD_0x2FFE: gUnknown_030030EC[i] = TRUE; break; - case 0xAAAA: + case LINKCMD_0xAAAA: sub_800A418(); break; - case 0xCCCC: + case LINKCMD_0xCCCC: SendBlock(0, gUnknown_082ED1A8[gRecvCmds[i][1]].address, gUnknown_082ED1A8[gRecvCmds[i][1]].size); break; - case 0xCAFE: - gUnknown_03003020[i] = gRecvCmds[i][1]; + case LINKCMD_SEND_HELD_KEYS_2: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; } } } -void BuildSendCmd(u16 command) +static void BuildSendCmd(u16 command) { switch (command) { - case 0x2222: - gSendCmd[0] = 0x2222; + case LINKCMD_SEND_LINK_TYPE: + gSendCmd[0] = LINKCMD_SEND_LINK_TYPE; gSendCmd[1] = gLinkType; break; - case 0x2ffe: - gSendCmd[0] = 0x2ffe; + case LINKCMD_0x2FFE: + gSendCmd[0] = LINKCMD_0x2FFE; break; - case 0x4444: - gSendCmd[0] = 0x4444; + case LINKCMD_SEND_HELD_KEYS: + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS; gSendCmd[1] = gMain.heldKeys; break; - case 0x5555: - gSendCmd[0] = 0x5555; + case LINKCMD_0x5555: + gSendCmd[0] = LINKCMD_0x5555; break; - case 0x6666: - gSendCmd[0] = 0x6666; + case LINKCMD_0x6666: + gSendCmd[0] = LINKCMD_0x6666; gSendCmd[1] = 0; break; - case 0x7777: + case LINKCMD_0x7777: { u8 i; - gSendCmd[0] = 0x7777; + gSendCmd[0] = LINKCMD_0x7777; for (i = 0; i < 5; i ++) { gSendCmd[i + 1] = 0xEE; } break; } - case 0xbbbb: - gSendCmd[0] = 0xbbbb; + case LINKCMD_INIT_BLOCK: + gSendCmd[0] = LINKCMD_INIT_BLOCK; gSendCmd[1] = sBlockSend.size; gSendCmd[2] = sBlockSend.multiplayerId + 0x80; break; - case 0xaaaa: - gSendCmd[0] = 0xaaaa; + case LINKCMD_0xAAAA: + gSendCmd[0] = LINKCMD_0xAAAA; break; - case 0xaaab: - gSendCmd[0] = 0xaaab; + case LINKCMD_0xAAAB: + gSendCmd[0] = LINKCMD_0xAAAB; gSendCmd[1] = gScriptItemId; break; - case 0xcccc: - gSendCmd[0] = 0xcccc; + case LINKCMD_0xCCCC: + gSendCmd[0] = LINKCMD_0xCCCC; gSendCmd[1] = gBlockRequestType; break; - case 0x5fff: - gSendCmd[0] = 0x5fff; + case LINKCMD_0x5FFF: + gSendCmd[0] = LINKCMD_0x5FFF; gSendCmd[1] = gUnknown_030030F4; break; - case 0x5566: - gSendCmd[0] = 0x5566; + case LINKCMD_0x5566: + gSendCmd[0] = LINKCMD_0x5566; break; - case 0xcafe: + case LINKCMD_SEND_HELD_KEYS_2: if (gUnknown_03005DA8 == 0 || gLinkTransferringData) { break; } - gSendCmd[0] = 0xcafe; + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2; gSendCmd[1] = gUnknown_03005DA8; break; } @@ -724,7 +722,7 @@ static void sub_8009F70(void) { if (gReceivedRemoteLinkPlayers == TRUE) { - BuildSendCmd(0xcafe); + BuildSendCmd(LINKCMD_SEND_HELD_KEYS_2); } } @@ -761,7 +759,7 @@ u8 GetLinkPlayerCount(void) return EXTRACT_PLAYER_COUNT(gLinkStatus); } -int sub_8009FF8(u32 version1, u32 version2) +static int sub_8009FF8(u32 version1, u32 version2) { int i; u8 nPlayers; @@ -964,7 +962,7 @@ static bool32 InitBlockSend(const void *src, size_t size) } sBlockSend.src = gBlockSendBuffer; } - BuildSendCmd(0xbbbb); + BuildSendCmd(LINKCMD_INIT_BLOCK); gLinkCallback = LinkCB_BlockSendBegin; sBlockSendDelayCounter = 0; return TRUE; @@ -984,7 +982,7 @@ static void LinkCB_BlockSend(void) const u8 *src; src = sBlockSend.src; - gSendCmd[0] = 0x8888; + gSendCmd[0] = LINKCMD_CONT_BLOCK; for (i = 0; i < 7; i ++) { gSendCmd[i + 1] = (src[sBlockSend.pos + i * 2 + 1] << 8) | src[sBlockSend.pos + i * 2]; @@ -1005,7 +1003,7 @@ static void LinkCB_BlockSendEnd(void) static void sub_800A3F8(void) { GetMultiplayerId(); - BuildSendCmd(0x4444); + BuildSendCmd(LINKCMD_SEND_HELD_KEYS); gUnknown_020223C0 ++; } @@ -1029,7 +1027,7 @@ u32 sub_800A44C(void) void sub_800A458(void) { - BuildSendCmd(0xaaaa); + BuildSendCmd(LINKCMD_0xAAAA); } u8 GetMultiplayerId(void) @@ -1067,7 +1065,7 @@ bool8 sub_800A4D8(u8 a0) if (gLinkCallback == NULL) { gBlockRequestType = a0; - BuildSendCmd(0xcccc); + BuildSendCmd(LINKCMD_0xCCCC); return TRUE; } return FALSE; @@ -1088,7 +1086,7 @@ u8 GetBlockReceivedStatus(void) { return sub_800FCD8(); } - return (gUnknown_0300307C[3] << 3) | (gUnknown_0300307C[2] << 2) | (gUnknown_0300307C[1] << 1) | (gUnknown_0300307C[0] << 0); + return (gBlockReceivedStatus[3] << 3) | (gBlockReceivedStatus[2] << 2) | (gBlockReceivedStatus[1] << 1) | (gBlockReceivedStatus[0] << 0); } static void SetBlockReceivedFlag(u8 who) @@ -1099,7 +1097,7 @@ static void SetBlockReceivedFlag(u8 who) } else { - gUnknown_0300307C[who] = TRUE; + gBlockReceivedStatus[who] = TRUE; } } @@ -1118,7 +1116,7 @@ void ResetBlockReceivedFlags(void) { for (i = 0; i < MAX_LINK_PLAYERS; i ++) { - gUnknown_0300307C[i] = FALSE; + gBlockReceivedStatus[i] = FALSE; } } } @@ -1129,9 +1127,9 @@ void ResetBlockReceivedFlag(u8 who) { sub_800F728(who); } - else if (gUnknown_0300307C[who]) + else if (gBlockReceivedStatus[who]) { - gUnknown_0300307C[who] = FALSE; + gBlockReceivedStatus[who] = FALSE; } } @@ -1244,7 +1242,7 @@ static void LinkCB_RequestPlayerDataExchange(void) { if (gLinkStatus & LINK_STAT_MASTER) { - BuildSendCmd(0x2222); + BuildSendCmd(LINKCMD_SEND_LINK_TYPE); } gLinkCallback = NULL; } @@ -1456,7 +1454,7 @@ static void sub_800AC80(void) { if (gLastRecvQueueCount == 0) { - BuildSendCmd(0x5fff); + BuildSendCmd(LINKCMD_0x5FFF); gLinkCallback = sub_800ACAC; } } @@ -1511,7 +1509,7 @@ static void sub_800AD5C(void) { if (gLastRecvQueueCount == 0) { - BuildSendCmd(0x5fff); + BuildSendCmd(LINKCMD_0x5FFF); gLinkCallback = sub_800AD88; } } @@ -1565,7 +1563,7 @@ static void sub_800AE30(void) { if (gLastRecvQueueCount == 0) { - BuildSendCmd(0x2ffe); + BuildSendCmd(LINKCMD_0x2FFE); gLinkCallback = sub_800AE5C; } } @@ -1901,7 +1899,7 @@ void sub_800B524(struct LinkPlayer *player) ConvertInternationalString(player->name, player->language); } -void DisableSerial(void) +static void DisableSerial(void) { DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); REG_SIOCNT = SIO_MULTI_MODE; @@ -1912,7 +1910,7 @@ void DisableSerial(void) CpuFill32(0, &gLink, sizeof(gLink)); } -void EnableSerial(void) +static void EnableSerial(void) { DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); REG_RCNT = 0; @@ -1922,7 +1920,7 @@ void EnableSerial(void) REG_SIOMLT_SEND = 0; CpuFill32(0, &gLink, sizeof(gLink)); gUnknown_03000D6C = 0; - gUnknown_03000D6E = 0; + sSendNonzeroCheck = 0; gUnknown_03000D70 = 0; gUnknown_03000D72 = 0; gUnknown_03000D73 = 0; @@ -1958,10 +1956,10 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG switch (*shouldAdvanceLinkState) { default: - sub_800B764(); + CheckMasterOrSlave(); break; case 1: - if (gLink.isMaster == 8 && gLink.playerCount > 1) + if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1) { gLink.handshakeAsMaster = TRUE; } @@ -1973,32 +1971,32 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG } break; case LINK_STATE_INIT_TIMER: - sub_800B790(); + InitTimer(); gLink.state = LINK_STATE_CONN_ESTABLISHED; // fallthrough case LINK_STATE_CONN_ESTABLISHED: - sub_800B7C0(sendCmd); - sub_800B8A8(recvCmds); + EnqueueSendCmd(sendCmd); + DequeueRecvCmds(recvCmds); break; } *shouldAdvanceLinkState = 0; retVal = gLink.localId; - retVal |= (gLink.playerCount << 2); - if (gLink.isMaster == 8) + retVal |= (gLink.playerCount << LINK_STAT_PLAYER_COUNT_SHIFT); + if (gLink.isMaster == LINK_MASTER) { - retVal |= 0x20; + retVal |= LINK_STAT_MASTER; } { - u32 receivedNothing = gLink.receivedNothing << 8; - u32 link_field_F = gLink.link_field_F << 9; - u32 hardwareError = gLink.hardwareError << 12; - u32 badChecksum = gLink.badChecksum << 13; - u32 queueFull = gLink.queueFull << 14; + u32 receivedNothing = gLink.receivedNothing << LINK_STAT_RECEIVED_NOTHING_SHIFT; + u32 link_field_F = gLink.link_field_F << LINK_STAT_UNK_FLAG_9_SHIFT; + u32 hardwareError = gLink.hardwareError << LINK_STAT_ERROR_HARDWARE_SHIFT; + u32 badChecksum = gLink.badChecksum << LINK_STAT_ERROR_CHECKSUM_SHIFT; + u32 queueFull = gLink.queueFull << LINK_STAT_ERROR_QUEUE_FULL_SHIFT; u32 val; if (gLink.state == LINK_STATE_CONN_ESTABLISHED) { - val = 0x40; + val = LINK_STAT_CONN_ESTABLISHED; val |= receivedNothing; val |= retVal; val |= link_field_F; @@ -2020,14 +2018,121 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG } if (gLink.lag == LAG_MASTER) - retVal |= 0x10000; + { + retVal |= LINK_STAT_ERROR_LAG_MASTER; + } - if (gLink.localId > 3) - retVal |= 0x20000; + if (gLink.localId >= MAX_LINK_PLAYERS) + { + retVal |= LINK_STAT_ERROR_INVALID_ID; + } retVal2 = retVal; if (gLink.lag == LAG_SLAVE) - retVal2 |= 0x40000; + { + retVal2 |= LINK_STAT_ERROR_LAG_SLAVE; + } return retVal2; } + +static void CheckMasterOrSlave(void) +{ + u32 terminals; + + terminals = *(vu32 *)REG_ADDR_SIOCNT & (SIO_MULTI_SD | SIO_MULTI_SI); + if (terminals == SIO_MULTI_SD && gLink.localId == 0) + { + gLink.isMaster = LINK_MASTER; + } + else + { + gLink.isMaster = LINK_SLAVE; + } +} + +static void InitTimer(void) +{ + if (gLink.isMaster) + { + REG_TM3CNT_L = 0xFF3B; + REG_TM3CNT_H = TIMER_64CLK | TIMER_INTR_ENABLE; + EnableInterrupts(INTR_FLAG_TIMER3); + } +} + +static void EnqueueSendCmd(u16 *sendCmd) +{ + u8 i; + u8 offset; + + gLinkSavedIme = REG_IME; + REG_IME = 0; + if (gLink.sendQueue.count < QUEUE_CAPACITY) + { + offset = gLink.sendQueue.pos + gLink.sendQueue.count; + if (offset >= QUEUE_CAPACITY) + { + offset -= QUEUE_CAPACITY; + } + for (i = 0; i < CMD_LENGTH; i ++) + { + sSendNonzeroCheck |= *sendCmd; + gLink.sendQueue.data[i][offset] = *sendCmd; + *sendCmd = 0; + sendCmd++; + } + } + else + { + gLink.queueFull = QUEUE_FULL_SEND; + } + if (sSendNonzeroCheck) + { + gLink.sendQueue.count ++; + sSendNonzeroCheck = 0; + } + REG_IME = gLinkSavedIme; + gLastSendQueueCount = gLink.sendQueue.count; +} + + +static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]) +{ + u8 i; + u8 j; + + gLinkSavedIme = REG_IME; + REG_IME = 0; + if (gLink.recvQueue.count == 0) + { + for (i = 0; i < gLink.playerCount; i ++) + { + for (j = 0; j < CMD_LENGTH; j ++) + { + recvCmds[i][j] = 0; + } + } + + gLink.receivedNothing = TRUE; + } + else + { + for (i = 0; i < gLink.playerCount; i ++) + { + for (j = 0; j < CMD_LENGTH; j ++) + { + recvCmds[i][j] = gLink.recvQueue.data[i][j][gLink.recvQueue.pos]; + } + } + gLink.recvQueue.count --; + gLink.recvQueue.pos ++; + if (gLink.recvQueue.pos >= QUEUE_CAPACITY) + { + gLink.recvQueue.pos = 0; + } + gLink.receivedNothing = FALSE; + } + REG_IME = gLinkSavedIme; +} +