diff --git a/include/functions.h b/include/functions.h index ab8384a06..0043a3544 100644 --- a/include/functions.h +++ b/include/functions.h @@ -351,7 +351,7 @@ void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac); s32 osVoiceClearDictionary(OSVoiceHandle* hd, u8 words); void osUnmapTLBAll(void); s32 osEPiStartDma(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction); -s32 __osVoiceContRead2(OSMesgQueue* mq, s32 port, u16, u8 dst[2]); +s32 __osVoiceContRead2(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[2]); u8 __osVoiceContDataCrc(u8* data, u32 arg1); const char* strchr(const char* __s, s32 __c); size_t strlen(const char* __s); @@ -363,7 +363,7 @@ void __osTimerServicesInit(void); void __osTimerInterrupt(void); void __osSetTimerIntr(OSTime tim); OSTime __osInsertTimer(OSTimer* t); -s32 __osVoiceContRead36(OSMesgQueue* mq, s32 port, s32, u8*); +s32 __osVoiceContRead36(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[36]); s32 __osSpDeviceBusy(void); s32 __osSiDeviceBusy(void); // void guMtxIdent(void); diff --git a/src/libultra/voice/voicecontread2.c b/src/libultra/voice/voicecontread2.c index e1d260372..64ac40605 100644 --- a/src/libultra/voice/voicecontread2.c +++ b/src/libultra/voice/voicecontread2.c @@ -2,7 +2,7 @@ extern s32 D_80097FB0; -s32 __osVoiceContRead2(OSMesgQueue* mq, s32 port, u16 arg2, u8* dst) { +s32 __osVoiceContRead2(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[2]) { u8* ptr; u8 status; s32 errorCode; diff --git a/src/libultra/voice/voicecontread36.c b/src/libultra/voice/voicecontread36.c index 38f3fe2f0..081b9a534 100644 --- a/src/libultra/voice/voicecontread36.c +++ b/src/libultra/voice/voicecontread36.c @@ -1,3 +1,68 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontread36/__osVoiceContRead36.s") +extern s32 D_80097FB0; + +s32 __osVoiceContRead36(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[36]) { + u8* ptr; + u8 status; + s32 errorCode; + s32 retryCount = 2; + s32 i; + + __osSiGetAccess(); + + do { + + ptr = (u8*)&__osPfsPifRam; + + if ((__osContLastCmd != 9) || (port != D_80097FB0)) { + __osContLastCmd = 9; + D_80097FB0 = port; + + for (i = 0; i < port; i++, *ptr++ = 0) { + ; + } + + __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; + + ptr[0] = 0xFF; + ptr[1] = 3; + ptr[2] = 0x25; + ptr[3] = 9; + ptr[0x2A] = 0xFF; + ptr[0x2B] = 0xFE; + } else { + ptr = (u8*)&__osPfsPifRam + port; + } + + ptr[4] = arg2 >> 3; + ptr[5] = __osContAddressCrc(arg2) | (arg2 << 5); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + errorCode = (ptr[2] & 0xC0) >> 4; + + if (errorCode == 0) { + if (ptr[0x2A] != __osVoiceContDataCrc(&ptr[6], 36)) { + errorCode = __osVoiceGetStatus(mq, port, &status); + if (errorCode != 0) { + break; + } + + errorCode = CONT_ERR_CONTRFAIL; + } else { + bcopy(&ptr[6], dst, 36); + } + } else { + errorCode = CONT_ERR_NO_CONTROLLER; + } + + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); + + __osSiRelAccess(); + + return errorCode; +}