summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2017-11-15 08:44:11 -0500
committerPikalaxALT <pikalaxalt@gmail.com>2017-11-15 08:44:11 -0500
commit50501396b21bf132cf71d0f5d353bf51d277ba27 (patch)
tree1640c9877d789de53f670827b797d8de4777f610 /src
parent3bb450645b65fee8a901521d148ab87f81f8f20b (diff)
DoHandshake
Diffstat (limited to 'src')
-rw-r--r--src/link.c110
1 files changed, 107 insertions, 3 deletions
diff --git a/src/link.c b/src/link.c
index a57385a59..741f5f707 100644
--- a/src/link.c
+++ b/src/link.c
@@ -65,7 +65,7 @@ IWRAM_DATA bool8 gUnknown_03000D6D;
IWRAM_DATA u16 sSendNonzeroCheck;
IWRAM_DATA u16 gUnknown_03000D70;
IWRAM_DATA u8 gUnknown_03000D72;
-IWRAM_DATA u8 gUnknown_03000D73;
+IWRAM_DATA u8 sHandshakePlayerCount;
IWRAM_DATA u8 gUnknown_03000D74;
u16 gLinkPartnersHeldKeys[6];
@@ -159,7 +159,12 @@ static void CheckMasterOrSlave(void);
static void InitTimer(void);
static void EnqueueSendCmd(u16 *sendCmd);
static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]);
-void StartTransfer(void);
+static void StartTransfer(void);
+static bool8 DoHandshake(void);
+void DoRecv(void);
+void DoSend(void);
+void StopTimer(void);
+void SendRecvDone(void);
// .rodata
@@ -1924,7 +1929,7 @@ static void EnableSerial(void)
sSendNonzeroCheck = 0;
gUnknown_03000D70 = 0;
gUnknown_03000D72 = 0;
- gUnknown_03000D73 = 0;
+ sHandshakePlayerCount = 0;
gLastSendQueueCount = 0;
gLastRecvQueueCount = 0;
}
@@ -2183,3 +2188,102 @@ void LinkVSync(void)
}
}
+void Timer3Intr(void)
+{
+ StopTimer();
+ StartTransfer();
+}
+
+void SerialCB(void)
+{
+ gLink.localId = SIO_MULTI_CNT->id;
+ switch (gLink.state)
+ {
+ case LINK_STATE_CONN_ESTABLISHED:
+ gLink.hardwareError = SIO_MULTI_CNT->error;
+ DoRecv();
+ DoSend();
+ SendRecvDone();
+ break;
+ case LINK_STATE_HANDSHAKE:
+ if (DoHandshake())
+ {
+ if (gLink.isMaster)
+ {
+ gLink.state = LINK_STATE_INIT_TIMER;
+ gLink.serialIntrCounter = 8;
+ }
+ else
+ {
+ gLink.state = LINK_STATE_CONN_ESTABLISHED;
+ }
+ }
+ break;
+ }
+ gLink.serialIntrCounter ++;
+ sNumVBlanksWithoutSerialIntr = 0;
+ if (gLink.serialIntrCounter == 8)
+ {
+ gLastRecvQueueCount = gLink.recvQueue.count;
+ }
+}
+
+static void StartTransfer(void)
+{
+ REG_SIOCNT |= SIO_START;
+}
+
+static bool8 DoHandshake(void)
+{
+ u8 i;
+ u8 playerCount;
+ u16 minRecv;
+
+ playerCount = 0;
+ minRecv = 0xFFFF;
+ if (gLink.handshakeAsMaster == TRUE)
+ {
+ REG_SIOMLT_SEND = MASTER_HANDSHAKE;
+ }
+ else
+ {
+ REG_SIOMLT_SEND = SLAVE_HANDSHAKE;
+ }
+ *(u64 *)gLink.tempRecvBuffer = REG_SIOMLT_RECV;
+ REG_SIOMLT_RECV = 0;
+ gLink.handshakeAsMaster = FALSE;
+ for (i = 0; i < 4; i ++)
+ {
+ if ((gLink.tempRecvBuffer[i] & ~0x3) == SLAVE_HANDSHAKE || gLink.tempRecvBuffer[i] == MASTER_HANDSHAKE)
+ {
+ playerCount ++;
+ if (minRecv > gLink.tempRecvBuffer[i] && gLink.tempRecvBuffer[i] != 0)
+ {
+ minRecv = gLink.tempRecvBuffer[i];
+ }
+ }
+ else
+ {
+ if (gLink.tempRecvBuffer[i] != 0xFFFF)
+ {
+ playerCount = 0;
+ }
+ break;
+ }
+ }
+ gLink.playerCount = playerCount;
+ if (gLink.playerCount > 1 && gLink.playerCount == sHandshakePlayerCount && gLink.tempRecvBuffer[0] == MASTER_HANDSHAKE)
+ {
+ return TRUE;
+ }
+ if (gLink.playerCount > 1)
+ {
+ gLink.link_field_F = (minRecv & 3) + 1;
+ }
+ else
+ {
+ gLink.link_field_F = 0;
+ }
+ sHandshakePlayerCount = gLink.playerCount;
+ return FALSE;
+}