diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/link.c | 313 |
1 files changed, 209 insertions, 104 deletions
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; +} + |