diff --git a/include/functions.h b/include/functions.h index 04f6dfb732..6a9ebcf60f 100644 --- a/include/functions.h +++ b/include/functions.h @@ -157,7 +157,6 @@ void osStopThread(OSThread* t); s32 osRecvMesg(OSMesgQueue* mq, OSMesg* msg, s32 flags); OSIntMask osSetIntMask(OSIntMask im); // OSIntMask osGetIntMask(void); -// void osVoiceSetWord(void); void guScale(Mtx* mtx, f32 x, f32 y, f32 z); f32 sinf(f32 __x); s16 sins(u16 x); @@ -186,7 +185,6 @@ void __osDispatchThread(void); void __osCleanupThread(void); void __osDequeueThread(OSThread** queue, OSThread* t); void osDestroyThread(OSThread* t); -// void __osVoiceCheckResult(void); void bzero(void* begin, s32 length); void __osSiCreateAccessQueue(void); @@ -199,7 +197,6 @@ void osCreateThread(OSThread* t, OSId id, void* entry, void* arg, void* sp, OSPr s32 osContStartReadData(OSMesgQueue* mq); void osContGetReadData(OSContPad* data); void __osPackReadData(void); -// void osVoiceGetReadData(void); uintptr_t osVirtualToPhysical(void* virtualAddress); u32 __osGetSR(void); void __osSetSR(u32 value); @@ -258,11 +255,8 @@ void guLookAtHiliteF(float mf[4][4], LookAt* l, Hilite* h, f32 xEye, f32 yEye, f void guLookAtHilite(Mtx* m, LookAt* l, Hilite* h, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp, f32 xl1, f32 yl1, f32 zl1, f32 xl2, f32 yl2, f32 zl2, s32 hiliteWidth, s32 hiliteHeight); s32 _Printf(PrintCallback pfn, void* arg, const char* fmt, va_list ap); void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac); -// void osVoiceClearDictionary(void); void osUnmapTLBAll(void); s32 osEPiStartDma(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction); -// void __osVoiceContRead2(void); -u8 __osVoiceContDataCrc(u8* data, size_t numBytes); const char* strchr(const char* s, s32 c); size_t strlen(const char* s); void* memcpy(void* s1, const void* s2, size_t n); @@ -273,7 +267,6 @@ void __osTimerServicesInit(void); void __osTimerInterrupt(void); void __osSetTimerIntr(OSTime tim); OSTime __osInsertTimer(OSTimer* t); -// void __osVoiceContRead36(void); s32 __osSpDeviceBusy(void); s32 __osSiDeviceBusy(void); void guMtxIdent(Mtx* mtx); @@ -291,12 +284,9 @@ OSTime osGetTime(void); void guRotateF(float m[4][4], f32 a, f32 x, f32 y, f32 z); void guRotate(Mtx* m, f32 a, f32 x, f32 y, f32 z); void __osSetGlobalIntMask(u32 mask); -s32 osVoiceInit(OSMesgQueue* mq, OSVoiceHandle* handle, s32 channel); s32 __osContChannelReset(OSMesgQueue* mq, s32 channel); -// void __osVoiceSetADConverter(void); s32 osAiSetFrequency(u32 frequency); s32 __osContRamRead(OSMesgQueue* ctrlrqueue, s32 channel, u16 addr, u8* buffer); -// void __osVoiceContWrite20(void); u8 __osContAddressCrc(u16 addr); u8 __osContDataCrc(u8* data); OSThread* __osGetActiveQueue(void); @@ -321,12 +311,10 @@ s32 osEPiReadIo(OSPiHandle* handle, uintptr_t devAddr, u32* data); void osViSetSpecialFeatures(u32 func); s16 coss(u16 x); void osSetTime(OSTime ticks); -// void osVoiceStopReadData(void); void osViSetEvent(OSMesgQueue* mq, OSMesg m, u32 retraceCount); s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern); // void __osPfsRequestData(void); // void __osPfsGetInitData(void); -s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status); OSPiHandle* osCartRomInit(void); // void guS2DInitBg(void); s32 __osPfsSelectBank(OSPfs* pfs, u8 bank); @@ -360,7 +348,6 @@ void osCreateViManager(OSPri pri); __OSViContext* __osViGetCurrentContext(void); void osWritebackDCacheAll(void); OSThread* __osGetCurrFaultedThread(void); -// void osVoiceMaskDictionary(void); void guMtxF2L(float mf[4][4], Mtx* m); void osStartThread(OSThread* t); void osViSetYScale(f32 value); @@ -373,12 +360,8 @@ double __ll_to_d(long long s); float __ll_to_f(long long s); double __ull_to_d(unsigned long long u); float __ull_to_f(unsigned long long u); -// void osVoiceCheckWord(void); -// void osVoiceControlGain(void); -// void osVoiceStartReadData(void); u32* osViGetCurrentFramebuffer(void); s32 __osSpSetPc(void* pc); -// void __osVoiceContWrite4(void); void __osGetHWIntrRoutine(s32 idx, OSMesgQueue** outQueue, OSMesg* outMsg); void __osSetHWIntrRoutine(s32 idx, OSMesgQueue* queue, OSMesg msg); u32 __osGetWatchLo(void); diff --git a/include/io/controller.h b/include/io/controller.h index b588b41984..d29c11f1f9 100644 --- a/include/io/controller.h +++ b/include/io/controller.h @@ -4,6 +4,8 @@ #include "PR/ultratypes.h" #include "PR/pfs.h" +#define CHNL_ERR(format) (((format).rxsize & CHNL_ERR_MASK) >> 4) + #define SIAccessQueueSize 2 #define BLOCKSIZE 32 #define MAXCONTROLLERS 4 diff --git a/include/os.h b/include/os.h index 6e34bd4283..47fed80a09 100644 --- a/include/os.h +++ b/include/os.h @@ -142,11 +142,4 @@ typedef struct { /* 0xC */ u32* text_end; } OSProf; // size = 0x10 -typedef struct { - /* 0x0 */ OSMesgQueue* mq; - /* 0x4 */ s32 port; /* Controller port */ - /* 0x8 */ s32 mode; - /* 0xC */ u8 status; -} OSVoiceHandle; // size = 0x10 - #endif diff --git a/include/ultra64.h b/include/ultra64.h index ad2bc24633..f7baade42a 100644 --- a/include/ultra64.h +++ b/include/ultra64.h @@ -6,6 +6,7 @@ #include "unk.h" +#include "ultra64/controller_voice.h" #include "ultra64/hardware.h" #include "ultra64/message.h" #include "ultra64/sptask.h" diff --git a/include/ultra64/controller_voice.h b/include/ultra64/controller_voice.h new file mode 100644 index 0000000000..a5480d8776 --- /dev/null +++ b/include/ultra64/controller_voice.h @@ -0,0 +1,71 @@ +#ifndef CONTROLLER_VOICE_H +#define CONTROLLER_VOICE_H + +#include "PR/ultratypes.h" +#include "ultra64/os_voice.h" +#include "ultra64/message.h" +#include "libc/stddef.h" + +typedef struct { + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; + /* 0x4 */ u8 addrh; + /* 0x5 */ u8 addrl; + /* 0x6 */ u8 data[2]; + /* 0x8 */ u8 datacrc; +} __OSVoiceRead2Format; // size = 0x9 + +typedef struct { + /* 0x00 */ u8 dummy; + /* 0x01 */ u8 txsize; + /* 0x02 */ u8 rxsize; + /* 0x03 */ u8 cmd; + /* 0x04 */ u8 addrh; + /* 0x05 */ u8 addrl; + /* 0x06 */ u8 data[36]; + /* 0x2A */ u8 datacrc; +} __OSVoiceRead36Format; // size = 0x2B + +typedef struct { + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; + /* 0x4 */ u8 addrh; + /* 0x5 */ u8 addrl; + /* 0x6 */ u8 data[4]; + /* 0xA */ u8 datacrc; +} __OSVoiceWrite4Format; // size = 0xB + +typedef struct { + /* 0x00 */ u8 dummy; + /* 0x01 */ u8 txsize; + /* 0x02 */ u8 rxsize; + /* 0x03 */ u8 cmd; + /* 0x04 */ u8 addrh; + /* 0x05 */ u8 addrl; + /* 0x06 */ u8 data[20]; + /* 0x1A */ u8 datacrc; +} __OSVoiceWrite20Format; // size = 0x1B + +typedef struct { + /* 0x0 */ u8 txsize; + /* 0x1 */ u8 rxsize; + /* 0x2 */ u8 cmd; + /* 0x3 */ u8 data; + /* 0x4 */ u8 scrc; + /* 0x5 */ u8 datacrc; +} __OSVoiceSWriteFormat; // size = 0x6 + +s32 __osVoiceContRead2(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[2]); +s32 __osVoiceContRead36(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[36]); +s32 __osVoiceContWrite4(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[4]); +s32 __osVoiceContWrite20(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[20]); +s32 __osVoiceCheckResult(OSVoiceHandle* hd, u8* status); +s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 channel, u8* status); +s32 __osVoiceSetADConverter(OSMesgQueue* mq, s32 channel, u8 data); +u8 __osVoiceContDataCrc(u8* data, size_t numBytes); + +#endif diff --git a/include/ultra64/os_voice.h b/include/ultra64/os_voice.h new file mode 100644 index 0000000000..8452ed45c2 --- /dev/null +++ b/include/ultra64/os_voice.h @@ -0,0 +1,42 @@ +#ifndef OS_VOICE_H +#define OS_VOICE_H + +#include "PR/ultratypes.h" +#include "ultra64/message.h" + +typedef enum OsVoiceHandleMode { + /* 0 */ VOICE_HANDLE_MODE_0, + /* 1 */ VOICE_HANDLE_MODE_1, + /* 2 */ VOICE_HANDLE_MODE_2, + /* 3 */ VOICE_HANDLE_MODE_3, + /* 4 */ VOICE_HANDLE_MODE_4 +} OsVoiceHandleMode; + +typedef struct { + /* 0x0 */ OSMesgQueue* mq; + /* 0x4 */ s32 channel; // Controller port + /* 0x8 */ OsVoiceHandleMode mode; + /* 0xC */ u8 status; +} OSVoiceHandle; // size = 0x10 + +typedef struct { + /* 0x00 */ u16 warning; // Warning + /* 0x02 */ u16 answerNum; // Candidate number (0~5) + /* 0x04 */ u16 voiceLevel; // Voice input level + /* 0x06 */ u16 voiceRelLevel; // Relative voice level "voice_sn" + /* 0x08 */ u16 voiceTime; // Voice input time + /* 0x0A */ u16 answer[5]; // Candidate word number + /* 0x14 */ u16 distance[5]; // Distance value +} OSVoiceData; // size = 0x20 + +s32 osVoiceInit(OSMesgQueue* mq, OSVoiceHandle* hd, s32 channel); +s32 osVoiceSetWord(OSVoiceHandle* hd, u8* word); +s32 osVoiceCheckWord(u8* word); +s32 osVoiceStartReadData(OSVoiceHandle* hd); +s32 osVoiceStopReadData(OSVoiceHandle* hd); +s32 osVoiceGetReadData(OSVoiceHandle* hd, OSVoiceData* result); +s32 osVoiceClearDictionary(OSVoiceHandle* hd, u8 numWords); +s32 osVoiceMaskDictionary(OSVoiceHandle* hd, u8* maskPattern, s32 size); +s32 osVoiceControlGain(OSVoiceHandle* hd, s32 analog, s32 digital); + +#endif diff --git a/include/variables.h b/include/variables.h index 108fa58338..7cdf40e31e 100644 --- a/include/variables.h +++ b/include/variables.h @@ -72,11 +72,6 @@ extern UNK_TYPE4 D_80097F10; extern char spaces[]; extern char zeroes[]; extern OSTimer* __osTimerList; -// extern UNK_TYPE4 D_80097F80; -extern float D_80097F90; -// extern UNK_TYPE1 D_80097FA0; -// extern UNK_TYPE1 D_80097FA4; -// extern UNK_TYPE1 D_80097FA5; extern s32 __osPfsLastChannel; extern OSViMode osViModeNtscLan1; extern OSViMode osViModeMpalLan1; @@ -89,7 +84,7 @@ extern OSViMode osViModeFpalLan1; // extern u8 udigs[]; // extern OSDevMgr __osViDevMgr; extern u32 __additional_scanline; -// extern UNK_TYPE1 D_80098180; + extern char bootThreadName[]; extern char idleThreadName[]; extern char irqmgrThreadName[]; @@ -308,8 +303,6 @@ extern OSTask tmp_task; extern OSMesg siAccessBuf[1]; extern OSMesgQueue __osSiAccessQueue; -extern UNK_TYPE1 D_8009CF60; -// extern UNK_TYPE4 D_8009CF70; extern OSThread __osThreadSave; extern OSPiHandle D_8009D130; extern OSPiHandle D_8009D1A8; @@ -2516,7 +2509,6 @@ extern s32 D_801FD120; // extern UNK_TYPE1 D_801FD598; // extern UNK_TYPE1 D_801FD5A0; // extern UNK_TYPE1 D_801FD5A4; -extern OSVoiceHandle gVoiceHandle; // extern UNK_TYPE1 D_801FD5C4; // extern UNK_TYPE1 D_801FD5C8; // extern UNK_TYPE1 D_801FD5E8; diff --git a/include/z64audio.h b/include/z64audio.h index 9b077cf1aa..c4943c09ab 100644 --- a/include/z64audio.h +++ b/include/z64audio.h @@ -1,7 +1,10 @@ #ifndef Z64AUDIO_H #define Z64AUDIO_H +#include "PR/ultratypes.h" +#include "ultra64/os_voice.h" #include "audiothread_cmd.h" +#include "libc/stddef.h" #define NO_LAYER ((SequenceLayer*)(-1)) @@ -1279,4 +1282,6 @@ typedef u32 (*AudioCustomSeqFunction)(s8 value, SequenceChannel* channel); typedef s32 (*AudioCustomReverbFunction)(Sample*, s32, s8, s32); typedef Acmd* (*AudioCustomSynthFunction)(Acmd*, s32, s32); +extern OSVoiceHandle gVoiceHandle; + #endif diff --git a/spec b/spec index e427e6866f..b1468144ef 100644 --- a/spec +++ b/spec @@ -77,7 +77,6 @@ beginseg include "build/src/libultra/os/createthread.o" include "build/src/libultra/io/contreaddata.o" include "build/src/libultra/voice/voicegetreaddata.o" - include "build/data/boot/voicegetreaddata.bss.o" include "build/src/libultra/os/virtualtophysical.o" include "build/asm/boot/getsr.text.o" include "build/asm/boot/setsr.text.o" @@ -155,7 +154,6 @@ beginseg include "build/src/libultra/gu/rotate.o" include "build/src/libultra/os/setglobalintmask.o" include "build/src/libultra/voice/voiceinit.o" - include "build/data/boot/voiceinit.data.o" include "build/src/libultra/io/contchannelreset.o" include "build/src/libultra/voice/voicesetadconverter.o" include "build/src/libultra/io/aisetfreq.o" diff --git a/src/code/graph.c b/src/code/graph.c index 2e104234e2..eca40bbaf1 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "buffers.h" #include "system_malloc.h" diff --git a/src/code/z_message.c b/src/code/z_message.c index 38f44d9ec7..03fadc9c92 100644 --- a/src/code/z_message.c +++ b/src/code/z_message.c @@ -244,6 +244,7 @@ void Message_LoadChar(PlayState* play, u16 codePointIndex, s32* offset, f32* arg *arg3 = temp2; } +// TODO: SJIS support // Message_LoadRupees JPN ? void func_8014CCB4(PlayState* play, s16* decodedBufPos, s32* offset, f32* arg3) { MessageContext* msgCtx = &play->msgCtx; @@ -259,7 +260,7 @@ void func_8014CCB4(PlayState* play, s16* decodedBufPos, s32* offset, f32* arg3) k += FONT_CHAR_TEX_SIZE; msgCtx->decodedBuffer.wchar[t] = 0x8373; t += 1; - Font_LoadChar(play, 0x815C, k); // Ox815C = ― in JISX0213 + Font_LoadChar(play, 0x815C, k); // 0x815C = ― in JISX0213 k += FONT_CHAR_TEX_SIZE; msgCtx->decodedBuffer.wchar[t] = 0x815C; diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c index 061c01b0aa..27bd0b8ed5 100644 --- a/src/libultra/io/contreaddata.c +++ b/src/libultra/io/contreaddata.c @@ -43,11 +43,11 @@ void __osPackReadData() { int i; ptr = (u8*)__osContPifRam.ramarray; - for (i = 0; i < 0xF; i++) { + for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray); i++) { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.status = 1; + __osContPifRam.status = CONT_CMD_READ_BUTTON; readformat.dummy = 255; readformat.txsize = 1; readformat.rxsize = 4; diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c index 2451832802..19be9281aa 100644 --- a/src/libultra/io/controller.c +++ b/src/libultra/io/controller.c @@ -74,11 +74,11 @@ void __osPackRequestData(u8 poll) { __OSContRequestHeader requestHeader; s32 i; - for (i = 0; i < 0xF; i++) { + for (i = 0; i < ARRAY_COUNT(__osContPifRam.ramarray); i++) { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.status = 1; + __osContPifRam.status = CONT_CMD_READ_BUTTON; ptr = (u8*)__osContPifRam.ramarray; requestHeader.align = 255; requestHeader.txsize = 1; diff --git a/src/libultra/voice/voicecheckresult.c b/src/libultra/voice/voicecheckresult.c index 44fb69be57..7d1e5c0a54 100644 --- a/src/libultra/voice/voicecheckresult.c +++ b/src/libultra/voice/voicecheckresult.c @@ -1,3 +1,29 @@ -#include "global.h" +/** + * File: voicecheckresult.c + */ +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecheckresult/__osVoiceCheckResult.s") +s32 __osVoiceCheckResult(OSVoiceHandle* hd, u8* status) { + s32 errorCode = __osVoiceGetStatus(hd->mq, hd->channel, status); + u8 data[2]; + + if (errorCode == 0) { + if (*status & 1) { + errorCode = CONT_ERR_VOICE_NO_RESPONSE; + } else { + errorCode = __osVoiceContRead2(hd->mq, hd->channel, 0, data); + if (errorCode == 0) { + hd->status = data[0] & 7; + + if (data[0] & 0x40) { + errorCode = CONT_ERR_VOICE_NO_RESPONSE; + } else { + errorCode = data[1] << 8; + } + } + } + } + return errorCode; +} diff --git a/src/libultra/voice/voicecheckword.c b/src/libultra/voice/voicecheckword.c index 8b5ac0dfb2..1a2695b513 100644 --- a/src/libultra/voice/voicecheckword.c +++ b/src/libultra/voice/voicecheckword.c @@ -1,3 +1,107 @@ -#include "global.h" +/** + * File: voicecheckwork.c + * + * Checks whether or not a word can be registered in the dictionary + */ +#include "io/controller.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecheckword/osVoiceCheckWord.s") +// TODO: SJIS support +s32 osVoiceCheckWord(u8* word) { + s32 i; + s32 errorCode = 0; + u16 curSyllable; + u16 prevSyllable = 0; + + for (i = 0; word[i] != 0; i += 2) { + curSyllable = (word[i] << 8) + word[i + 1]; + if (((curSyllable != 0x815B) && (curSyllable < 0x829F)) || + ((curSyllable >= 0x82F2) && (curSyllable < 0x8340)) || (curSyllable == 0x837F) || (curSyllable >= 0x8397)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if ((i == 0) && ((curSyllable == 0x815B) || (curSyllable == 0x82F1) || (curSyllable == 0x82C1) || + (curSyllable == 0x82EC) || (curSyllable == 0x8393) || (curSyllable == 0x8362) || + (curSyllable == 0x838E) || (curSyllable == 0x8395) || (curSyllable == 0x8396))) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x829F) || (curSyllable == 0x8340)) && (prevSyllable != 0x82D3) && + (prevSyllable != 0x8374) && (prevSyllable != 0x8394)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x82A1) || (curSyllable == 0x8342)) && (prevSyllable != 0x82A4) && + (prevSyllable != 0x82C4) && (prevSyllable != 0x82C5) && (prevSyllable != 0x82D3) && + (prevSyllable != 0x8345) && (prevSyllable != 0x8365) && (prevSyllable != 0x8366) && + (prevSyllable != 0x8374) && (prevSyllable != 0x8394)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x82A3) || (curSyllable == 0x8344)) && (prevSyllable != 0x82C6) && + (prevSyllable != 0x82C7) && (prevSyllable != 0x82D3) && (prevSyllable != 0x8367) && + (prevSyllable != 0x8368) && (prevSyllable != 0x8374) && (prevSyllable != 0x8394)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x82A5) || (curSyllable == 0x8346)) && (prevSyllable != 0x82A4) && + (prevSyllable != 0x82B5) && (prevSyllable != 0x82B6) && (prevSyllable != 0x82BF) && + (prevSyllable != 0x82C0) && (prevSyllable != 0x82C2) && (prevSyllable != 0x82D3) && + (prevSyllable != 0x8345) && (prevSyllable != 0x8356) && (prevSyllable != 0x8357) && + (prevSyllable != 0x8360) && (prevSyllable != 0x8361) && (prevSyllable != 0x8363) && + (prevSyllable != 0x8374) && (prevSyllable != 0x8394)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x82A7) || (curSyllable == 0x8348)) && (prevSyllable != 0x82A4) && + (prevSyllable != 0x82D3) && (prevSyllable != 0x8345) && (prevSyllable != 0x8374) && + (prevSyllable != 0x8394)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x82E1) || (curSyllable == 0x82E3) || (curSyllable == 0x82E5) || + (curSyllable == 0x8383) || (curSyllable == 0x8385) || (curSyllable == 0x8387)) && + (prevSyllable != 0x82AB) && (prevSyllable != 0x82B5) && (prevSyllable != 0x82BF) && + (prevSyllable != 0x82C9) && (prevSyllable != 0x82D0) && (prevSyllable != 0x82DD) && + (prevSyllable != 0x82E8) && (prevSyllable != 0x82AC) && (prevSyllable != 0x82B6) && + (prevSyllable != 0x82C0) && (prevSyllable != 0x82D1) && (prevSyllable != 0x82D2) && + (prevSyllable != 0x834C) && (prevSyllable != 0x8356) && (prevSyllable != 0x8360) && + (prevSyllable != 0x836A) && (prevSyllable != 0x8371) && (prevSyllable != 0x837E) && + (prevSyllable != 0x838A) && (prevSyllable != 0x834D) && (prevSyllable != 0x8357) && + (prevSyllable != 0x8361) && (prevSyllable != 0x8372) && (prevSyllable != 0x8373) && + (prevSyllable != 0x8394)) { + errorCode = CONT_ERR_VOICE_WORD; + } else if ((curSyllable == 0x815B) && ((prevSyllable == 0x82F1) || (prevSyllable == 0x82C1) || + (prevSyllable == 0x8393) || (prevSyllable == 0x8362))) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((curSyllable == 0x82F1) || (curSyllable == 0x8393)) && + ((prevSyllable == 0x82F1) || (prevSyllable == 0x8393))) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (((prevSyllable == 0x82C1) || (prevSyllable == 0x8362)) && + ((curSyllable == 0x815B) || (curSyllable == 0x82A0) || (curSyllable == 0x82A2) || + (curSyllable == 0x82A4) || (curSyllable == 0x82A6) || (curSyllable == 0x82A8) || + (curSyllable == 0x82C8) || (curSyllable == 0x82C9) || (curSyllable == 0x82CA) || + (curSyllable == 0x82CB) || (curSyllable == 0x82CC) || (curSyllable == 0x82DC) || + (curSyllable == 0x82DD) || (curSyllable == 0x82DE) || (curSyllable == 0x82DF) || + (curSyllable == 0x82E0) || (curSyllable == 0x82E2) || (curSyllable == 0x82E4) || + (curSyllable == 0x82E6) || (curSyllable == 0x82E7) || (curSyllable == 0x82E8) || + (curSyllable == 0x82E9) || (curSyllable == 0x82EA) || (curSyllable == 0x82EB) || + (curSyllable == 0x82ED) || (curSyllable == 0x82EE) || (curSyllable == 0x82EF) || + (curSyllable == 0x82F0) || (curSyllable == 0x82F1) || (curSyllable == 0x829F) || + (curSyllable == 0x82A1) || (curSyllable == 0x82A3) || (curSyllable == 0x82A5) || + (curSyllable == 0x82A7) || (curSyllable == 0x82E1) || (curSyllable == 0x82E3) || + (curSyllable == 0x82E5) || (curSyllable == 0x82C1) || (curSyllable == 0x82EC) || + (curSyllable == 0x8341) || (curSyllable == 0x8343) || (curSyllable == 0x8345) || + (curSyllable == 0x8347) || (curSyllable == 0x8349) || (curSyllable == 0x8369) || + (curSyllable == 0x836A) || (curSyllable == 0x836B) || (curSyllable == 0x836C) || + (curSyllable == 0x836D) || (curSyllable == 0x837D) || (curSyllable == 0x837E) || + (curSyllable == 0x8380) || (curSyllable == 0x8381) || (curSyllable == 0x8382) || + (curSyllable == 0x8384) || (curSyllable == 0x8386) || (curSyllable == 0x8388) || + (curSyllable == 0x8389) || (curSyllable == 0x838A) || (curSyllable == 0x838B) || + (curSyllable == 0x838C) || (curSyllable == 0x838D) || (curSyllable == 0x838F) || + (curSyllable == 0x8390) || (curSyllable == 0x8391) || (curSyllable == 0x8392) || + (curSyllable == 0x8393) || (curSyllable == 0x8340) || (curSyllable == 0x8342) || + (curSyllable == 0x8344) || (curSyllable == 0x8346) || (curSyllable == 0x8348) || + (curSyllable == 0x8383) || (curSyllable == 0x8385) || (curSyllable == 0x8387) || + (curSyllable == 0x8362) || (curSyllable == 0x838E))) { + errorCode = CONT_ERR_VOICE_WORD; + } + + if (errorCode != 0) { + return errorCode; + } + + prevSyllable = curSyllable; + } + + if ((curSyllable == 0x82C1) || (curSyllable == 0x8362)) { + errorCode = CONT_ERR_VOICE_WORD; + } + + return errorCode; +} diff --git a/src/libultra/voice/voicecleardictionary.c b/src/libultra/voice/voicecleardictionary.c index 29766bb2a6..e474bc2fd5 100644 --- a/src/libultra/voice/voicecleardictionary.c +++ b/src/libultra/voice/voicecleardictionary.c @@ -1,3 +1,51 @@ -#include "global.h" +/** + * File: voicecleardictionary.c + * + * Initializes Voice Recognition System word registration dictionary. + * + * The dictionary is initialized so that the specified "numWords" can be + * registered in the dictionary. 1-255 words can be registered in the dictionary. + * + * Words cannot be registered with the osVoiceSetWord before the dictionary + * is initialized with the osVoiceClearDictionary function + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecleardictionary/osVoiceClearDictionary.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" + +s32 osVoiceClearDictionary(OSVoiceHandle* hd, u8 numWords) { + s32 errorCode; + u8 status; + u8 data[4]; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + /** + * data[0] = 2 + * data[1] = 0 + * data[2] = numWords + * data[3] = 0 + */ + *(u32*)data = 0x2000000; + data[2] = numWords; + + errorCode = __osVoiceContWrite4(hd->mq, hd->channel, 0, data); + if (errorCode != 0) { + return errorCode; + } + + errorCode = __osVoiceCheckResult(hd, &status); + if (errorCode & 0xFF00) { + errorCode = CONT_ERR_INVALID; + } + + return errorCode; +} diff --git a/src/libultra/voice/voicecontread2.c b/src/libultra/voice/voicecontread2.c index 38350ee5f2..1477e570b6 100644 --- a/src/libultra/voice/voicecontread2.c +++ b/src/libultra/voice/voicecontread2.c @@ -1,3 +1,74 @@ -#include "global.h" +/** + * File: voicecontread2.c + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontread2/__osVoiceContRead2.s") +#include "ultra64/controller_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "variables.h" + +#define READ2FORMAT(ptr) ((__OSVoiceRead2Format*)(ptr)) + +s32 __osVoiceContRead2(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[2]) { + s32 errorCode; + u8 status; + u8* ptr; + s32 retryCount = 2; + s32 i; + + __osSiGetAccess(); + + do { + ptr = (u8*)&__osPfsPifRam.ramarray; + + if ((__osContLastPoll != CONT_CMD_READ2_VOICE) || (channel != __osPfsLastChannel)) { + __osContLastPoll = CONT_CMD_READ2_VOICE; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++, *ptr++ = 0) {} + + __osPfsPifRam.status = CONT_CMD_EXE; + + READ2FORMAT(ptr)->dummy = CONT_CMD_NOP; + READ2FORMAT(ptr)->txsize = CONT_CMD_READ2_VOICE_TX; + READ2FORMAT(ptr)->rxsize = CONT_CMD_READ2_VOICE_RX; + READ2FORMAT(ptr)->cmd = CONT_CMD_READ2_VOICE; + READ2FORMAT(ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSVoiceRead2Format)] = CONT_CMD_END; + } else { + ptr += channel; + } + + READ2FORMAT(ptr)->addrh = address >> 3; + READ2FORMAT(ptr)->addrl = (address << 5) | __osContAddressCrc(address); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + errorCode = CHNL_ERR(*READ2FORMAT(ptr)); + + if (errorCode == 0) { + if (__osVoiceContDataCrc(READ2FORMAT(ptr)->data, ARRAY_COUNT(READ2FORMAT(ptr)->data)) != + READ2FORMAT(ptr)->datacrc) { + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + break; + } + + errorCode = CONT_ERR_CONTRFAIL; + } else { + bcopy(READ2FORMAT(ptr)->data, dst, ARRAY_COUNT(READ2FORMAT(ptr)->data)); + } + } else { + errorCode = CONT_ERR_NO_CONTROLLER; + } + + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); + + __osSiRelAccess(); + + return errorCode; +} diff --git a/src/libultra/voice/voicecontread36.c b/src/libultra/voice/voicecontread36.c index 38f3fe2f0a..83d0fdf2ea 100644 --- a/src/libultra/voice/voicecontread36.c +++ b/src/libultra/voice/voicecontread36.c @@ -1,3 +1,74 @@ -#include "global.h" +/** + * File: voicecontread36.c + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontread36/__osVoiceContRead36.s") +#include "ultra64/controller_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "variables.h" + +#define READ36FORMAT(ptr) ((__OSVoiceRead36Format*)(ptr)) + +s32 __osVoiceContRead36(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[36]) { + s32 errorCode; + u8 status; + u8* ptr; + s32 retryCount = 2; + s32 i; + + __osSiGetAccess(); + + do { + ptr = (u8*)&__osPfsPifRam.ramarray; + + if ((__osContLastPoll != CONT_CMD_READ36_VOICE) || (channel != __osPfsLastChannel)) { + __osContLastPoll = CONT_CMD_READ36_VOICE; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++, *ptr++ = 0) {} + + __osPfsPifRam.status = CONT_CMD_EXE; + + READ36FORMAT(ptr)->dummy = CONT_CMD_NOP; + READ36FORMAT(ptr)->txsize = CONT_CMD_READ36_VOICE_TX; + READ36FORMAT(ptr)->rxsize = CONT_CMD_READ36_VOICE_RX; + READ36FORMAT(ptr)->cmd = CONT_CMD_READ36_VOICE; + READ36FORMAT(ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSVoiceRead36Format)] = CONT_CMD_END; + } else { + ptr += channel; + } + + READ36FORMAT(ptr)->addrh = address >> 3; + READ36FORMAT(ptr)->addrl = (address << 5) | __osContAddressCrc(address); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + errorCode = CHNL_ERR(*READ36FORMAT(ptr)); + + if (errorCode == 0) { + if (__osVoiceContDataCrc(READ36FORMAT(ptr)->data, ARRAY_COUNT(READ36FORMAT(ptr)->data)) != + READ36FORMAT(ptr)->datacrc) { + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + break; + } + + errorCode = CONT_ERR_CONTRFAIL; + } else { + bcopy(READ36FORMAT(ptr)->data, dst, ARRAY_COUNT(READ36FORMAT(ptr)->data)); + } + } else { + errorCode = CONT_ERR_NO_CONTROLLER; + } + + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); + + __osSiRelAccess(); + + return errorCode; +} diff --git a/src/libultra/voice/voicecontrolgain.c b/src/libultra/voice/voicecontrolgain.c index d7ec8ef69b..61cccde708 100644 --- a/src/libultra/voice/voicecontrolgain.c +++ b/src/libultra/voice/voicecontrolgain.c @@ -1,5 +1,41 @@ -#include "global.h" +/** + * File: voicecontrolgain.c + * + * Adjusts the input gain of the Voice Recognition System + */ -u8 D_80098180[] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0 }; +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" +#include "macros.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontrolgain/osVoiceControlGain.s") +u8 sDigitalTable[] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0 }; + +s32 osVoiceControlGain(OSVoiceHandle* hd, s32 analog, s32 digital) { + s32 errorCode; + u8 cmd; + + if (analog == 0) { + cmd = 0x18; + } else { + cmd = 0x98; + } + + errorCode = __osVoiceSetADConverter(hd->mq, hd->channel, cmd); + if (errorCode != 0) { + return errorCode; + } + + if ((digital < ARRAY_COUNT(sDigitalTable)) && (digital >= 0)) { + cmd = sDigitalTable[digital] + 2; + } else { + return CONT_ERR_INVALID; + } + + errorCode = __osVoiceSetADConverter(hd->mq, hd->channel, cmd); + if (errorCode != 0) { + return errorCode; + } + + return errorCode; +} diff --git a/src/libultra/voice/voicecontwrite20.c b/src/libultra/voice/voicecontwrite20.c index 5ca3560edd..cc3af385e0 100644 --- a/src/libultra/voice/voicecontwrite20.c +++ b/src/libultra/voice/voicecontwrite20.c @@ -1,3 +1,75 @@ -#include "global.h" +/** + * File: voicecontwrite20.c + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontwrite20/__osVoiceContWrite20.s") +#include "ultra64/controller_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "variables.h" + +#define WRITE20FORMAT(ptr) ((__OSVoiceWrite20Format*)(ptr)) + +s32 __osVoiceContWrite20(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[20]) { + s32 errorCode; + u8 status; + u8* ptr; + s32 retryCount = 2; + s32 i; + u8 crc; + + __osSiGetAccess(); + + do { + ptr = (u8*)&__osPfsPifRam.ramarray; + + if ((__osContLastPoll != CONT_CMD_WRITE20_VOICE) || (channel != __osPfsLastChannel)) { + __osContLastPoll = CONT_CMD_WRITE20_VOICE; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++, *ptr++ = 0) {} + + __osPfsPifRam.status = CONT_CMD_EXE; + + WRITE20FORMAT(ptr)->dummy = CONT_CMD_NOP; + WRITE20FORMAT(ptr)->txsize = CONT_CMD_WRITE20_VOICE_TX; + WRITE20FORMAT(ptr)->rxsize = CONT_CMD_WRITE20_VOICE_RX; + WRITE20FORMAT(ptr)->cmd = CONT_CMD_WRITE20_VOICE; + WRITE20FORMAT(ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSVoiceWrite20Format)] = CONT_CMD_END; + } else { + ptr += channel; + } + + WRITE20FORMAT(ptr)->addrh = address >> 3; + WRITE20FORMAT(ptr)->addrl = (address << 5) | __osContAddressCrc(address); + + bcopy(dst, WRITE20FORMAT(ptr)->data, ARRAY_COUNT(WRITE20FORMAT(ptr)->data)); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + crc = __osVoiceContDataCrc(dst, ARRAY_COUNT(WRITE20FORMAT(ptr)->data)); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + errorCode = CHNL_ERR(*WRITE20FORMAT(ptr)); + + if (errorCode == 0) { + if (crc != WRITE20FORMAT(ptr)->datacrc) { + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + break; + } + + errorCode = CONT_ERR_CONTRFAIL; + } + } else { + errorCode = CONT_ERR_NO_CONTROLLER; + } + + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); + + __osSiRelAccess(); + + return errorCode; +} diff --git a/src/libultra/voice/voicecontwrite4.c b/src/libultra/voice/voicecontwrite4.c index c28e2d7624..06239219a6 100644 --- a/src/libultra/voice/voicecontwrite4.c +++ b/src/libultra/voice/voicecontwrite4.c @@ -1,3 +1,75 @@ -#include "global.h" +/** + * File: voicecontwrite4.c + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontwrite4/__osVoiceContWrite4.s") +#include "ultra64/controller_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "variables.h" + +#define WRITE4FORMAT(ptr) ((__OSVoiceWrite4Format*)(ptr)) + +s32 __osVoiceContWrite4(OSMesgQueue* mq, s32 channel, u16 address, u8 dst[4]) { + s32 errorCode; + u8 status; + u8* ptr; + s32 retryCount = 2; + s32 i; + u8 crc; + + __osSiGetAccess(); + + do { + ptr = (u8*)&__osPfsPifRam.ramarray; + + if ((__osContLastPoll != CONT_CMD_WRITE4_VOICE) || (channel != __osPfsLastChannel)) { + __osContLastPoll = CONT_CMD_WRITE4_VOICE; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++, *ptr++ = 0) {} + + __osPfsPifRam.status = CONT_CMD_EXE; + + WRITE4FORMAT(ptr)->dummy = CONT_CMD_NOP; + WRITE4FORMAT(ptr)->txsize = CONT_CMD_WRITE4_VOICE_TX; + WRITE4FORMAT(ptr)->rxsize = CONT_CMD_WRITE4_VOICE_RX; + WRITE4FORMAT(ptr)->cmd = CONT_CMD_WRITE4_VOICE; + WRITE4FORMAT(ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSVoiceWrite4Format)] = CONT_CMD_END; + } else { + ptr += channel; + } + + WRITE4FORMAT(ptr)->addrh = address >> 3; + WRITE4FORMAT(ptr)->addrl = (address << 5) | __osContAddressCrc(address); + + bcopy(dst, WRITE4FORMAT(ptr)->data, ARRAY_COUNT(WRITE4FORMAT(ptr)->data)); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + crc = __osVoiceContDataCrc(dst, ARRAY_COUNT(WRITE4FORMAT(ptr)->data)); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + errorCode = CHNL_ERR(*WRITE4FORMAT(ptr)); + + if (errorCode == 0) { + if (crc != WRITE4FORMAT(ptr)->datacrc) { + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + break; + } + + errorCode = CONT_ERR_CONTRFAIL; + } + } else { + errorCode = CONT_ERR_NO_CONTROLLER; + } + + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); + + __osSiRelAccess(); + + return errorCode; +} diff --git a/src/libultra/voice/voicecrc.c b/src/libultra/voice/voicecrc.c index 35b7b8656f..36ffc4373a 100644 --- a/src/libultra/voice/voicecrc.c +++ b/src/libultra/voice/voicecrc.c @@ -4,7 +4,7 @@ * * For general information about CRC, see the crc.c file (that's a lot of c's!). */ -#include "global.h" +#include "libc/stddef.h" #define VOICE_CRC_LENGTH 8 #define VOICE_CRC_GENERATOR 0x85 diff --git a/src/libultra/voice/voicegetreaddata.c b/src/libultra/voice/voicegetreaddata.c index 5940a1f8b5..d271f71c70 100644 --- a/src/libultra/voice/voicegetreaddata.c +++ b/src/libultra/voice/voicegetreaddata.c @@ -1,3 +1,125 @@ -#include "global.h" +/** + * File: voicegetreaddata.c + * + * Gets voice recognition result from the Voice Recognition System + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicegetreaddata/osVoiceGetReadData.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" + +s32 osVoiceGetReadData(OSVoiceHandle* hd, OSVoiceData* result) { + static u8 sHandleStatus; + s32 errorCode; + s32 i; + u8 status; + u8 data[36]; + + switch (hd->mode) { + case VOICE_HANDLE_MODE_1: + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 1) { + return CONT_ERR_NOT_READY; + } + + errorCode = __osVoiceContRead2(hd->mq, hd->channel, 0, data); + if (errorCode != 0) { + return errorCode; + } + + sHandleStatus = data[0] & 7; + hd->status = sHandleStatus; + if ((sHandleStatus != 0) && (sHandleStatus != 7)) { + return CONT_ERR_NOT_READY; + } + // fallthrough + case VOICE_HANDLE_MODE_2: + hd->mode = VOICE_HANDLE_MODE_2; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + *(u32*)data = 0x600; + errorCode = __osVoiceContWrite4(hd->mq, hd->channel, 0, data); + if (errorCode != 0) { + return errorCode; + } + // fallthrough + case VOICE_HANDLE_MODE_3: + hd->mode = VOICE_HANDLE_MODE_3; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 1) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + errorCode = __osVoiceContRead36(hd->mq, hd->channel, 0, data); + if (errorCode != 0) { + return errorCode; + } + + result->warning = data[4] + (data[5] << 8); + result->answerNum = data[6]; + result->voiceLevel = data[8] + (data[9] << 8); + result->voiceRelLevel = data[10] + (data[11] << 8); + result->voiceTime = data[12] + (data[13] << 8); + + for (i = 0; i < 5; i++) { + result->answer[i] = data[14 + (i << 2)] + (data[15 + (i << 2)] << 8); + result->distance[i] = data[16 + (i << 2)] + (data[17 + (i << 2)] << 8); + } + + if (result->answer[0] == 0x7FFF) { + result->answerNum = 0; + } + + hd->status = data[34] & 7; + if ((sHandleStatus == 0) || (hd->status == 0)) { + break; + } + // fallthrough + case VOICE_HANDLE_MODE_4: + hd->mode = VOICE_HANDLE_MODE_4; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 1) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + errorCode = __osVoiceContRead2(hd->mq, hd->channel, 0, data); + if (errorCode != 0) { + return errorCode; + } + + hd->status = data[0] & 7; + if (data[0] & 7) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + break; + + default: + return CONT_ERR_INVALID; + } + + hd->mode = VOICE_HANDLE_MODE_0; + return errorCode; +} diff --git a/src/libultra/voice/voicegetstatus.c b/src/libultra/voice/voicegetstatus.c index 3840ec62b9..444ae62335 100644 --- a/src/libultra/voice/voicegetstatus.c +++ b/src/libultra/voice/voicegetstatus.c @@ -1,56 +1,62 @@ -#include "global.h" -#include "io/controller.h" +/** + * File: voicegetstatus.c + */ -s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status) { +#include "ultra64/controller_voice.h" +#include "io/controller.h" +#include "functions.h" + +s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 channel, u8* status) { __OSContRequestHeaderAligned header; - s32 ret = 0; + s32 errorCode = 0; s32 i; - u8* ptr = (u8*)&__osContPifRam; - s32 var = 2; + u8* ptr = (u8*)&__osContPifRam.ramarray; + s32 retryCount = 2; __osSiGetAccess(); do { - if (ret != CONT_ERR_CONTRFAIL) { + if (errorCode != CONT_ERR_CONTRFAIL) { __osContPifRam.status = CONT_CMD_READ_BUTTON; - for (i = 0; i < port; i++, *ptr++ = 0) {} + for (i = 0; i < channel; i++, *ptr++ = 0) {} - *ptr++ = 1; - *ptr++ = 3; + *ptr++ = CONT_CMD_REQUEST_STATUS_TX; + *ptr++ = CONT_CMD_REQUEST_STATUS_RX; *ptr = CONT_CMD_REQUEST_STATUS; ptr += 4; *ptr = CONT_CMD_END; __osContLastPoll = CONT_CMD_END; - ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam); + errorCode = __osSiRawStartDma(OS_WRITE, &__osContPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); } - ret = __osSiRawStartDma(OS_READ, &__osContPifRam); + errorCode = __osSiRawStartDma(OS_READ, &__osContPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); - ptr = (u8*)&__osContPifRam + port; + ptr = (u8*)&__osContPifRam.ramarray + channel; header = *((__OSContRequestHeaderAligned*)ptr); - ret = (u8)((header.rxsize & 0xC0) >> 4); + errorCode = (u8)CHNL_ERR(header); *status = header.status; - if (ret == 0) { + if (errorCode == 0) { if ((header.typeh == 0) && (header.typel == 1)) { if (header.status & 4) { - ret = CONT_ERR_CONTRFAIL; + errorCode = CONT_ERR_CONTRFAIL; } } else { - ret = CONT_ERR_DEVICE; + errorCode = CONT_ERR_DEVICE; } - } else if (ret & CONT_NO_RESPONSE_ERROR) { - ret = CONT_ERR_NO_CONTROLLER; + } else if (errorCode & CONT_NO_RESPONSE_ERROR) { + errorCode = CONT_ERR_NO_CONTROLLER; } else { - ret = CONT_ERR_CONTRFAIL; + errorCode = CONT_ERR_CONTRFAIL; } - } while ((ret == CONT_ERR_CONTRFAIL) && (var-- >= 0)); + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); __osSiRelAccess(); - return (ret); + + return errorCode; } diff --git a/src/libultra/voice/voiceinit.c b/src/libultra/voice/voiceinit.c index 920bc48183..2a777edaf6 100644 --- a/src/libultra/voice/voiceinit.c +++ b/src/libultra/voice/voiceinit.c @@ -1,3 +1,69 @@ -#include "global.h" +/** + * File: voiceinit.c + * + * Initializes Voice Recognition System control structure and hardware + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voiceinit/osVoiceInit.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "macros.h" + +static u8 sCmds[] = { + 0x1E, 0x6E, 0x08, 0x56, 0x03, +}; + +s32 osVoiceInit(OSMesgQueue* mq, OSVoiceHandle* hd, s32 channel) { + s32 errorCode; + s32 i; + u8 status = 0; + u8 data[4]; + + hd->channel = channel; + hd->mq = mq; + hd->mode = VOICE_HANDLE_MODE_0; + + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (__osContChannelReset(mq, channel) != 0) { + return CONT_ERR_CONTRFAIL; + } + + for (i = 0; i < ARRAY_COUNT(sCmds); i++) { + errorCode = __osVoiceSetADConverter(mq, channel, sCmds[i]); + if (errorCode != 0) { + return errorCode; + } + } + + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + return errorCode; + } + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + /** + * data[0] = 0 + * data[1] = 0 + * data[2] = 1 + * data[3] = 0 + */ + *(u32*)data = 0x100; + errorCode = __osVoiceContWrite4(mq, channel, 0, data); + if (errorCode != 0) { + return errorCode; + } + + errorCode = __osVoiceCheckResult(hd, &status); + if (errorCode & 0xFF00) { + errorCode = CONT_ERR_INVALID; + } + + return errorCode; +} diff --git a/src/libultra/voice/voicemaskdictionary.c b/src/libultra/voice/voicemaskdictionary.c index 3de841de36..a8f090329c 100644 --- a/src/libultra/voice/voicemaskdictionary.c +++ b/src/libultra/voice/voicemaskdictionary.c @@ -1,3 +1,57 @@ -#include "global.h" +/** + * File: voicemaskdictionary.c + * + * Mask words registered in the voice recognition system + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicemaskdictionary/osVoiceMaskDictionary.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "macros.h" + +s32 osVoiceMaskDictionary(OSVoiceHandle* hd, u8* maskPattern, s32 size) { + s32 errorCode; + s32 i; + s32 j; + u8 status; + u8 data[20]; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + if (size & 1) { + j = size + 1; + } else { + j = size; + } + + bzero(&data, ARRAY_COUNT(data)); + + data[ARRAY_COUNT(data) - 2 - j] = 4; + + for (i = 0; i < j; i += 2) { + data[i + ARRAY_COUNT(data) - j] = maskPattern[i]; + data[i + ARRAY_COUNT(data) - j + 1] = maskPattern[i + 1]; + } + + if (size & 1) { + data[ARRAY_COUNT(data) - 1] = 0; + } + + errorCode = __osVoiceContWrite20(hd->mq, hd->channel, 0, data); + if (errorCode == 0) { + errorCode = __osVoiceCheckResult(hd, &status); + if (errorCode & 0xFF00) { + errorCode = CONT_ERR_INVALID; + } + } + + return errorCode; +} diff --git a/src/libultra/voice/voicesetadconverter.c b/src/libultra/voice/voicesetadconverter.c index c1b8fa002c..2a6ebfbc7c 100644 --- a/src/libultra/voice/voicesetadconverter.c +++ b/src/libultra/voice/voicesetadconverter.c @@ -1,3 +1,70 @@ -#include "global.h" +/** + * File: voicesetadconverter.c + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicesetadconverter/__osVoiceSetADConverter.s") +#include "ultra64/controller_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "variables.h" + +#define SWRITEFORMAT(ptr) ((__OSVoiceSWriteFormat*)(ptr)) + +s32 __osVoiceSetADConverter(OSMesgQueue* mq, s32 channel, u8 data) { + s32 errorCode; + s32 i; + u8* ptr; + u8 status; + s32 retryCount = 2; + + __osSiGetAccess(); + + do { + ptr = (u8*)&__osPfsPifRam.ramarray; + + if ((__osContLastPoll != CONT_CMD_SWRITE_VOICE) || (channel != __osPfsLastChannel)) { + __osContLastPoll = CONT_CMD_SWRITE_VOICE; + __osPfsLastChannel = channel; + + for (i = 0; i < channel; i++, *ptr++ = 0) {} + + __osPfsPifRam.status = CONT_CMD_EXE; + + SWRITEFORMAT(ptr)->txsize = CONT_CMD_SWRITE_VOICE_TX; + SWRITEFORMAT(ptr)->rxsize = CONT_CMD_SWRITE_VOICE_RX; + SWRITEFORMAT(ptr)->cmd = CONT_CMD_SWRITE_VOICE; + SWRITEFORMAT(ptr)->datacrc = 0; + + ptr[sizeof(__OSVoiceSWriteFormat)] = CONT_CMD_END; + } else { + ptr += channel; + } + + SWRITEFORMAT(ptr)->data = data; + SWRITEFORMAT(ptr)->scrc = __osContAddressCrc(data << 3); + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + errorCode = CHNL_ERR(*SWRITEFORMAT(ptr)); + + if (errorCode == 0) { + if (SWRITEFORMAT(ptr)->datacrc & 1) { + errorCode = __osVoiceGetStatus(mq, channel, &status); + if (errorCode != 0) { + break; + } + + errorCode = CONT_ERR_CONTRFAIL; + } + } else { + errorCode = CONT_ERR_NO_CONTROLLER; + } + + } while ((errorCode == CONT_ERR_CONTRFAIL) && (retryCount-- >= 0)); + + __osSiRelAccess(); + + return errorCode; +} diff --git a/src/libultra/voice/voicesetword.c b/src/libultra/voice/voicesetword.c index e50f26874c..2dfe58b94f 100644 --- a/src/libultra/voice/voicesetword.c +++ b/src/libultra/voice/voicesetword.c @@ -1,3 +1,69 @@ -#include "global.h" +/** + * File: voicesetword.c + * + * Registers words to the Voice Recognition System dictionary + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicesetword/osVoiceSetWord.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" +#include "functions.h" +#include "macros.h" + +s32 osVoiceSetWord(OSVoiceHandle* hd, u8* word) { + s32 i; + s32 k; + s32 errorCode; + u8 status; + u8 data[40]; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + k = 0; + + while (word[k] != 0) { + k += 2; + } + + bzero(data, ARRAY_COUNT(data)); + + for (i = 0; i < k; i += 2) { + data[ARRAY_COUNT(data) - 1 - k + i] = word[i]; + data[ARRAY_COUNT(data) - 1 - k + i - 1] = word[i + 1]; + } + + data[ARRAY_COUNT(data) - 1 - i - 5] = 3; + + if (k >= 15) { + errorCode = __osVoiceContWrite20(hd->mq, hd->channel, 0, &data[0]); + if (errorCode != 0) { + return errorCode; + } + } + + errorCode = __osVoiceContWrite20(hd->mq, hd->channel, 0, &data[20]); + if (errorCode != 0) { + return errorCode; + } + + errorCode = __osVoiceCheckResult(hd, &status); + + if (errorCode != 0) { + if (errorCode & 0x100) { + errorCode = CONT_ERR_VOICE_MEMORY; + } else if (errorCode & 0x200) { + errorCode = CONT_ERR_VOICE_WORD; + } else if (errorCode & 0xFF00) { + errorCode = CONT_ERR_INVALID; + } + } + + return errorCode; +} diff --git a/src/libultra/voice/voicestartreaddata.c b/src/libultra/voice/voicestartreaddata.c index e7105a7d44..398d10a15c 100644 --- a/src/libultra/voice/voicestartreaddata.c +++ b/src/libultra/voice/voicestartreaddata.c @@ -1,3 +1,49 @@ -#include "global.h" +/** + * File: voicestartreaddata.c + * + * Start voice recognition by the Voice Recognition System + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicestartreaddata/osVoiceStartReadData.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" + +s32 osVoiceStartReadData(OSVoiceHandle* hd) { + s32 errorCode; + u8 status; + u8 data[4]; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + if (hd->mode != VOICE_HANDLE_MODE_0) { + return CONT_ERR_INVALID; + } + + /** + * data[0] = 5 + * data[1] = 0 + * data[2] = 0 + * data[3] = 0 + */ + *(u32*)data = 0x5000000; + errorCode = __osVoiceContWrite4(hd->mq, hd->channel, 0, data); + + if (errorCode == 0) { + errorCode = __osVoiceCheckResult(hd, &status); + + if (errorCode & 0xFF00) { + errorCode = CONT_ERR_INVALID; + } else { + hd->mode = VOICE_HANDLE_MODE_1; + } + } + + return errorCode; +} diff --git a/src/libultra/voice/voicestopread.c b/src/libultra/voice/voicestopread.c index f032fc40e7..570613428c 100644 --- a/src/libultra/voice/voicestopread.c +++ b/src/libultra/voice/voicestopread.c @@ -1,3 +1,60 @@ -#include "global.h" +/** + * File: voicestopread.c + * + * Forcibly stops voice recognition processing by the Voice Recognition System + */ -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicestopread/osVoiceStopReadData.s") +#include "ultra64/controller_voice.h" +#include "ultra64/os_voice.h" +#include "io/controller.h" + +s32 osVoiceStopReadData(OSVoiceHandle* hd) { + s32 errorCode; + s32 i; + u8 status; + u8 data[4]; + + errorCode = __osVoiceGetStatus(hd->mq, hd->channel, &status); + if (errorCode != 0) { + return errorCode; + } + + if (status & 2) { + return CONT_ERR_VOICE_NO_RESPONSE; + } + + if (hd->mode == VOICE_HANDLE_MODE_0) { + return CONT_ERR_INVALID; + } + + /** + * data[0] = 0 + * data[1] = 0 + * data[2] = 7 + * data[3] = 0 + */ + *(u32*)data = 0x700; + errorCode = __osVoiceContWrite4(hd->mq, hd->channel, 0, data); + + if (errorCode == 0) { + i = 0; + do { + errorCode = __osVoiceCheckResult(hd, &status); + if (errorCode & 0xFF00) { + if (((errorCode & 7) == 0) || ((errorCode & 7) == 7)) { + errorCode = 0; + hd->mode = VOICE_HANDLE_MODE_0; + } else { + errorCode = CONT_ERR_INVALID; + } + } else { + hd->mode = VOICE_HANDLE_MODE_0; + } + i++; + } while ((errorCode == CONT_ERR_VOICE_NO_RESPONSE) && (i < 20)); + } + + if (i >= 20) {} + + return errorCode; +} diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index e4c0138f33..b2c82bf7f2 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -71,9 +71,7 @@ 0x80097F70:("__osTimerList","OSTimer*","",0x4), 0x80097F80:("D_80097F80","f32","",0x4), 0x80097F90:("D_80097F90","f32","",0x4), - 0x80097FA0:("D_80097FA0","UNK_TYPE1","",0x1), - 0x80097FA4:("D_80097FA4","UNK_TYPE1","",0x1), - 0x80097FA5:("D_80097FA5","UNK_TYPE1","",0x1), + 0x80097FA0:("sCmds","UNK_TYPE1","",0x1), 0x80097FB0:("__osPfsLastChannel","s32","",0x4), 0x80097FC0:("osViModeNtscLan1","OSViMode","",0x50), 0x80098010:("osViModeMpalLan1","OSViMode","",0x50), @@ -86,7 +84,7 @@ 0x80098144:("udigs","u8","[]",0x14), 0x80098160:("__osViDevMgr","OSDevMgr","",0x1c), 0x8009817C:("__additional_scanline","UNK_TYPE4","",0x4), - 0x80098180:("D_80098180","UNK_TYPE1","",0x1), + 0x80098180:("sDigitalTable","UNK_TYPE1","",0x1), 0x80098190:("D_80098190","char","[]",0x5), 0x80098198:("D_80098198","char","[]",0x5), 0x800981A0:("D_800981A0","char","[]",0x7), @@ -338,7 +336,7 @@ 0x8009CF18:("__osEepromTimer","OSTimer","",0x20), 0x8009CF38:("D_8009CF38","OSMesgQueue","",0x18), 0x8009CF50:("D_8009CF50","OSMesg","",0x4), - 0x8009CF60:("D_8009CF60","UNK_TYPE1","",0x1), + 0x8009CF60:("sHandleStatus","UNK_TYPE1","",0x1), 0x8009CF70:("D_8009CF70","UNK_TYPE4","",0x4), 0x8009CF80:("__osThreadSave","OSThread","",0x1b0), 0x8009D130:("D_8009D130","OSPiHandle","",0x74),