mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-15 12:24:39 +00:00
Matched some controller files (#178)
* osPfsIsPlug.c and osContSetCh.c OK * update * __osPfsGetStatus.c OK * removed unused asm * Updated all libultra controller files to use new structs instead of the temporary structs. Added os_pfs.h * controller updates * fixed header guard * Made suggested changes
This commit is contained in:
parent
229e0c8629
commit
b86edcf92c
39 changed files with 650 additions and 1001 deletions
77
src/libultra_code/__osPfsGetStatus.c
Normal file
77
src/libultra_code/__osPfsGetStatus.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
OSPifRam pifMempakBuf;
|
||||
|
||||
s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel) {
|
||||
s32 ret = 0;
|
||||
OSMesg msg;
|
||||
OSContStatus data;
|
||||
|
||||
__osPfsInodeCacheBank = 250;
|
||||
|
||||
__osPfsRequestOneChannel(channel, CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &pifMempakBuf);
|
||||
osRecvMesg(queue, &msg, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &pifMempakBuf);
|
||||
osRecvMesg(queue, &msg, OS_MESG_BLOCK);
|
||||
|
||||
__osPfsGetOneChannelData(channel, &data);
|
||||
if (((data.status & CONT_CARD_ON) != 0) && ((data.status & CONT_CARD_PULL) != 0)) {
|
||||
return PFS_ERR_NEW_PACK;
|
||||
} else if (data.errno || ((data.status & CONT_CARD_ON) == 0)) {
|
||||
return PFS_ERR_NOPACK;
|
||||
} else if ((data.status & CONT_ADDR_CRC_ER) != 0) {
|
||||
return PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPfsRequestOneChannel(s32 channel, u8 poll) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeaderAligned req;
|
||||
s32 idx;
|
||||
|
||||
__osContLastPoll = CONT_CMD_END;
|
||||
|
||||
pifMempakBuf.status = CONT_CMD_READ_BUTTON;
|
||||
|
||||
bufptr = &pifMempakBuf;
|
||||
|
||||
req.txsize = 1;
|
||||
req.rxsize = 3;
|
||||
req.poll = poll;
|
||||
req.typeh = 0xFF;
|
||||
req.typel = 0xFF;
|
||||
req.status = 0xFF;
|
||||
|
||||
for (idx = 0; idx < channel; idx++) {
|
||||
*bufptr++ = 0;
|
||||
}
|
||||
|
||||
*((__OSContRequestHeaderAligned*)bufptr) = req;
|
||||
bufptr += sizeof(req);
|
||||
*((u8*)bufptr) = CONT_CMD_END;
|
||||
}
|
||||
|
||||
void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeaderAligned req;
|
||||
s32 idx;
|
||||
|
||||
bufptr = &pifMempakBuf;
|
||||
|
||||
for (idx = 0; idx < channel; idx++) {
|
||||
bufptr++;
|
||||
}
|
||||
|
||||
req = *((__OSContRequestHeaderAligned*)bufptr);
|
||||
contData->errno = (req.rxsize & 0xC0) >> 4;
|
||||
if (contData->errno) {
|
||||
return;
|
||||
}
|
||||
|
||||
contData->type = (req.typel << 8) | req.typeh;
|
||||
contData->status = req.status;
|
||||
}
|
|
@ -4,23 +4,23 @@
|
|||
#include <ultra64/controller.h>
|
||||
|
||||
OSMesg osSiMesgBuff[SIAccessQueueSize];
|
||||
OSMesgQueue gOsSiMessageQueue;
|
||||
u32 gOsSiAccessQueueCreated = 0;
|
||||
OSMesgQueue gOSSiMessageQueue;
|
||||
u32 gOSSiAccessQueueCreated = 0;
|
||||
|
||||
void __osSiCreateAccessQueue() {
|
||||
gOsSiAccessQueueCreated = 1;
|
||||
osCreateMesgQueue(&gOsSiMessageQueue, &osSiMesgBuff[0], SIAccessQueueSize - 1);
|
||||
osSendMesg(&gOsSiMessageQueue, NULL, OS_MESG_NOBLOCK);
|
||||
gOSSiAccessQueueCreated = 1;
|
||||
osCreateMesgQueue(&gOSSiMessageQueue, &osSiMesgBuff[0], SIAccessQueueSize - 1);
|
||||
osSendMesg(&gOSSiMessageQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
void __osSiGetAccess() {
|
||||
OSMesg sp1c;
|
||||
if (!gOsSiAccessQueueCreated) {
|
||||
if (!gOSSiAccessQueueCreated) {
|
||||
__osSiCreateAccessQueue();
|
||||
}
|
||||
osRecvMesg(&gOsSiMessageQueue, &sp1c, OS_MESG_BLOCK);
|
||||
osRecvMesg(&gOSSiMessageQueue, &sp1c, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
void __osSiRelAccess() {
|
||||
osSendMesg(&gOsSiMessageQueue, NULL, OS_MESG_NOBLOCK);
|
||||
osSendMesg(&gOSSiMessageQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ s32 osContStartQuery(OSMesgQueue* mq) {
|
|||
ret = 0;
|
||||
|
||||
__osSiGetAccess();
|
||||
if (_osCont_lastPollType != CONT_CMD_REQUEST_STATUS) {
|
||||
if (__osContLastPoll != CONT_CMD_REQUEST_STATUS) {
|
||||
__osPackRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &_osPifInternalBuff);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPifInternalBuff);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
ret = __osSiRawStartDma(OS_READ, &_osPifInternalBuff);
|
||||
_osCont_lastPollType = CONT_CMD_REQUEST_STATUS;
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPifInternalBuff);
|
||||
__osContLastPoll = CONT_CMD_REQUEST_STATUS;
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
#include <ultra64/controller.h>
|
||||
|
||||
pif_data_buffer_t _osPifInternalBuff;
|
||||
u8 _osCont_lastPollType;
|
||||
u8 _osCont_numControllers; // always 4
|
||||
OSPifRam __osPifInternalBuff;
|
||||
u8 __osContLastPoll;
|
||||
u8 __osMaxControllers; // always 4
|
||||
|
||||
// Not sure if the following is a struct together with the last two variables
|
||||
u16 unk_80175812;
|
||||
u32 unk_80175814;
|
||||
u8 unk_80175818[0x20];
|
||||
OSTimer __osEepromTimer;
|
||||
OSMesgQueue __osEepromTimerMsgQ;
|
||||
OSMesg __osEepromTimerMsg;
|
||||
|
||||
u32 gOsContInitialized = 0;
|
||||
OSMesgQueue _osContMesgQueue;
|
||||
OSMesg _osContMesgBuff[4];
|
||||
u32 gOSContInitialized = 0;
|
||||
|
||||
#define HALF_SECOND OS_USEC_TO_CYCLES(500000)
|
||||
s32 osContInit(OSMesgQueue* mq, u8* ctl_present_bitfield, OSContStatus* status) {
|
||||
s32 osContInit(OSMesgQueue* mq, u8* ctlBitfield, OSContStatus* status) {
|
||||
OSMesg mesg;
|
||||
s32 ret = 0;
|
||||
OSTime currentTime;
|
||||
OSTimer timer;
|
||||
OSMesgQueue timerqueue;
|
||||
|
||||
if (gOsContInitialized) {
|
||||
if (gOSContInitialized) {
|
||||
return 0;
|
||||
}
|
||||
gOsContInitialized = 1;
|
||||
gOSContInitialized = 1;
|
||||
currentTime = osGetTime();
|
||||
if (HALF_SECOND > currentTime) {
|
||||
osCreateMesgQueue(&timerqueue, &mesg, 1);
|
||||
osSetTimer(&timer, HALF_SECOND - currentTime, 0, &timerqueue, &mesg);
|
||||
osRecvMesg(&timerqueue, &mesg, OS_MESG_BLOCK);
|
||||
}
|
||||
_osCont_numControllers = 4;
|
||||
__osPackRequestData(0);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &_osPifInternalBuff);
|
||||
__osMaxControllers = MAXCONTROLLERS;
|
||||
__osPackRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPifInternalBuff);
|
||||
osRecvMesg(mq, &mesg, OS_MESG_BLOCK);
|
||||
ret = __osSiRawStartDma(OS_READ, &_osPifInternalBuff);
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPifInternalBuff);
|
||||
osRecvMesg(mq, &mesg, OS_MESG_BLOCK);
|
||||
__osContGetInitData(ctl_present_bitfield, status);
|
||||
_osCont_lastPollType = 0;
|
||||
__osContGetInitData(ctlBitfield, status);
|
||||
__osContLastPoll = CONT_CMD_REQUEST_STATUS;
|
||||
__osSiCreateAccessQueue();
|
||||
osCreateMesgQueue(&_osContMesgQueue, _osContMesgBuff, 1);
|
||||
osCreateMesgQueue(&__osEepromTimerMsgQ, &__osEepromTimerMsg, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osContGetInitData(u8* ctl_present_bitfield, OSContStatus* status) {
|
||||
PIF_IO_slot_t* slot_ptr;
|
||||
PIF_IO_slot_t slot;
|
||||
void __osContGetInitData(u8* ctlBitfield, OSContStatus* status) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeader req;
|
||||
s32 i;
|
||||
u8 bitfield_temp;
|
||||
bitfield_temp = 0;
|
||||
slot_ptr = _osPifInternalBuff.slots;
|
||||
for (i = 0; i < _osCont_numControllers; i++, slot_ptr++, status++) {
|
||||
slot = *slot_ptr;
|
||||
status->errno = (slot.hdr.status_hi_bytes_rec_lo & 0xc0) >> 4;
|
||||
if (status->errno == 0) {
|
||||
status->type = slot.ctl_type_hi << 8 | slot.ctl_type_lo;
|
||||
status->status = slot.ctl_status;
|
||||
bitfield_temp |= 1 << i;
|
||||
u8 bitfieldTemp = 0;
|
||||
bufptr = (u8*)(&__osPifInternalBuff);
|
||||
for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(req), status++) {
|
||||
req = *((__OSContRequestHeader*)bufptr);
|
||||
status->errno = (req.rxsize & 0xC0) >> 4;
|
||||
if (status->errno) {
|
||||
continue;
|
||||
}
|
||||
status->type = req.typel << 8 | req.typeh;
|
||||
status->status = req.status;
|
||||
bitfieldTemp |= 1 << i;
|
||||
}
|
||||
*ctl_present_bitfield = bitfield_temp;
|
||||
*ctlBitfield = bitfieldTemp;
|
||||
}
|
||||
|
||||
void __osPackRequestData(u8 command) {
|
||||
PIF_IO_slot_t* slot_ptr;
|
||||
PIF_IO_slot_t slot;
|
||||
void __osPackRequestData(u8 poll) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeader req;
|
||||
s32 i;
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
_osPifInternalBuff.words[i] = 0;
|
||||
__osPifInternalBuff.ram[i] = 0;
|
||||
}
|
||||
_osPifInternalBuff.status_control = 1;
|
||||
slot.hdr.slot_type = 0xFF;
|
||||
slot.hdr.bytes_send = 1;
|
||||
slot.hdr.status_hi_bytes_rec_lo = 3;
|
||||
slot.hdr.command = command;
|
||||
slot.ctl_type_lo = 0xFF;
|
||||
slot.ctl_type_hi = 0xFF;
|
||||
slot.ctl_status = 0xFF;
|
||||
slot.dummy = 0xFF;
|
||||
slot_ptr = _osPifInternalBuff.slots;
|
||||
for (i = 0; i < _osCont_numControllers; i++) {
|
||||
*slot_ptr++ = slot;
|
||||
__osPifInternalBuff.status = 1;
|
||||
|
||||
bufptr = &__osPifInternalBuff;
|
||||
|
||||
req.align = 0xFF;
|
||||
req.txsize = 1;
|
||||
req.rxsize = 3;
|
||||
req.poll = poll;
|
||||
req.typeh = 0xFF;
|
||||
req.typel = 0xFF;
|
||||
req.status = 0xFF;
|
||||
req.align1 = 0xFF;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContRequestHeader*)bufptr) = req;
|
||||
bufptr += sizeof(req);
|
||||
}
|
||||
slot_ptr->hdr.slot_type = 254;
|
||||
*((u8*)bufptr) = 254;
|
||||
}
|
||||
|
|
21
src/libultra_code/osContSetCh.c
Normal file
21
src/libultra_code/osContSetCh.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
/*
|
||||
* s32 osContSetCh(u8 ch)
|
||||
* This function specifies the number of devices for the functions to access when those functions access to multiple
|
||||
* direct SI devices.
|
||||
*/
|
||||
s32 osContSetCh(u8 ch) {
|
||||
__osSiGetAccess();
|
||||
|
||||
if (ch > MAXCONTROLLERS) {
|
||||
__osMaxControllers = MAXCONTROLLERS;
|
||||
} else {
|
||||
__osMaxControllers = ch;
|
||||
}
|
||||
|
||||
__osContLastPoll = -2;
|
||||
__osSiRelAccess();
|
||||
return 0;
|
||||
}
|
|
@ -1,56 +1,56 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
#include <ultra64/controller.h>
|
||||
|
||||
s32 osContStartReadData(OSMesgQueue* mq) {
|
||||
s32 ret;
|
||||
__osSiGetAccess(); // __osSiGetAccess
|
||||
if (_osCont_lastPollType != 1) {
|
||||
__osSiGetAccess();
|
||||
if (__osContLastPoll != 1) {
|
||||
__osPackReadData();
|
||||
__osSiRawStartDma(OS_WRITE, &_osPifInternalBuff);
|
||||
__osSiRawStartDma(OS_WRITE, &__osPifInternalBuff);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
ret = __osSiRawStartDma(OS_READ, &_osPifInternalBuff);
|
||||
_osCont_lastPollType = 1;
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPifInternalBuff);
|
||||
__osContLastPoll = CONT_CMD_READ_BUTTON;
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void osContGetReadData(OSContPad* pad) {
|
||||
PIF_IO_slot_t* slot_ptr;
|
||||
PIF_IO_slot_t slot;
|
||||
void osContGetReadData(OSContPad* contData) {
|
||||
u8* bufptr;
|
||||
__OSContReadHeader read;
|
||||
s32 i;
|
||||
slot_ptr = _osPifInternalBuff.slots;
|
||||
for (i = 0; i < _osCont_numControllers; i++, slot_ptr++, pad++) {
|
||||
slot = *slot_ptr;
|
||||
pad->errno = (slot.hdr.status_hi_bytes_rec_lo & 0xc0) >> 4;
|
||||
if (pad->errno == 0) {
|
||||
pad->button = slot.input.button;
|
||||
pad->stick_x = slot.input.x;
|
||||
pad->stick_y = slot.input.y;
|
||||
bufptr = (u8*)(&__osPifInternalBuff);
|
||||
for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(read), contData++) {
|
||||
read = *((__OSContReadHeader*)bufptr);
|
||||
contData->errno = (read.rxsize & 0xC0) >> 4;
|
||||
if (contData->errno == 0) {
|
||||
contData->button = read.button;
|
||||
contData->stick_x = read.joyX;
|
||||
contData->stick_y = read.joyY;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void __osPackReadData() {
|
||||
PIF_IO_slot_t* slot_ptr;
|
||||
PIF_IO_slot_t slot;
|
||||
u8* bufptr;
|
||||
__OSContReadHeader read;
|
||||
s32 i;
|
||||
slot_ptr = _osPifInternalBuff.slots;
|
||||
bufptr = (u8*)(&__osPifInternalBuff);
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
_osPifInternalBuff.words[i] = 0;
|
||||
__osPifInternalBuff.ram[i] = 0;
|
||||
}
|
||||
_osPifInternalBuff.status_control = 1;
|
||||
slot.hdr.slot_type = 0xFF;
|
||||
slot.hdr.bytes_send = 1;
|
||||
slot.hdr.status_hi_bytes_rec_lo = 4;
|
||||
slot.hdr.command = 1;
|
||||
slot.input.button = 0xFFFF;
|
||||
slot.input.x = 0xFF;
|
||||
slot.input.y = 0xFF;
|
||||
for (i = 0; i < _osCont_numControllers; i++) {
|
||||
*slot_ptr++ = slot;
|
||||
__osPifInternalBuff.status = 1;
|
||||
read.align = 0xFF;
|
||||
read.txsize = 1;
|
||||
read.rxsize = 4;
|
||||
read.poll = CONT_CMD_READ_BUTTON;
|
||||
read.button = 0xFFFF;
|
||||
read.joyX = 0xFF;
|
||||
read.joyY = 0xFF;
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContReadHeader*)bufptr) = read;
|
||||
bufptr += sizeof(read);
|
||||
}
|
||||
slot_ptr->hdr.slot_type = 0xFE;
|
||||
*((u8*)bufptr) = CONT_CMD_END;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
#include <ultra64/controller.h>
|
||||
|
||||
// Valid addr up to 0x7FF
|
||||
|
|
93
src/libultra_code/osPfsIsPlug.c
Normal file
93
src/libultra_code/osPfsIsPlug.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) {
|
||||
s32 ret = 0;
|
||||
OSMesg msg;
|
||||
u8 bitpattern;
|
||||
OSContStatus contData[MAXCONTROLLERS];
|
||||
s32 channel;
|
||||
u8 bits = 0;
|
||||
s32 crcErrorCount = 3;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
__osPfsRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &pifMempakBuf);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &pifMempakBuf);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
__osPfsGetInitData(&bitpattern, &contData[0]);
|
||||
|
||||
for (channel = 0; channel < __osMaxControllers; channel++) {
|
||||
if ((contData[channel].status & CONT_ADDR_CRC_ER) == 0) {
|
||||
crcErrorCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (channel == __osMaxControllers) {
|
||||
crcErrorCount = 0;
|
||||
}
|
||||
} while (crcErrorCount > 0);
|
||||
|
||||
for (channel = 0; channel < __osMaxControllers; channel++) {
|
||||
if ((contData[channel].errno == 0) && ((contData[channel].status & CONT_CARD_ON) != 0)) {
|
||||
bits |= (1 << channel);
|
||||
}
|
||||
}
|
||||
__osSiRelAccess();
|
||||
*pattern = bits;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPfsRequestData(u8 poll) {
|
||||
u8* bufPtr = &pifMempakBuf;
|
||||
__OSContRequestHeader req;
|
||||
s32 i;
|
||||
|
||||
__osContLastPoll = poll;
|
||||
|
||||
pifMempakBuf.status = 1;
|
||||
|
||||
req.align = 0xFF;
|
||||
req.txsize = 1;
|
||||
req.rxsize = 3;
|
||||
req.poll = poll;
|
||||
req.typeh = 0xFF;
|
||||
req.typel = 0xFF;
|
||||
req.status = 0xFF;
|
||||
req.align1 = 0xFF;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContRequestHeader*)bufPtr) = req;
|
||||
bufPtr += sizeof(req);
|
||||
}
|
||||
*((u8*)bufPtr) = CONT_CMD_END;
|
||||
}
|
||||
|
||||
void __osPfsGetInitData(u8* pattern, OSContStatus* contData) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeader req;
|
||||
s32 i;
|
||||
u8 bits = 0;
|
||||
|
||||
bufptr = &pifMempakBuf;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(req), contData++) {
|
||||
req = *((__OSContRequestHeader*)bufptr);
|
||||
contData->errno = ((req.rxsize & 0xC0) >> 4);
|
||||
|
||||
if (contData->errno) {
|
||||
continue;
|
||||
}
|
||||
|
||||
contData->type = ((req.typel << 8) | req.typeh);
|
||||
contData->status = req.status;
|
||||
bits |= (1 << i);
|
||||
}
|
||||
*pattern = bits;
|
||||
}
|
|
@ -1,50 +1,52 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
#include <ultra64/controller.h>
|
||||
|
||||
s32 osReadMempak(OSMesgQueue* ctrlrqueue, s32 ctrlridx, u16 addr, PIF_mempak_data_t* data) {
|
||||
#define BLOCKSIZE 32
|
||||
|
||||
s32 osReadMempak(OSMesgQueue* ctrlrqueue, s32 channel, u16 addr, u8* data) {
|
||||
s32 ret;
|
||||
s32 i;
|
||||
u8* bufptr;
|
||||
s32 read_try_count = 2;
|
||||
s32 retryCount = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
do {
|
||||
if ((_osCont_lastPollType != 2) || (ctrlridx != D_80134D20)) {
|
||||
bufptr = &pifMempakBuf.bytes[0];
|
||||
_osCont_lastPollType = 2;
|
||||
D_80134D20 = ctrlridx;
|
||||
bufptr = &pifMempakBuf;
|
||||
if ((__osContLastPoll != 2) || (__osPfsLastChannel != channel)) {
|
||||
|
||||
__osContLastPoll = 2;
|
||||
__osPfsLastChannel = channel;
|
||||
// clang-format off
|
||||
for (i = 0; i < ctrlridx; i++) { *bufptr++ = 0; }
|
||||
for (i = 0; i < channel; i++) { *bufptr++ = 0; }
|
||||
// clang-format on
|
||||
pifMempakBuf.status_control = 1;
|
||||
((PIF_header_t*)bufptr)->slot_type = 0xff;
|
||||
((PIF_header_t*)bufptr)->bytes_send = 3;
|
||||
((PIF_header_t*)bufptr)->status_hi_bytes_rec_lo = 0x21;
|
||||
((PIF_header_t*)bufptr)->command = 2; // read mempak; send byte 0
|
||||
pifMempakBuf.status = 1;
|
||||
((__OSContRamHeader*)bufptr)->unk_00 = 0xFF;
|
||||
((__OSContRamHeader*)bufptr)->txsize = 3;
|
||||
((__OSContRamHeader*)bufptr)->rxsize = 0x21;
|
||||
((__OSContRamHeader*)bufptr)->poll = CONT_CMD_READ_MEMPACK; // read mempak; send byte 0
|
||||
((__OSContRamHeader*)bufptr)->datacrc = 0xFF; // read mempak; send byte 0
|
||||
// Received bytes are 6-26 inclusive
|
||||
bufptr[0x26] = 0xff; // last byte of receive
|
||||
bufptr[0x27] = 0xfe; // End of commands
|
||||
bufptr[sizeof(__OSContRamHeader)] = CONT_CMD_END; // End of commands
|
||||
} else {
|
||||
bufptr = &pifMempakBuf.bytes[ctrlridx];
|
||||
bufptr += channel;
|
||||
}
|
||||
bufptr[4] = addr >> 3; // send byte 1
|
||||
bufptr[5] = (s8)(osMempakAddrCRC(addr) | (addr << 5)); // send byte 2
|
||||
__osSiRawStartDma(1, &pifMempakBuf);
|
||||
osRecvMesg(ctrlrqueue, 0, 1);
|
||||
__osSiRawStartDma(0, &pifMempakBuf);
|
||||
osRecvMesg(ctrlrqueue, 0, 1);
|
||||
ret = (((PIF_header_t*)bufptr)->status_hi_bytes_rec_lo & 0xc0) >> 4;
|
||||
((__OSContRamHeader*)bufptr)->hi = addr >> 3; // send byte 1
|
||||
((__OSContRamHeader*)bufptr)->lo = (s8)(osMempakAddrCRC(addr) | (addr << 5)); // send byte 2
|
||||
__osSiRawStartDma(OS_WRITE, &pifMempakBuf);
|
||||
osRecvMesg(ctrlrqueue, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &pifMempakBuf);
|
||||
osRecvMesg(ctrlrqueue, NULL, OS_MESG_BLOCK);
|
||||
ret = (((__OSContRamHeader*)bufptr)->rxsize & 0xC0) >> 4;
|
||||
if (!ret) {
|
||||
if (bufptr[0x26] != osMempakDataCRC(bufptr + 6)) {
|
||||
ret = func_80101910(ctrlrqueue, ctrlridx);
|
||||
if (((__OSContRamHeader*)bufptr)->datacrc != osMempakDataCRC(bufptr + 6)) {
|
||||
ret = __osPfsGetStatus(ctrlrqueue, channel);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
ret = 4; // Retry
|
||||
} else {
|
||||
bcopy(bufptr + 6, data, 0x20);
|
||||
bcopy(bufptr + 6, data, BLOCKSIZE);
|
||||
}
|
||||
} else {
|
||||
ret = 1; // Error
|
||||
|
@ -52,7 +54,7 @@ s32 osReadMempak(OSMesgQueue* ctrlrqueue, s32 ctrlridx, u16 addr, PIF_mempak_dat
|
|||
if (ret != 4) {
|
||||
break;
|
||||
}
|
||||
} while (0 <= read_try_count--);
|
||||
} while (0 <= retryCount--);
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,41 +1,43 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
#include <ultra64/controller.h>
|
||||
|
||||
pif_data_buffer_t osPifBuffers[4];
|
||||
#define BANK_ADDR 0x400
|
||||
#define MOTOR_ID 0x80
|
||||
|
||||
OSPifRam osPifBuffers[MAXCONTROLLERS];
|
||||
|
||||
// func_800CF990 in 1.0
|
||||
s32 osSetRumble(unk_controller_t* arg0, u32 vibrate) {
|
||||
s32 osSetRumble(OSPfs* pfs, u32 vibrate) {
|
||||
s32 i;
|
||||
s32 ret;
|
||||
u8* buf;
|
||||
|
||||
buf = (u8*)&osPifBuffers[arg0->ctrlridx];
|
||||
if (!(arg0->unk0 & 8)) {
|
||||
buf = (u8*)&osPifBuffers[pfs->channel];
|
||||
if (!(pfs->status & 8)) {
|
||||
return 5;
|
||||
}
|
||||
__osSiGetAccess();
|
||||
osPifBuffers[arg0->ctrlridx].status_control = 1;
|
||||
buf += arg0->ctrlridx;
|
||||
for (i = 0; i < 0x20; i++) {
|
||||
((PIF_mempak_wr_t*)buf)->data[i + 2] = vibrate;
|
||||
osPifBuffers[pfs->channel].status = 1;
|
||||
buf += pfs->channel;
|
||||
for (i = 0; i < BLOCKSIZE; i++) {
|
||||
((__OSContRamHeader*)buf)->data[i] = vibrate;
|
||||
}
|
||||
|
||||
_osCont_lastPollType = 0xfe; // last controller poll type?
|
||||
__osSiRawStartDma(OS_WRITE, &osPifBuffers[arg0->ctrlridx]);
|
||||
osRecvMesg(arg0->ctrlrqueue, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &osPifBuffers[arg0->ctrlridx]);
|
||||
osRecvMesg(arg0->ctrlrqueue, NULL, OS_MESG_BLOCK);
|
||||
ret = ((PIF_mempak_wr_t*)buf)->hdr.status_hi_bytes_rec_lo & 0xc0;
|
||||
__osContLastPoll = CONT_CMD_END;
|
||||
__osSiRawStartDma(OS_WRITE, &osPifBuffers[pfs->channel]);
|
||||
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &osPifBuffers[pfs->channel]);
|
||||
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
|
||||
ret = ((__OSContRamHeader*)buf)->rxsize & 0xC0;
|
||||
if (!ret) {
|
||||
if (!vibrate) {
|
||||
if (((PIF_mempak_wr_t*)buf)->data[0x22] != 0) {
|
||||
ret = 4;
|
||||
if (((__OSContRamHeader*)buf)->datacrc != 0) {
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
if (((PIF_mempak_wr_t*)buf)->data[0x22] != 0xeb) {
|
||||
ret = 4;
|
||||
if (((__OSContRamHeader*)buf)->datacrc != 0xEB) {
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,47 +45,43 @@ s32 osSetRumble(unk_controller_t* arg0, u32 vibrate) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
void osSetUpMempakWrite(s32 ctrlridx, pif_data_buffer_t* buf) {
|
||||
u8* buf_ptr = (u8*)buf;
|
||||
PIF_mempak_wr_t mempakwr;
|
||||
void osSetUpMempakWrite(s32 channel, OSPifRam* buf) {
|
||||
u8* bufptr = (u8*)buf;
|
||||
__OSContRamHeader mempakwr;
|
||||
s32 i;
|
||||
mempakwr.hdr.slot_type = 0xFF;
|
||||
mempakwr.hdr.bytes_send = 0x23;
|
||||
mempakwr.hdr.status_hi_bytes_rec_lo = 1;
|
||||
mempakwr.hdr.command = 3; // write mempak
|
||||
mempakwr.data[0] = 0x600 >> 3;
|
||||
mempakwr.data[1] = (u8)(osMempakAddrCRC(0x600) | (0x600 << 5));
|
||||
if (ctrlridx != 0) {
|
||||
for (i = 0; i < ctrlridx; ++i) {
|
||||
*buf_ptr++ = 0;
|
||||
mempakwr.unk_00 = 0xFF;
|
||||
mempakwr.txsize = 0x23;
|
||||
mempakwr.rxsize = 1;
|
||||
mempakwr.poll = 3; // write mempak
|
||||
mempakwr.hi = 0x600 >> 3;
|
||||
mempakwr.lo = (u8)(osMempakAddrCRC(0x600) | (0x600 << 5));
|
||||
if (channel != 0) {
|
||||
for (i = 0; i < channel; ++i) {
|
||||
*bufptr++ = 0;
|
||||
}
|
||||
}
|
||||
*(PIF_mempak_wr_t*)buf_ptr = mempakwr;
|
||||
buf_ptr += 0x27;
|
||||
*buf_ptr = 0xFE;
|
||||
*(__OSContRamHeader*)bufptr = mempakwr;
|
||||
bufptr += sizeof(mempakwr);
|
||||
*bufptr = 0xFE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
u8 unk[0x20];
|
||||
} unk_sp24_t;
|
||||
|
||||
s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, unk_controller_t* unk_controller, u32 ctrlridx) {
|
||||
s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, OSPfs* pfs, u32 channel) {
|
||||
s32 ret;
|
||||
unk_sp24_t sp24;
|
||||
u8 sp24[BLOCKSIZE];
|
||||
|
||||
unk_controller->ctrlrqueue = ctrlrqueue;
|
||||
unk_controller->ctrlridx = ctrlridx;
|
||||
unk_controller->bytes[0x65] = 0xff;
|
||||
unk_controller->unk0 = 0;
|
||||
pfs->queue = ctrlrqueue;
|
||||
pfs->channel = channel;
|
||||
pfs->activebank = 0xFF;
|
||||
pfs->status = 0;
|
||||
|
||||
ret = func_80104C80(unk_controller, 0xfe);
|
||||
ret = func_80104C80(pfs, 0xFE);
|
||||
if (ret == 2) {
|
||||
ret = func_80104C80(unk_controller, 0x80);
|
||||
ret = func_80104C80(pfs, MOTOR_ID);
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = osReadMempak(ctrlrqueue, ctrlridx, 0x400, &sp24);
|
||||
ret = osReadMempak(ctrlrqueue, channel, BANK_ADDR, sp24);
|
||||
ret = ret;
|
||||
if (ret == 2) {
|
||||
ret = 4; // "Controller pack communication error"
|
||||
|
@ -91,29 +89,29 @@ s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, unk_controller_t* unk_controller,
|
|||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (sp24.unk[0x1F] == 0xfe) {
|
||||
return 0xb; // possibly controller pack? (Some other valid return value other than rumble pak)
|
||||
if (sp24[BLOCKSIZE - 1] == 0xFE) {
|
||||
return 0xB;
|
||||
}
|
||||
ret = func_80104C80(unk_controller, 0x80);
|
||||
ret = func_80104C80(pfs, MOTOR_ID);
|
||||
if (ret == 2) {
|
||||
ret = 4; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = osReadMempak(ctrlrqueue, ctrlridx, 0x400, &sp24);
|
||||
ret = osReadMempak(ctrlrqueue, channel, BANK_ADDR, sp24);
|
||||
if (ret == 2) {
|
||||
ret = 4; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (sp24.unk[0x1F] != 0x80) {
|
||||
return 0xb; // possibly controller pack? (Some other valid return value other than rumble pak)
|
||||
if (sp24[BLOCKSIZE - 1] != MOTOR_ID) {
|
||||
return 0xB;
|
||||
}
|
||||
if ((unk_controller->unk0 & 8) == 0) {
|
||||
osSetUpMempakWrite(ctrlridx, &osPifBuffers[ctrlridx]);
|
||||
if ((pfs->status & PFS_MOTOR_INITIALIZED) == 0) {
|
||||
osSetUpMempakWrite(channel, &osPifBuffers[channel]);
|
||||
}
|
||||
unk_controller->unk0 = 8;
|
||||
pfs->status = PFS_MOTOR_INITIALIZED;
|
||||
return 0; // "Recognized rumble pak"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue