through DequeueRecvCmd

This commit is contained in:
PikalaxALT 2017-11-14 08:31:37 -05:00
parent c81d50cb2f
commit 6f8da5dcb6
6 changed files with 255 additions and 401 deletions

View File

@ -5,290 +5,6 @@
.text .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 thumb_func_start sub_800B9B8
sub_800B9B8: @ 800B9B8 sub_800B9B8: @ 800B9B8
push {r4,lr} push {r4,lr}

View File

@ -3725,7 +3725,7 @@ _0800FBB0:
b _0800FC08 b _0800FC08
.pool .pool
_0800FBF4: _0800FBF4:
ldr r0, =gUnknown_03003020 ldr r0, =gLinkPartnersHeldKeys
mov r3, r8 mov r3, r8
lsls r1, r3, 1 lsls r1, r3, 1
adds r1, r0 adds r1, r0

View File

@ -4578,7 +4578,7 @@ c1_link_related: @ 8086BD8
_08086BF2: _08086BF2:
ldr r0, =gUnknown_03005DB4 ldr r0, =gUnknown_03005DB4
ldrb r4, [r0] ldrb r4, [r0]
ldr r0, =gUnknown_03003020 ldr r0, =gLinkPartnersHeldKeys
adds r1, r4, 0 adds r1, r4, 0
bl sub_8086F38 bl sub_8086F38
ldr r0, =gUnknown_03000E14 ldr r0, =gUnknown_03000E14
@ -4610,7 +4610,7 @@ sub_8086C2C: @ 8086C2C
thumb_func_start sub_8086C40 thumb_func_start sub_8086C40
sub_8086C40: @ 8086C40 sub_8086C40: @ 8086C40
push {lr} push {lr}
ldr r0, =gUnknown_03003020 ldr r0, =gLinkPartnersHeldKeys
bl sub_808709C bl sub_808709C
pop {r0} pop {r0}
bx r0 bx r0

View File

@ -1,11 +1,11 @@
gUnknown_03003020 gLinkPartnersHeldKeys
gLinkDebugSeed gLinkDebugSeed
gLocalLinkPlayerBlock gLocalLinkPlayerBlock
gLinkErrorOccurred gLinkErrorOccurred
gLinkDebugFlags gLinkDebugFlags
gUnknown_03003074 gFiller_03003074
gUnknown_03003078 gRemoteLinkPlayersNotReceived
gUnknown_0300307C gBlockReceivedStatus
gFiller_03003080 gFiller_03003080
gLinkHeldKeys gLinkHeldKeys
gRecvCmds gRecvCmds
@ -32,6 +32,6 @@ gFiller_0300315c
gLastSendQueueCount gLastSendQueueCount
gLink gLink
gLastRecvQueueCount gLastRecvQueueCount
gUnknown_03004134 gLinkSavedIme
gFiller_03004138 gFiller_03004138
gFiller_0300413C gFiller_0300413C

View File

@ -7,6 +7,9 @@
#define QUEUE_CAPACITY 50 #define QUEUE_CAPACITY 50
#define BLOCK_BUFFER_SIZE 0x100 #define BLOCK_BUFFER_SIZE 0x100
#define LINK_SLAVE 0
#define LINK_MASTER 8
#define LINK_STAT_LOCAL_ID 0x00000003 #define LINK_STAT_LOCAL_ID 0x00000003
#define LINK_STAT_PLAYER_COUNT 0x0000001C #define LINK_STAT_PLAYER_COUNT 0x0000001C
#define LINK_STAT_PLAYER_COUNT_SHIFT 2 #define LINK_STAT_PLAYER_COUNT_SHIFT 2
@ -16,9 +19,24 @@
#define LINK_STAT_CONN_ESTABLISHED_SHIFT 6 #define LINK_STAT_CONN_ESTABLISHED_SHIFT 6
#define LINK_STAT_RECEIVED_NOTHING 0x00000100 #define LINK_STAT_RECEIVED_NOTHING 0x00000100
#define LINK_STAT_RECEIVED_NOTHING_SHIFT 8 #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 0x0007F000
#define LINK_STAT_ERRORS_SHIFT 12 #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) \ #define EXTRACT_PLAYER_COUNT(status) \
(((status) & LINK_STAT_PLAYER_COUNT) >> LINK_STAT_PLAYER_COUNT_SHIFT) (((status) & LINK_STAT_PLAYER_COUNT) >> LINK_STAT_PLAYER_COUNT_SHIFT)
#define EXTRACT_MASTER(status) \ #define EXTRACT_MASTER(status) \
@ -30,6 +48,21 @@
#define EXTRACT_LINK_ERRORS(status) \ #define EXTRACT_LINK_ERRORS(status) \
(((status) & LINK_STAT_ERRORS) >> LINK_STAT_ERRORS_SHIFT) (((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 struct LinkStatus
{ {
u32 localId:2; u32 localId:2;
@ -215,13 +248,13 @@ void sub_800B524(struct LinkPlayer *linkPlayer);
u8 GetSioMultiSI(void); u8 GetSioMultiSI(void);
void sub_800B9B8(void); void sub_800B9B8(void);
extern u16 gUnknown_03003020[6]; extern u16 gLinkPartnersHeldKeys[6];
extern u32 gLinkDebugSeed; extern u32 gLinkDebugSeed;
extern struct LinkPlayerBlock gLocalLinkPlayerBlock; extern struct LinkPlayerBlock gLocalLinkPlayerBlock;
extern bool8 gLinkErrorOccurred; extern bool8 gLinkErrorOccurred;
extern u32 gLinkDebugFlags; extern u32 gLinkDebugFlags;
extern bool8 gUnknown_03003078[MAX_LINK_PLAYERS]; extern bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS];
extern u8 gUnknown_0300307C[MAX_LINK_PLAYERS]; extern u8 gBlockReceivedStatus[MAX_LINK_PLAYERS];
extern u16 gLinkHeldKeys; extern u16 gLinkHeldKeys;
extern u32 gLinkStatus; extern u32 gLinkStatus;
extern u8 gUnknown_030030E4; extern u8 gUnknown_030030E4;
@ -240,8 +273,8 @@ extern u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS];
extern u8 gBlockRequestType; extern u8 gBlockRequestType;
extern u8 gLastSendQueueCount; extern u8 gLastSendQueueCount;
extern u8 gLastRecvQueueCount; extern u8 gLastRecvQueueCount;
extern u16 gUnknown_03004134; extern u16 gLinkSavedIme;
extern u32 gUnknown_03003074; extern u32 gFiller_03003074;
extern u32 gFiller_03003154; extern u32 gFiller_03003154;
extern u32 gFiller_03003158; extern u32 gFiller_03003158;
extern u32 gFiller_0300315c; extern u32 gFiller_0300315c;

View File

@ -62,20 +62,20 @@ IWRAM_DATA u8 sLinkTestLastBlockSendPos;
ALIGNED() IWRAM_DATA u8 sLinkTestLastBlockRecvPos[MAX_LINK_PLAYERS]; ALIGNED() IWRAM_DATA u8 sLinkTestLastBlockRecvPos[MAX_LINK_PLAYERS];
IWRAM_DATA u8 gUnknown_03000D6C; IWRAM_DATA u8 gUnknown_03000D6C;
IWRAM_DATA bool8 gUnknown_03000D6D; IWRAM_DATA bool8 gUnknown_03000D6D;
IWRAM_DATA u16 gUnknown_03000D6E; IWRAM_DATA u16 sSendNonzeroCheck;
IWRAM_DATA u16 gUnknown_03000D70; IWRAM_DATA u16 gUnknown_03000D70;
IWRAM_DATA u8 gUnknown_03000D72; IWRAM_DATA u8 gUnknown_03000D72;
IWRAM_DATA u8 gUnknown_03000D73; IWRAM_DATA u8 gUnknown_03000D73;
IWRAM_DATA u8 gUnknown_03000D74; IWRAM_DATA u8 gUnknown_03000D74;
u16 gUnknown_03003020[6]; u16 gLinkPartnersHeldKeys[6];
u32 gLinkDebugSeed; u32 gLinkDebugSeed;
struct LinkPlayerBlock gLocalLinkPlayerBlock; struct LinkPlayerBlock gLocalLinkPlayerBlock;
bool8 gLinkErrorOccurred; bool8 gLinkErrorOccurred;
u32 gLinkDebugFlags; u32 gLinkDebugFlags;
u32 gUnknown_03003074; u32 gFiller_03003074;
bool8 gUnknown_03003078[MAX_LINK_PLAYERS]; bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS];
u8 gUnknown_0300307C[MAX_LINK_PLAYERS]; u8 gBlockReceivedStatus[MAX_LINK_PLAYERS];
u32 gFiller_03003080; u32 gFiller_03003080;
u16 gLinkHeldKeys; u16 gLinkHeldKeys;
u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH]; u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH];
@ -102,7 +102,7 @@ u32 gFiller_0300315c;
u8 gLastSendQueueCount; u8 gLastSendQueueCount;
struct Link gLink; struct Link gLink;
u8 gLastRecvQueueCount; u8 gLastRecvQueueCount;
u16 gUnknown_03004134; u16 gLinkSavedIme;
u32 gFiller_03004138; u32 gFiller_03004138;
u32 gFiller_0300413C; u32 gFiller_0300413C;
@ -128,8 +128,8 @@ EWRAM_DATA void *gUnknown_02022B0C = NULL;
// Static ROM declarations // Static ROM declarations
void InitLocalLinkPlayer(void); static void InitLocalLinkPlayer(void);
void sub_80096BC(void); static void sub_80096BC(void);
static void CB2_LinkTest(void); static void CB2_LinkTest(void);
static void ProcessRecvCmds(u8 unused); static void ProcessRecvCmds(u8 unused);
static void sub_8009F70(void); static void sub_8009F70(void);
@ -152,15 +152,13 @@ static void sub_800AE5C(void);
static void CheckErrorStatus(void); static void CheckErrorStatus(void);
static void CB2_PrintErrorMessage(void); static void CB2_PrintErrorMessage(void);
static bool8 IsSioMultiMaster(void); static bool8 IsSioMultiMaster(void);
u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENGTH]);
static void sub_800B4A4(void); static void sub_800B4A4(void);
void DisableSerial(void); static void DisableSerial(void);
void EnableSerial(void); static void EnableSerial(void);
static void CheckMasterOrSlave(void);
void sub_800B764(void); static void InitTimer(void);
void sub_800B790(void); static void EnqueueSendCmd(u16 *sendCmd);
void sub_800B7C0(u16 *queue); static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]);
void sub_800B8A8(u16 (*queue)[CMD_LENGTH]);
// .rodata // .rodata
@ -300,7 +298,7 @@ void sub_8009628(u8 a0)
gLocalLinkPlayer.lp_field_18 = 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); gLocalLinkPlayer.trainerId = gSaveBlock2Ptr->playerTrainerId[0] | (gSaveBlock2Ptr->playerTrainerId[1] << 8) | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
StringCopy(gLocalLinkPlayer.name, gSaveBlock2Ptr->playerName); StringCopy(gLocalLinkPlayer.name, gSaveBlock2Ptr->playerName);
@ -316,14 +314,14 @@ void InitLocalLinkPlayer(void)
} }
} }
void sub_80096BC(void) static void sub_80096BC(void)
{ {
LoadOam(); LoadOam();
ProcessSpriteCopyRequests(); ProcessSpriteCopyRequests();
TransferPlttBuffer(); TransferPlttBuffer();
} }
void InitLink(void) static void InitLink(void)
{ {
int i; int i;
@ -335,7 +333,7 @@ void InitLink(void)
EnableSerial(); EnableSerial();
} }
void Task_TriggerHandshake(u8 taskId) static void Task_TriggerHandshake(u8 taskId)
{ {
if (++ gTasks[taskId].data[0] == 5) if (++ gTasks[taskId].data[0] == 5)
{ {
@ -371,7 +369,7 @@ void OpenLink(void)
gReceivedRemoteLinkPlayers = 0; gReceivedRemoteLinkPlayers = 0;
for (i = 0; i < MAX_LINK_PLAYERS; i ++) for (i = 0; i < MAX_LINK_PLAYERS; i ++)
{ {
gUnknown_03003078[i] = TRUE; gRemoteLinkPlayersNotReceived[i] = TRUE;
gUnknown_030030F0[i] = FALSE; gUnknown_030030F0[i] = FALSE;
gUnknown_030030EC[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) if (gMain.newKeys & A_BUTTON)
{ {
@ -492,16 +490,16 @@ u16 LinkMain2(const u16 *heldKeys)
return gLinkStatus; return gLinkStatus;
} }
void HandleReceiveRemoteLinkPlayer(u8 who) static void HandleReceiveRemoteLinkPlayer(u8 who)
{ {
int i; int i;
int count; int count;
count = 0; count = 0;
gUnknown_03003078[who] = FALSE; gRemoteLinkPlayersNotReceived[who] = FALSE;
for (i = 0; i < GetLinkPlayerCount_2(); i ++) for (i = 0; i < GetLinkPlayerCount_2(); i ++)
{ {
count += gUnknown_03003078[i]; count += gRemoteLinkPlayersNotReceived[i];
} }
if (count == 0 && gReceivedRemoteLinkPlayers == 0) if (count == 0 && gReceivedRemoteLinkPlayers == 0)
{ {
@ -515,14 +513,14 @@ static void ProcessRecvCmds(u8 unused)
for (i = 0; i < MAX_LINK_PLAYERS; i ++) for (i = 0; i < MAX_LINK_PLAYERS; i ++)
{ {
gUnknown_03003020[i] = 0; gLinkPartnersHeldKeys[i] = 0;
if (gRecvCmds[i][0] == 0) if (gRecvCmds[i][0] == 0)
{ {
continue; continue;
} }
switch (gRecvCmds[i][0]) switch (gRecvCmds[i][0])
{ {
case 0x2222: case LINKCMD_SEND_LINK_TYPE:
{ {
struct LinkPlayerBlock *block; struct LinkPlayerBlock *block;
@ -534,16 +532,16 @@ static void ProcessRecvCmds(u8 unused)
InitBlockSend(block, sizeof(*block)); InitBlockSend(block, sizeof(*block));
break; break;
} }
case 0x4444: case LINKCMD_SEND_HELD_KEYS:
gUnknown_03003020[i] = gRecvCmds[i][1]; gLinkPartnersHeldKeys[i] = gRecvCmds[i][1];
break; break;
case 0x5555: case LINKCMD_0x5555:
gUnknown_030030E8 = TRUE; gUnknown_030030E8 = TRUE;
break; break;
case 0x5566: case LINKCMD_0x5566:
gUnknown_030030E8 = TRUE; gUnknown_030030E8 = TRUE;
break; break;
case 0xBBBB: case LINKCMD_INIT_BLOCK:
{ {
struct BlockTransfer *blockRecv; struct BlockTransfer *blockRecv;
@ -553,7 +551,7 @@ static void ProcessRecvCmds(u8 unused)
blockRecv->multiplayerId = gRecvCmds[i][2]; blockRecv->multiplayerId = gRecvCmds[i][2];
break; break;
} }
case 0x8888: case LINKCMD_CONT_BLOCK:
{ {
if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE) if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE)
{ {
@ -580,7 +578,7 @@ static void ProcessRecvCmds(u8 unused)
if (sBlockRecv[i].pos >= sBlockRecv[i].size) if (sBlockRecv[i].pos >= sBlockRecv[i].size)
{ {
if (gUnknown_03003078[i] == TRUE) if (gRemoteLinkPlayersNotReceived[i] == TRUE)
{ {
struct LinkPlayerBlock *block; struct LinkPlayerBlock *block;
struct LinkPlayer *linkPlayer; struct LinkPlayer *linkPlayer;
@ -612,87 +610,87 @@ static void ProcessRecvCmds(u8 unused)
} }
} }
break; break;
case 0x5FFF: case LINKCMD_0x5FFF:
gUnknown_030030F0[i] = TRUE; gUnknown_030030F0[i] = TRUE;
break; break;
case 0x2FFE: case LINKCMD_0x2FFE:
gUnknown_030030EC[i] = TRUE; gUnknown_030030EC[i] = TRUE;
break; break;
case 0xAAAA: case LINKCMD_0xAAAA:
sub_800A418(); sub_800A418();
break; break;
case 0xCCCC: case LINKCMD_0xCCCC:
SendBlock(0, gUnknown_082ED1A8[gRecvCmds[i][1]].address, gUnknown_082ED1A8[gRecvCmds[i][1]].size); SendBlock(0, gUnknown_082ED1A8[gRecvCmds[i][1]].address, gUnknown_082ED1A8[gRecvCmds[i][1]].size);
break; break;
case 0xCAFE: case LINKCMD_SEND_HELD_KEYS_2:
gUnknown_03003020[i] = gRecvCmds[i][1]; gLinkPartnersHeldKeys[i] = gRecvCmds[i][1];
break; break;
} }
} }
} }
void BuildSendCmd(u16 command) static void BuildSendCmd(u16 command)
{ {
switch (command) switch (command)
{ {
case 0x2222: case LINKCMD_SEND_LINK_TYPE:
gSendCmd[0] = 0x2222; gSendCmd[0] = LINKCMD_SEND_LINK_TYPE;
gSendCmd[1] = gLinkType; gSendCmd[1] = gLinkType;
break; break;
case 0x2ffe: case LINKCMD_0x2FFE:
gSendCmd[0] = 0x2ffe; gSendCmd[0] = LINKCMD_0x2FFE;
break; break;
case 0x4444: case LINKCMD_SEND_HELD_KEYS:
gSendCmd[0] = 0x4444; gSendCmd[0] = LINKCMD_SEND_HELD_KEYS;
gSendCmd[1] = gMain.heldKeys; gSendCmd[1] = gMain.heldKeys;
break; break;
case 0x5555: case LINKCMD_0x5555:
gSendCmd[0] = 0x5555; gSendCmd[0] = LINKCMD_0x5555;
break; break;
case 0x6666: case LINKCMD_0x6666:
gSendCmd[0] = 0x6666; gSendCmd[0] = LINKCMD_0x6666;
gSendCmd[1] = 0; gSendCmd[1] = 0;
break; break;
case 0x7777: case LINKCMD_0x7777:
{ {
u8 i; u8 i;
gSendCmd[0] = 0x7777; gSendCmd[0] = LINKCMD_0x7777;
for (i = 0; i < 5; i ++) for (i = 0; i < 5; i ++)
{ {
gSendCmd[i + 1] = 0xEE; gSendCmd[i + 1] = 0xEE;
} }
break; break;
} }
case 0xbbbb: case LINKCMD_INIT_BLOCK:
gSendCmd[0] = 0xbbbb; gSendCmd[0] = LINKCMD_INIT_BLOCK;
gSendCmd[1] = sBlockSend.size; gSendCmd[1] = sBlockSend.size;
gSendCmd[2] = sBlockSend.multiplayerId + 0x80; gSendCmd[2] = sBlockSend.multiplayerId + 0x80;
break; break;
case 0xaaaa: case LINKCMD_0xAAAA:
gSendCmd[0] = 0xaaaa; gSendCmd[0] = LINKCMD_0xAAAA;
break; break;
case 0xaaab: case LINKCMD_0xAAAB:
gSendCmd[0] = 0xaaab; gSendCmd[0] = LINKCMD_0xAAAB;
gSendCmd[1] = gScriptItemId; gSendCmd[1] = gScriptItemId;
break; break;
case 0xcccc: case LINKCMD_0xCCCC:
gSendCmd[0] = 0xcccc; gSendCmd[0] = LINKCMD_0xCCCC;
gSendCmd[1] = gBlockRequestType; gSendCmd[1] = gBlockRequestType;
break; break;
case 0x5fff: case LINKCMD_0x5FFF:
gSendCmd[0] = 0x5fff; gSendCmd[0] = LINKCMD_0x5FFF;
gSendCmd[1] = gUnknown_030030F4; gSendCmd[1] = gUnknown_030030F4;
break; break;
case 0x5566: case LINKCMD_0x5566:
gSendCmd[0] = 0x5566; gSendCmd[0] = LINKCMD_0x5566;
break; break;
case 0xcafe: case LINKCMD_SEND_HELD_KEYS_2:
if (gUnknown_03005DA8 == 0 || gLinkTransferringData) if (gUnknown_03005DA8 == 0 || gLinkTransferringData)
{ {
break; break;
} }
gSendCmd[0] = 0xcafe; gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2;
gSendCmd[1] = gUnknown_03005DA8; gSendCmd[1] = gUnknown_03005DA8;
break; break;
} }
@ -724,7 +722,7 @@ static void sub_8009F70(void)
{ {
if (gReceivedRemoteLinkPlayers == TRUE) if (gReceivedRemoteLinkPlayers == TRUE)
{ {
BuildSendCmd(0xcafe); BuildSendCmd(LINKCMD_SEND_HELD_KEYS_2);
} }
} }
@ -761,7 +759,7 @@ u8 GetLinkPlayerCount(void)
return EXTRACT_PLAYER_COUNT(gLinkStatus); return EXTRACT_PLAYER_COUNT(gLinkStatus);
} }
int sub_8009FF8(u32 version1, u32 version2) static int sub_8009FF8(u32 version1, u32 version2)
{ {
int i; int i;
u8 nPlayers; u8 nPlayers;
@ -964,7 +962,7 @@ static bool32 InitBlockSend(const void *src, size_t size)
} }
sBlockSend.src = gBlockSendBuffer; sBlockSend.src = gBlockSendBuffer;
} }
BuildSendCmd(0xbbbb); BuildSendCmd(LINKCMD_INIT_BLOCK);
gLinkCallback = LinkCB_BlockSendBegin; gLinkCallback = LinkCB_BlockSendBegin;
sBlockSendDelayCounter = 0; sBlockSendDelayCounter = 0;
return TRUE; return TRUE;
@ -984,7 +982,7 @@ static void LinkCB_BlockSend(void)
const u8 *src; const u8 *src;
src = sBlockSend.src; src = sBlockSend.src;
gSendCmd[0] = 0x8888; gSendCmd[0] = LINKCMD_CONT_BLOCK;
for (i = 0; i < 7; i ++) for (i = 0; i < 7; i ++)
{ {
gSendCmd[i + 1] = (src[sBlockSend.pos + i * 2 + 1] << 8) | src[sBlockSend.pos + i * 2]; 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) static void sub_800A3F8(void)
{ {
GetMultiplayerId(); GetMultiplayerId();
BuildSendCmd(0x4444); BuildSendCmd(LINKCMD_SEND_HELD_KEYS);
gUnknown_020223C0 ++; gUnknown_020223C0 ++;
} }
@ -1029,7 +1027,7 @@ u32 sub_800A44C(void)
void sub_800A458(void) void sub_800A458(void)
{ {
BuildSendCmd(0xaaaa); BuildSendCmd(LINKCMD_0xAAAA);
} }
u8 GetMultiplayerId(void) u8 GetMultiplayerId(void)
@ -1067,7 +1065,7 @@ bool8 sub_800A4D8(u8 a0)
if (gLinkCallback == NULL) if (gLinkCallback == NULL)
{ {
gBlockRequestType = a0; gBlockRequestType = a0;
BuildSendCmd(0xcccc); BuildSendCmd(LINKCMD_0xCCCC);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -1088,7 +1086,7 @@ u8 GetBlockReceivedStatus(void)
{ {
return sub_800FCD8(); 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) static void SetBlockReceivedFlag(u8 who)
@ -1099,7 +1097,7 @@ static void SetBlockReceivedFlag(u8 who)
} }
else else
{ {
gUnknown_0300307C[who] = TRUE; gBlockReceivedStatus[who] = TRUE;
} }
} }
@ -1118,7 +1116,7 @@ void ResetBlockReceivedFlags(void)
{ {
for (i = 0; i < MAX_LINK_PLAYERS; i ++) 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); 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) if (gLinkStatus & LINK_STAT_MASTER)
{ {
BuildSendCmd(0x2222); BuildSendCmd(LINKCMD_SEND_LINK_TYPE);
} }
gLinkCallback = NULL; gLinkCallback = NULL;
} }
@ -1456,7 +1454,7 @@ static void sub_800AC80(void)
{ {
if (gLastRecvQueueCount == 0) if (gLastRecvQueueCount == 0)
{ {
BuildSendCmd(0x5fff); BuildSendCmd(LINKCMD_0x5FFF);
gLinkCallback = sub_800ACAC; gLinkCallback = sub_800ACAC;
} }
} }
@ -1511,7 +1509,7 @@ static void sub_800AD5C(void)
{ {
if (gLastRecvQueueCount == 0) if (gLastRecvQueueCount == 0)
{ {
BuildSendCmd(0x5fff); BuildSendCmd(LINKCMD_0x5FFF);
gLinkCallback = sub_800AD88; gLinkCallback = sub_800AD88;
} }
} }
@ -1565,7 +1563,7 @@ static void sub_800AE30(void)
{ {
if (gLastRecvQueueCount == 0) if (gLastRecvQueueCount == 0)
{ {
BuildSendCmd(0x2ffe); BuildSendCmd(LINKCMD_0x2FFE);
gLinkCallback = sub_800AE5C; gLinkCallback = sub_800AE5C;
} }
} }
@ -1901,7 +1899,7 @@ void sub_800B524(struct LinkPlayer *player)
ConvertInternationalString(player->name, player->language); ConvertInternationalString(player->name, player->language);
} }
void DisableSerial(void) static void DisableSerial(void)
{ {
DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
REG_SIOCNT = SIO_MULTI_MODE; REG_SIOCNT = SIO_MULTI_MODE;
@ -1912,7 +1910,7 @@ void DisableSerial(void)
CpuFill32(0, &gLink, sizeof(gLink)); CpuFill32(0, &gLink, sizeof(gLink));
} }
void EnableSerial(void) static void EnableSerial(void)
{ {
DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
REG_RCNT = 0; REG_RCNT = 0;
@ -1922,7 +1920,7 @@ void EnableSerial(void)
REG_SIOMLT_SEND = 0; REG_SIOMLT_SEND = 0;
CpuFill32(0, &gLink, sizeof(gLink)); CpuFill32(0, &gLink, sizeof(gLink));
gUnknown_03000D6C = 0; gUnknown_03000D6C = 0;
gUnknown_03000D6E = 0; sSendNonzeroCheck = 0;
gUnknown_03000D70 = 0; gUnknown_03000D70 = 0;
gUnknown_03000D72 = 0; gUnknown_03000D72 = 0;
gUnknown_03000D73 = 0; gUnknown_03000D73 = 0;
@ -1958,10 +1956,10 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG
switch (*shouldAdvanceLinkState) switch (*shouldAdvanceLinkState)
{ {
default: default:
sub_800B764(); CheckMasterOrSlave();
break; break;
case 1: case 1:
if (gLink.isMaster == 8 && gLink.playerCount > 1) if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1)
{ {
gLink.handshakeAsMaster = TRUE; gLink.handshakeAsMaster = TRUE;
} }
@ -1973,32 +1971,32 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG
} }
break; break;
case LINK_STATE_INIT_TIMER: case LINK_STATE_INIT_TIMER:
sub_800B790(); InitTimer();
gLink.state = LINK_STATE_CONN_ESTABLISHED; gLink.state = LINK_STATE_CONN_ESTABLISHED;
// fallthrough // fallthrough
case LINK_STATE_CONN_ESTABLISHED: case LINK_STATE_CONN_ESTABLISHED:
sub_800B7C0(sendCmd); EnqueueSendCmd(sendCmd);
sub_800B8A8(recvCmds); DequeueRecvCmds(recvCmds);
break; break;
} }
*shouldAdvanceLinkState = 0; *shouldAdvanceLinkState = 0;
retVal = gLink.localId; retVal = gLink.localId;
retVal |= (gLink.playerCount << 2); retVal |= (gLink.playerCount << LINK_STAT_PLAYER_COUNT_SHIFT);
if (gLink.isMaster == 8) if (gLink.isMaster == LINK_MASTER)
{ {
retVal |= 0x20; retVal |= LINK_STAT_MASTER;
} }
{ {
u32 receivedNothing = gLink.receivedNothing << 8; u32 receivedNothing = gLink.receivedNothing << LINK_STAT_RECEIVED_NOTHING_SHIFT;
u32 link_field_F = gLink.link_field_F << 9; u32 link_field_F = gLink.link_field_F << LINK_STAT_UNK_FLAG_9_SHIFT;
u32 hardwareError = gLink.hardwareError << 12; u32 hardwareError = gLink.hardwareError << LINK_STAT_ERROR_HARDWARE_SHIFT;
u32 badChecksum = gLink.badChecksum << 13; u32 badChecksum = gLink.badChecksum << LINK_STAT_ERROR_CHECKSUM_SHIFT;
u32 queueFull = gLink.queueFull << 14; u32 queueFull = gLink.queueFull << LINK_STAT_ERROR_QUEUE_FULL_SHIFT;
u32 val; u32 val;
if (gLink.state == LINK_STATE_CONN_ESTABLISHED) if (gLink.state == LINK_STATE_CONN_ESTABLISHED)
{ {
val = 0x40; val = LINK_STAT_CONN_ESTABLISHED;
val |= receivedNothing; val |= receivedNothing;
val |= retVal; val |= retVal;
val |= link_field_F; val |= link_field_F;
@ -2020,14 +2018,121 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG
} }
if (gLink.lag == LAG_MASTER) if (gLink.lag == LAG_MASTER)
retVal |= 0x10000; {
retVal |= LINK_STAT_ERROR_LAG_MASTER;
}
if (gLink.localId > 3) if (gLink.localId >= MAX_LINK_PLAYERS)
retVal |= 0x20000; {
retVal |= LINK_STAT_ERROR_INVALID_ID;
}
retVal2 = retVal; retVal2 = retVal;
if (gLink.lag == LAG_SLAVE) if (gLink.lag == LAG_SLAVE)
retVal2 |= 0x40000; {
retVal2 |= LINK_STAT_ERROR_LAG_SLAVE;
}
return retVal2; 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;
}