#include "libultra_internal.h" #include "osContInternal.h" #include #ifndef AVOID_UB ALIGNED8 OSContPackedStruct _osContCmdBuf[7]; UNUSED static u32 unused; // padding between these two variables u32 _osContPifCtrl; #else // Reordered gcc vars above will disturb the aliasing done to access all 8 members of this array, hence AVOID_UB. ALIGNED8 OSContPackedStruct _osContCmdBuf[8]; #endif extern u8 _osLastSentSiCmd; extern u8 _osContNumControllers; void __osPackReadData(void); s32 osContStartReadData(OSMesgQueue *mesg) { s32 ret = 0; s32 i; __osSiGetAccess(); if (_osLastSentSiCmd != 1) { __osPackReadData(); ret = __osSiRawStartDma(OS_WRITE, _osContCmdBuf); osRecvMesg(mesg, NULL, OS_MESG_BLOCK); } for (i = 0; i < 0x10; i++) { *((u32 *) &_osContCmdBuf + i) = 255; } _osContPifCtrl = 0; ret = __osSiRawStartDma(OS_READ, _osContCmdBuf); _osLastSentSiCmd = 1; __osSiRelAccess(); return ret; } void osContGetReadData(OSContPad *pad) { OSContPackedRead *cmdBufPtr; OSContPackedRead response; s32 i; cmdBufPtr = &_osContCmdBuf[0].read; for (i = 0; i < _osContNumControllers; i++, cmdBufPtr++, pad++) { response = *cmdBufPtr; pad->errnum = (response.rxLen & 0xc0) >> 4; if (pad->errnum == 0) { pad->button = response.button; pad->stick_x = response.rawStickX; pad->stick_y = response.rawStickY; } }; } void __osPackReadData() { OSContPackedRead *cmdBufPtr; OSContPackedRead request; s32 i; cmdBufPtr = &_osContCmdBuf[0].read; for (i = 0; i < 0x10; i++) { *((u32 *) &_osContCmdBuf + i) = 0; } _osContPifCtrl = 1; request.padOrEnd = 255; request.txLen = 1; request.rxLen = 4; request.command = 1; request.button = 65535; request.rawStickX = -1; request.rawStickY = -1; for (i = 0; i < _osContNumControllers; i++) { *cmdBufPtr++ = request; } cmdBufPtr->padOrEnd = 254; }