From 57e73f22e6388d7b3434aece490583b836ec0e69 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Fri, 21 Feb 2025 15:24:51 -0500 Subject: [PATCH 01/13] apply 08facd523e99661be99b61dc10b8f2b9516244ad from https://github.com/FazanaJ/Diddy-Kong-Racing --- include/PR/os_cont.h | 8 ++++++++ src/io/contreaddata.c | 6 ++++++ src/io/controller.c | 2 ++ src/io/contsetch.c | 17 +++++++++++++++++ src/io/pfsisplug.c | 12 ++++++++++++ 5 files changed, 45 insertions(+) diff --git a/include/PR/os_cont.h b/include/PR/os_cont.h index 942a8fa2..61cfdb81 100644 --- a/include/PR/os_cont.h +++ b/include/PR/os_cont.h @@ -161,6 +161,12 @@ typedef struct { #define CONT_ERR_VOICE_WORD 14 #define CONT_ERR_VOICE_NO_RESPONSE 15 +// Controller mask values +#define CONT_P1 0x01 +#define CONT_P2 0x02 +#define CONT_P3 0x04 +#define CONT_P4 0x08 + #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) /************************************************************************** @@ -174,6 +180,7 @@ typedef struct { * Extern variables * */ +extern u8 __osControllerMask; /************************************************************************** * @@ -190,6 +197,7 @@ extern s32 osContStartReadData(OSMesgQueue*); #ifndef _HW_VERSION_1 extern s32 osContSetCh(u8); #endif +extern s32 osContSetMask(u8 ch); extern void osContGetQuery(OSContStatus*); extern void osContGetReadData(OSContPad*); diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index a2b17302..d20d6ce5 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -29,6 +29,9 @@ void osContGetReadData(OSContPad* data) { int i; for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(__OSContReadFormat), data++) { + if ((__osControllerMask & (1 << i)) == 0) { + continue; + } readformat = *(__OSContReadFormat*)ptr; data->errno = CHNL_ERR(readformat); @@ -61,6 +64,9 @@ static void __osPackReadData(void) { readformat.stick_y = -1; for (i = 0; i < __osMaxControllers; i++) { + if ((__osControllerMask & (1 << i)) == 0) { + continue; + } *(__OSContReadFormat*)ptr = readformat; ptr += sizeof(__OSContReadFormat); } diff --git a/src/io/controller.c b/src/io/controller.c index fd87b163..03c4fd75 100644 --- a/src/io/controller.c +++ b/src/io/controller.c @@ -10,6 +10,7 @@ u8 __osMaxControllers; OSTimer __osEepromTimer; OSMesgQueue __osEepromTimerQ ALIGNED(0x8); OSMesg __osEepromTimerMsg; +u8 __osControllerMask; s32 __osContinitialized = FALSE; @@ -25,6 +26,7 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) { } __osContinitialized = TRUE; + __osControllerMask = CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4; t = osGetTime(); if (t < OS_USEC_TO_CYCLES(500000)) { diff --git a/src/io/contsetch.c b/src/io/contsetch.c index 2f7a33fe..d2d78b5a 100644 --- a/src/io/contsetch.c +++ b/src/io/contsetch.c @@ -21,3 +21,20 @@ s32 osContSetCh(u8 ch) { __osSiRelAccess(); return ret; } + +s32 osContSetMask(u8 mask) { + s32 ret = 0; + s32 i; + + __osSiGetAccess(); + + if (mask > (CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4)) { + __osControllerMask = CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4; + } else { + __osControllerMask = mask; + } + + __osContLastCmd = CONT_CMD_END; + __osSiRelAccess(); + return ret; +} diff --git a/src/io/pfsisplug.c b/src/io/pfsisplug.c index 01040305..ebaf8b88 100644 --- a/src/io/pfsisplug.c +++ b/src/io/pfsisplug.c @@ -28,6 +28,9 @@ s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) { __osPfsGetInitData(&bitpattern, &contData[0]); for (channel = 0; channel < __osMaxControllers; channel++) { + if ((__osControllerMask & (1 << channel)) == 0) { + continue; + } if ((contData[channel].status & CONT_ADDR_CRC_ER) == 0) { crcErrorCount--; break; @@ -40,6 +43,9 @@ s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) { } while (crcErrorCount > 0); for (channel = 0; channel < __osMaxControllers; channel++) { + if ((__osControllerMask & (1 << channel)) == 0) { + continue; + } if ((contData[channel].errno == 0) && ((contData[channel].status & CONT_CARD_ON) != 0)) { bits |= (1 << channel); } @@ -66,6 +72,9 @@ void __osPfsRequestData(u8 cmd) { requestformat.dummy1 = CONT_CMD_NOP; for (i = 0; i < __osMaxControllers; i++) { + if ((__osControllerMask & (1 << i)) == 0) { + continue; + } *((__OSContRequesFormat*)ptr) = requestformat; ptr += sizeof(__OSContRequesFormat); } @@ -82,6 +91,9 @@ void __osPfsGetInitData(u8* pattern, OSContStatus* data) { ptr = (u8*)&__osPfsPifRam; for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(requestformat), data++) { + if ((__osControllerMask & (1 << i)) == 0) { + continue; + } requestformat = *((__OSContRequesFormat*)ptr); data->errno = CHNL_ERR(requestformat); From a70e3bf1ad29be4661cedcf8e090277fcea42797 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Fri, 21 Feb 2025 17:29:01 -0500 Subject: [PATCH 02/13] bit defines --- include/PR/os_cont.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/PR/os_cont.h b/include/PR/os_cont.h index 61cfdb81..eb4bc3d8 100644 --- a/include/PR/os_cont.h +++ b/include/PR/os_cont.h @@ -162,10 +162,10 @@ typedef struct { #define CONT_ERR_VOICE_NO_RESPONSE 15 // Controller mask values -#define CONT_P1 0x01 -#define CONT_P2 0x02 -#define CONT_P3 0x04 -#define CONT_P4 0x08 +#define CONT_P1 (1 << 0) +#define CONT_P2 (1 << 1) +#define CONT_P3 (1 << 2) +#define CONT_P4 (1 << 3) #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) From 8d4b47dfdb9232bf943601da420a5523dc8d1359 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Fri, 21 Feb 2025 17:32:29 -0500 Subject: [PATCH 03/13] explicitly tell PI to skip --- src/io/contreaddata.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index d20d6ce5..bb7dcf4d 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -65,6 +65,7 @@ static void __osPackReadData(void) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { + *ptr++ = CONT_CMD_NOP; continue; } *(__OSContReadFormat*)ptr = readformat; From d7c848c33811f9f414a4a07626ac499eb9a54c55 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Fri, 21 Feb 2025 21:42:29 -0500 Subject: [PATCH 04/13] 0 is skip channel --- src/io/contreaddata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index bb7dcf4d..5919cdf4 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -65,7 +65,7 @@ static void __osPackReadData(void) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { - *ptr++ = CONT_CMD_NOP; + *ptr++ = 0; continue; } *(__OSContReadFormat*)ptr = readformat; From dca5cfc2a5e9e35346981c616c529e9be35e9e0d Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 09:54:50 -0500 Subject: [PATCH 05/13] merge latest changs to actually skip a channel --- src/io/contreaddata.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index 5919cdf4..06b99d64 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -56,17 +56,19 @@ static void __osPackReadData(void) { __osContPifRam.pifstatus = CONT_CMD_EXE; readformat.dummy = CONT_CMD_NOP; - readformat.txsize = CONT_CMD_READ_BUTTON_TX; - readformat.rxsize = CONT_CMD_READ_BUTTON_RX; - readformat.cmd = CONT_CMD_READ_BUTTON; readformat.button = 0xFFFF; readformat.stick_x = -1; readformat.stick_y = -1; for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { - *ptr++ = 0; - continue; + readformat.txsize = CONT_CMD_NOP; + readformat.rxsize = CONT_CMD_NOP; + readformat.cmd = 0; + } else { + readformat.txsize = CONT_CMD_READ_BUTTON_TX; + readformat.rxsize = CONT_CMD_READ_BUTTON_RX; + readformat.cmd = CONT_CMD_READ_BUTTON; } *(__OSContReadFormat*)ptr = readformat; ptr += sizeof(__OSContReadFormat); From 80bd02af856b438c6f6d6d017e93b807b40a9ce5 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 11:34:12 -0500 Subject: [PATCH 06/13] add new version of SetMask --- src/io/controller.c | 2 +- src/io/contsetch.c | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/io/controller.c b/src/io/controller.c index 03c4fd75..576717e5 100644 --- a/src/io/controller.c +++ b/src/io/controller.c @@ -35,7 +35,7 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) { osRecvMesg(&timerMesgQueue, &dummy, OS_MESG_BLOCK); } - __osMaxControllers = 4; + __osMaxControllers = MAXCONTROLLERS; __osPackRequestData(CONT_CMD_REQUEST_STATUS); diff --git a/src/io/contsetch.c b/src/io/contsetch.c index d2d78b5a..984601a5 100644 --- a/src/io/contsetch.c +++ b/src/io/contsetch.c @@ -22,19 +22,35 @@ s32 osContSetCh(u8 ch) { return ret; } -s32 osContSetMask(u8 mask) { +/* + * Use a mask to detect controller channels instead, allowing the PIF to skip channels instead of + * spending time reading data. + * This does not work on iQue Player. + */ +s32 osContSetMask(u8 ch) { s32 ret = 0; - s32 i; +#ifdef BBPLAYER + return ret; +#else __osSiGetAccess(); - if (mask > (CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4)) { - __osControllerMask = CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4; + if ((ch == 0) || (ch > (CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4))) { + __osControllerMask = (CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4); + __osMaxControllers = MAXCONTROLLERS; } else { - __osControllerMask = mask; + __osControllerMask = ch; + for (s32 i = 0; i < MAXCONTROLLERS; i++) { + if (ch & (1 << i)) { + __osMaxControllers = i; + } + } + __osMaxControllers++; } __osContLastCmd = CONT_CMD_END; __osSiRelAccess(); return ret; +#endif } + From 94c584d4bad4596ead010da1a29939b50cf214be Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 11:35:07 -0500 Subject: [PATCH 07/13] formatting --- src/io/contsetch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/io/contsetch.c b/src/io/contsetch.c index 984601a5..d376e237 100644 --- a/src/io/contsetch.c +++ b/src/io/contsetch.c @@ -31,7 +31,7 @@ s32 osContSetMask(u8 ch) { s32 ret = 0; #ifdef BBPLAYER - return ret; + return ret; #else __osSiGetAccess(); @@ -53,4 +53,3 @@ s32 osContSetMask(u8 ch) { return ret; #endif } - From 1719335ba5d91bb9b64651ff9409a1a6ffcbd7e3 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 21:15:46 -0500 Subject: [PATCH 08/13] should skip channels in __osPfsRequestData --- src/io/pfsisplug.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/io/pfsisplug.c b/src/io/pfsisplug.c index ebaf8b88..5fa7020a 100644 --- a/src/io/pfsisplug.c +++ b/src/io/pfsisplug.c @@ -63,9 +63,6 @@ void __osPfsRequestData(u8 cmd) { __osContLastCmd = cmd; __osPfsPifRam.pifstatus = CONT_CMD_EXE; requestformat.dummy = CONT_CMD_NOP; - requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX; - requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; - requestformat.cmd = cmd; requestformat.typeh = CONT_CMD_NOP; requestformat.typel = CONT_CMD_NOP; requestformat.status = CONT_CMD_NOP; @@ -73,7 +70,13 @@ void __osPfsRequestData(u8 cmd) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { - continue; + readformat.txsize = CONT_CMD_NOP; + readformat.rxsize = CONT_CMD_NOP; + readformat.cmd = 0; + } else { + readformat.txsize = CONT_CMD_REQUEST_STATUS_TX; + readformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; + readformat.cmd = cmd; } *((__OSContRequesFormat*)ptr) = requestformat; ptr += sizeof(__OSContRequesFormat); From b437da4fd6e1dd9b41f1262bcfce2645e5a0b677 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 21:16:40 -0500 Subject: [PATCH 09/13] force correct max cont and mask values on ique --- src/io/contsetch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/io/contsetch.c b/src/io/contsetch.c index d376e237..ce0d0473 100644 --- a/src/io/contsetch.c +++ b/src/io/contsetch.c @@ -31,6 +31,8 @@ s32 osContSetMask(u8 ch) { s32 ret = 0; #ifdef BBPLAYER + __osControllerMask = (CONT_P1 | CONT_P2 | CONT_P3 | CONT_P4); + __osMaxControllers = MAXCONTROLLERS; return ret; #else __osSiGetAccess(); From 113783a9ea5835021f687458aee3d95ad0ca34a0 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 21:17:27 -0500 Subject: [PATCH 10/13] make SetCh transparent, compile error in pfsisplug --- src/io/contsetch.c | 14 +------------- src/io/pfsisplug.c | 12 ++++++------ 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/io/contsetch.c b/src/io/contsetch.c index ce0d0473..52ce50bd 100644 --- a/src/io/contsetch.c +++ b/src/io/contsetch.c @@ -7,19 +7,7 @@ * to multiple direct SI devices. */ s32 osContSetCh(u8 ch) { - s32 ret = 0; - - __osSiGetAccess(); - - if (ch > MAXCONTROLLERS) { - __osMaxControllers = MAXCONTROLLERS; - } else { - __osMaxControllers = ch; - } - - __osContLastCmd = CONT_CMD_END; - __osSiRelAccess(); - return ret; + return osContSetMask((1 << ch) - 1); } /* diff --git a/src/io/pfsisplug.c b/src/io/pfsisplug.c index 5fa7020a..3ac562b3 100644 --- a/src/io/pfsisplug.c +++ b/src/io/pfsisplug.c @@ -70,13 +70,13 @@ void __osPfsRequestData(u8 cmd) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { - readformat.txsize = CONT_CMD_NOP; - readformat.rxsize = CONT_CMD_NOP; - readformat.cmd = 0; + requestformat.txsize = CONT_CMD_NOP; + requestformat.rxsize = CONT_CMD_NOP; + requestformat.cmd = 0; } else { - readformat.txsize = CONT_CMD_REQUEST_STATUS_TX; - readformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; - readformat.cmd = cmd; + requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX; + requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX; + requestformat.cmd = cmd; } *((__OSContRequesFormat*)ptr) = requestformat; ptr += sizeof(__OSContRequesFormat); From 58783212e741a7b6836319180ba291f92667a05e Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 21:27:05 -0500 Subject: [PATCH 11/13] document why the code is written like that --- src/io/contreaddata.c | 5 +++++ src/io/pfsisplug.c | 1 + 2 files changed, 6 insertions(+) diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index 06b99d64..5a50b1d3 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -62,6 +62,11 @@ static void __osPackReadData(void) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { + // In the Joybus frame, a packet is sent to the PIF chip describing the number of bytes to transfer and receive + // over the protocol. There are two special commands, 0x00 (skip) and 0xFF (nop). This function senda a packet + // with the layout: FF FF FF 00 FF FF FF FF, basically saying to skip the channel, with some extra bytes + // that do nothing, allowing the next packet to be processed. This wastes memory, but it works. + // Source: https://n64brew.dev/wiki/PIF-NUS#Joybus_frame_(controller_and_EEPROM_communication) readformat.txsize = CONT_CMD_NOP; readformat.rxsize = CONT_CMD_NOP; readformat.cmd = 0; diff --git a/src/io/pfsisplug.c b/src/io/pfsisplug.c index 3ac562b3..a2278efe 100644 --- a/src/io/pfsisplug.c +++ b/src/io/pfsisplug.c @@ -70,6 +70,7 @@ void __osPfsRequestData(u8 cmd) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { + // See __osPackReadData in contreaddata.c for an explanation for this behavior. requestformat.txsize = CONT_CMD_NOP; requestformat.rxsize = CONT_CMD_NOP; requestformat.cmd = 0; From 9cc8aba8a934c8c85848e51f48fa35a4c48e63df Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 21:27:53 -0500 Subject: [PATCH 12/13] why does clang-format format comments --- src/io/contreaddata.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index 5a50b1d3..bdf1247b 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -62,10 +62,10 @@ static void __osPackReadData(void) { for (i = 0; i < __osMaxControllers; i++) { if ((__osControllerMask & (1 << i)) == 0) { - // In the Joybus frame, a packet is sent to the PIF chip describing the number of bytes to transfer and receive - // over the protocol. There are two special commands, 0x00 (skip) and 0xFF (nop). This function senda a packet - // with the layout: FF FF FF 00 FF FF FF FF, basically saying to skip the channel, with some extra bytes - // that do nothing, allowing the next packet to be processed. This wastes memory, but it works. + // In the Joybus frame, a packet is sent to the PIF chip describing the number of bytes to transfer and + // receive over the protocol. There are two special commands, 0x00 (skip) and 0xFF (nop). This function + // senda a packet with the layout: FF FF FF 00 FF FF FF FF, basically saying to skip the channel, with some + // extra bytes that do nothing, allowing the next packet to be processed. This wastes memory, but it works. // Source: https://n64brew.dev/wiki/PIF-NUS#Joybus_frame_(controller_and_EEPROM_communication) readformat.txsize = CONT_CMD_NOP; readformat.rxsize = CONT_CMD_NOP; From 71fd3c6af58ad8ede4294cc0b379ce4b89f812c0 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sat, 22 Feb 2025 21:32:12 -0500 Subject: [PATCH 13/13] i send a the channel --- src/io/contreaddata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index bdf1247b..9b552c0d 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -64,7 +64,7 @@ static void __osPackReadData(void) { if ((__osControllerMask & (1 << i)) == 0) { // In the Joybus frame, a packet is sent to the PIF chip describing the number of bytes to transfer and // receive over the protocol. There are two special commands, 0x00 (skip) and 0xFF (nop). This function - // senda a packet with the layout: FF FF FF 00 FF FF FF FF, basically saying to skip the channel, with some + // sends a packet with the layout: FF FF FF 00 FF FF FF FF, basically saying to skip the channel, with some // extra bytes that do nothing, allowing the next packet to be processed. This wastes memory, but it works. // Source: https://n64brew.dev/wiki/PIF-NUS#Joybus_frame_(controller_and_EEPROM_communication) readformat.txsize = CONT_CMD_NOP;