mirror of
https://github.com/zeldaret/oot.git
synced 2025-02-25 13:30:31 +00:00
Cleanup libultra controller routines (#1312)
* Cleanup libultra controller routines * Correct structure name * Fixes + Suggestions * Move READFORMAT macro to controller.h
This commit is contained in:
parent
2f5eac6b76
commit
97e795fc0e
@ -3,6 +3,21 @@
|
||||
|
||||
#include "message.h"
|
||||
|
||||
/**
|
||||
* Controller channel
|
||||
* Each game controller channel has 4 error bits that are defined in bit 6-7 of
|
||||
* the Rx and Tx data size area bytes. Programmers need to clear these bits
|
||||
* when setting the Tx/Rx size area values for a channel
|
||||
*/
|
||||
#define CHNL_ERR_NORESP 0x80 /* Bit 7 (Rx): No response error */
|
||||
#define CHNL_ERR_OVERRUN 0x40 /* Bit 6 (Rx): Overrun error */
|
||||
#define CHNL_ERR_FRAME 0x80 /* Bit 7 (Tx): Frame error */
|
||||
#define CHNL_ERR_COLLISION 0x40 /* Bit 6 (Tx): Collision error */
|
||||
|
||||
#define CHNL_ERR_MASK 0xC0 /* Bit 6-7: channel errors */
|
||||
|
||||
#define CHNL_ERR(readFormat) (((readFormat).rxsize & CHNL_ERR_MASK) >> 4)
|
||||
|
||||
#define BLOCKSIZE 32
|
||||
#define MAXCONTROLLERS 4
|
||||
#define PFS_ONE_PAGE 8
|
||||
@ -36,6 +51,7 @@
|
||||
#define CONT_CMD_NOP 0xFF
|
||||
#define CONT_CMD_END 0xFE // Indicates end of a command
|
||||
#define CONT_CMD_EXE 1 // Set pif ram status byte to this to do a command
|
||||
#define CONT_CMD_SKIP_CHNL 0 // Skip channel
|
||||
|
||||
#define CONT_ERR_NO_CONTROLLER PFS_ERR_NOPACK /* 1 */
|
||||
#define CONT_ERR_CONTRFAIL CONT_OVERRUN_ERROR /* 4 */
|
||||
@ -79,6 +95,27 @@
|
||||
#define CONT_ADDR_CRC_ER 0x04
|
||||
#define CONT_EEPROM_BUSY 0x80
|
||||
|
||||
/* Accessory detection */
|
||||
#define CONT_ADDR_DETECT 0x8000
|
||||
|
||||
// Rumble
|
||||
#define CONT_ADDR_RUMBLE 0xC000
|
||||
|
||||
// Controller Pak / Transfer Pak
|
||||
#define CONT_ADDR_GB_POWER 0x8000 // Same as the detection address, but semantically different
|
||||
#define CONT_ADDR_GB_BANK 0xA000
|
||||
#define CONT_ADDR_GB_STATUS 0xB000
|
||||
|
||||
// Addresses sent to controller accessories are in blocks, not bytes
|
||||
#define CONT_BLOCKS(x) ((x) / BLOCKSIZE)
|
||||
|
||||
// Block addresses of the above
|
||||
#define CONT_BLOCK_DETECT CONT_BLOCKS(CONT_ADDR_DETECT)
|
||||
#define CONT_BLOCK_RUMBLE CONT_BLOCKS(CONT_ADDR_RUMBLE)
|
||||
#define CONT_BLOCK_GB_POWER CONT_BLOCKS(CONT_ADDR_GB_POWER)
|
||||
#define CONT_BLOCK_GB_BANK CONT_BLOCKS(CONT_ADDR_GB_BANK)
|
||||
#define CONT_BLOCK_GB_STATUS CONT_BLOCKS(CONT_ADDR_GB_STATUS)
|
||||
|
||||
/* Buttons */
|
||||
#define BTN_CRIGHT 0x0001
|
||||
#define BTN_CLEFT 0x0002
|
||||
@ -124,49 +161,47 @@ typedef struct {
|
||||
/* 0x26 */ u8 errno;
|
||||
} OSContRamIo; // size = 0x28
|
||||
|
||||
// Original name: __OSContRequesFormat
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 align;
|
||||
/* 0x01 */ u8 txsize;
|
||||
/* 0x02 */ u8 rxsize;
|
||||
/* 0x03 */ u8 poll;
|
||||
/* 0x03 */ u8 cmd;
|
||||
/* 0x04 */ u8 typeh;
|
||||
/* 0x05 */ u8 typel;
|
||||
/* 0x06 */ u8 status;
|
||||
/* 0x07 */ u8 align1;
|
||||
} __OSContRequestHeader; // size = 0x8
|
||||
} __OSContRequesFormat; // size = 0x8
|
||||
|
||||
// Original name: __OSContRequesHeaderFormatShort
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 txsize;
|
||||
/* 0x01 */ u8 rxsize;
|
||||
/* 0x02 */ u8 poll;
|
||||
/* 0x02 */ u8 cmd;
|
||||
/* 0x03 */ u8 typeh;
|
||||
/* 0x04 */ u8 typel;
|
||||
/* 0x05 */ u8 status;
|
||||
} __OSContRequestHeaderAligned; // size = 0x6
|
||||
} __OSContRequesFormatShort; // size = 0x6
|
||||
|
||||
// Original Name: __OSContRamReadFormat
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 unk_00;
|
||||
/* 0x01 */ u8 txsize;
|
||||
/* 0x02 */ u8 rxsize;
|
||||
/* 0x03 */ u8 poll;
|
||||
/* 0x03 */ u8 cmd;
|
||||
/* 0x04 */ u8 hi;
|
||||
/* 0x05 */ u8 lo;
|
||||
/* 0x06 */ u8 data[BLOCKSIZE];
|
||||
/* 0x26 */ u8 datacrc;
|
||||
} __OSContRamHeader; // size = 0x27
|
||||
} __OSContRamReadFormat; // size = 0x27
|
||||
|
||||
#define READFORMAT(ptr) ((__OSContRamReadFormat*)(ptr))
|
||||
|
||||
// Original name: __OSContReadFormat
|
||||
typedef struct {
|
||||
/* 0x00 */ u8 align;
|
||||
/* 0x01 */ u8 txsize;
|
||||
/* 0x02 */ u8 rxsize;
|
||||
/* 0x03 */ u8 poll;
|
||||
/* 0x03 */ u8 cmd;
|
||||
/* 0x04 */ u16 button;
|
||||
/* 0x06 */ s8 joyX;
|
||||
/* 0x07 */ s8 joyY;
|
||||
} __OSContReadHeader; // size = 0x8
|
||||
} __OSContReadFormat; // size = 0x8
|
||||
|
||||
#endif
|
||||
|
@ -77,16 +77,16 @@ typedef struct {
|
||||
/* 0x2C */ u8 label[32];
|
||||
/* 0x4C */ s32 version;
|
||||
/* 0x50 */ s32 dir_size;
|
||||
/* 0x54 */ s32 inode_table; /* block location */
|
||||
/* 0x58 */ s32 minode_table; /* mirrioring inode_table */
|
||||
/* 0x5C */ s32 dir_table; /* block location */
|
||||
/* 0x60 */ s32 inodeStartPage; /* page # */
|
||||
/* 0x54 */ s32 inode_table; /* block location */
|
||||
/* 0x58 */ s32 minode_table; /* mirroring inode_table */
|
||||
/* 0x5C */ s32 dir_table; /* block location */
|
||||
/* 0x60 */ s32 inodeStartPage; /* page # */
|
||||
/* 0x64 */ u8 banks;
|
||||
/* 0x65 */ u8 activebank;
|
||||
} OSPfs; // size = 0x68
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 file_size; /* bytes */
|
||||
/* 0x00 */ u32 file_size; /* bytes */
|
||||
/* 0x04 */ u32 game_code;
|
||||
/* 0x08 */ u16 company_code;
|
||||
/* 0x0C */ char ext_name[4];
|
||||
|
@ -226,11 +226,11 @@ extern void(*D_801755D0)(void);
|
||||
|
||||
extern u32 __osMalloc_FreeBlockTest_Enable;
|
||||
extern Arena gSystemArena;
|
||||
extern OSPifRam __osPifInternalBuff;
|
||||
extern u8 __osContLastPoll;
|
||||
extern OSPifRam __osContPifRam;
|
||||
extern u8 __osContLastCmd;
|
||||
extern u8 __osMaxControllers;
|
||||
extern __OSInode __osPfsInodeCache;
|
||||
extern OSPifRam gPifMempakBuf;
|
||||
extern OSPifRam __osPfsPifRam;
|
||||
extern u16 gZBuffer[SCREEN_HEIGHT][SCREEN_WIDTH]; // 0x25800 bytes
|
||||
extern u64 gGfxSPTaskOutputBuffer[0x3000]; // 0x18000 bytes
|
||||
extern u64 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE / sizeof(u64)]; // 0xC00 bytes
|
||||
|
@ -20,8 +20,8 @@ s32 __osIdCheckSum(u16* ptr, u16* checkSum, u16* idSum) {
|
||||
u32 i;
|
||||
|
||||
*checkSum = *idSum = 0;
|
||||
for (i = 0; i < ((sizeof(__OSPackId) - sizeof(u32)) / sizeof(u8)); i += 2) {
|
||||
data = *((u16*)((u32)ptr + i));
|
||||
for (i = 0; i < ((sizeof(__OSPackId) - sizeof(u32)) / sizeof(u8)); i += sizeof(u16)) {
|
||||
data = *((u16*)((uintptr_t)ptr + i));
|
||||
*checkSum += data;
|
||||
*idSum += ~data;
|
||||
}
|
||||
@ -33,10 +33,11 @@ s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid) {
|
||||
u8 temp[BLOCKSIZE];
|
||||
u8 comp[BLOCKSIZE];
|
||||
u8 mask = 0;
|
||||
s32 i, j = 0;
|
||||
s32 i;
|
||||
s32 j = 0;
|
||||
u16 index[4];
|
||||
|
||||
newid->repaired = 0xFFFFFFFF;
|
||||
newid->repaired = -1;
|
||||
newid->random = osGetCount();
|
||||
newid->serialMid = badid->serialMid;
|
||||
newid->serialLow = badid->serialLow;
|
||||
@ -111,7 +112,7 @@ s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid) {
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < BLOCKSIZE; i++) {
|
||||
if (temp[i] != *(u8*)((s32)newid + i)) {
|
||||
if (temp[i] != ((u8*)newid)[i]) {
|
||||
return PFS_ERR_DEVICE;
|
||||
}
|
||||
}
|
||||
@ -126,7 +127,7 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check) {
|
||||
s32 i;
|
||||
s32 j;
|
||||
|
||||
if ((pfs->activebank != 0) && (ret = __osPfsSelectBank(pfs, 0)) != 0) {
|
||||
if (pfs->activebank != 0 && (ret = __osPfsSelectBank(pfs, 0)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -134,20 +135,21 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check) {
|
||||
index[1] = PFS_ID_1AREA;
|
||||
index[2] = PFS_ID_2AREA;
|
||||
index[3] = PFS_ID_3AREA;
|
||||
for (i = 1; i < 4; i++) {
|
||||
|
||||
for (i = 1; i < ARRAY_COUNT(index); i++) {
|
||||
if ((ret = __osContRamRead(pfs->queue, pfs->channel, index[i], (u8*)check)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
__osIdCheckSum((u16*)check, &sum, &idSum);
|
||||
if ((check->checksum == sum) && (check->invertedChecksum == idSum)) {
|
||||
if (check->checksum == sum && check->invertedChecksum == idSum) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 4) {
|
||||
if (i == ARRAY_COUNT(index)) {
|
||||
return PFS_ERR_ID_FATAL;
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (j = 0; j < ARRAY_COUNT(index); j++) {
|
||||
if (j != i) {
|
||||
if ((ret = __osContRamWrite(pfs->queue, pfs->channel, index[j], (u8*)check, PFS_FORCE)) != 0) {
|
||||
return ret;
|
||||
@ -165,10 +167,8 @@ s32 __osGetId(OSPfs* pfs) {
|
||||
__OSPackId newid;
|
||||
s32 ret;
|
||||
|
||||
if (pfs->activebank != 0) {
|
||||
if ((ret = __osPfsSelectBank(pfs, 0)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (pfs->activebank != 0 && (ret = __osPfsSelectBank(pfs, 0)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, temp)) != 0) {
|
||||
@ -177,7 +177,7 @@ s32 __osGetId(OSPfs* pfs) {
|
||||
|
||||
__osIdCheckSum((u16*)temp, &sum, &isum);
|
||||
id = (__OSPackId*)temp;
|
||||
if ((id->checksum != sum) || (id->invertedChecksum != isum)) {
|
||||
if (id->checksum != sum || id->invertedChecksum != isum) {
|
||||
if ((ret = __osCheckPackId(pfs, id)) == PFS_ERR_ID_FATAL) {
|
||||
ret = __osRepairPackId(pfs, id, &newid);
|
||||
if (ret) {
|
||||
@ -189,13 +189,13 @@ s32 __osGetId(OSPfs* pfs) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((id->deviceid & 0x01) == 0) {
|
||||
if ((id->deviceid & 1) == 0) {
|
||||
ret = __osRepairPackId(pfs, id, &newid);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
id = &newid;
|
||||
if ((id->deviceid & 0x01) == 0) {
|
||||
if ((id->deviceid & 1) == 0) {
|
||||
return PFS_ERR_DEVICE;
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,7 @@ s32 __osPfsRWInode(OSPfs* pfs, __OSInode* inode, u8 flag, u8 bank) {
|
||||
sum = __osSumcalc((u8*)(inode->inodePage + offset), (PFS_INODE_SIZE_PER_PAGE - offset) * 2);
|
||||
if (sum != inode->inodePage[0].inode_t.page) {
|
||||
for (j = 0; j < PFS_ONE_PAGE; j++) {
|
||||
addr = (u8*)(((u8*)inode) + (j * BLOCKSIZE));
|
||||
addr = (((u8*)inode->inodePage) + (j * BLOCKSIZE));
|
||||
ret = __osContRamRead(pfs->queue, pfs->channel, pfs->minode_table + (bank * PFS_ONE_PAGE) + j, addr);
|
||||
}
|
||||
sum = __osSumcalc((u8*)(inode->inodePage + offset), (PFS_INODE_SIZE_PER_PAGE - offset) * 2);
|
||||
@ -298,7 +298,7 @@ s32 __osPfsRWInode(OSPfs* pfs, __OSInode* inode, u8 flag, u8 bank) {
|
||||
return PFS_ERR_INCONSISTENT;
|
||||
}
|
||||
for (j = 0; j < PFS_ONE_PAGE; j++) {
|
||||
addr = (u8*)(((u8*)inode) + (j * BLOCKSIZE));
|
||||
addr = (((u8*)inode->inodePage) + (j * BLOCKSIZE));
|
||||
ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->inode_table + (bank * PFS_ONE_PAGE) + j, addr, 0);
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ s32 osContStartQuery(OSMesgQueue* mq) {
|
||||
s32 ret = 0;
|
||||
|
||||
__osSiGetAccess();
|
||||
if (__osContLastPoll != CONT_CMD_REQUEST_STATUS) {
|
||||
if (__osContLastCmd != CONT_CMD_REQUEST_STATUS) {
|
||||
__osPackRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPifInternalBuff);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPifInternalBuff);
|
||||
__osContLastPoll = CONT_CMD_REQUEST_STATUS;
|
||||
ret = __osSiRawStartDma(OS_READ, &__osContPifRam);
|
||||
__osContLastCmd = CONT_CMD_REQUEST_STATUS;
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
@ -7,48 +7,48 @@ s32 __osPfsLastChannel = -1;
|
||||
s32 __osContRamRead(OSMesgQueue* ctrlrqueue, s32 channel, u16 addr, u8* data) {
|
||||
s32 ret;
|
||||
s32 i;
|
||||
u8* bufptr;
|
||||
u8* ptr;
|
||||
s32 retryCount = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
do {
|
||||
bufptr = (u8*)&gPifMempakBuf;
|
||||
ptr = (u8*)&__osPfsPifRam;
|
||||
|
||||
if ((__osContLastPoll != 2) || (__osPfsLastChannel != channel)) {
|
||||
__osContLastPoll = 2;
|
||||
if (__osContLastCmd != CONT_CMD_READ_MEMPACK || __osPfsLastChannel != channel) {
|
||||
__osContLastCmd = CONT_CMD_READ_MEMPACK;
|
||||
__osPfsLastChannel = channel;
|
||||
// clang-format off
|
||||
for (i = 0; i < channel; i++) { *bufptr++ = 0; }
|
||||
for (i = 0; i < channel; i++) { *ptr++ = CONT_CMD_SKIP_CHNL; }
|
||||
// clang-format on
|
||||
gPifMempakBuf.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
|
||||
__osPfsPifRam.status = CONT_CMD_EXE;
|
||||
READFORMAT(ptr)->unk_00 = CONT_CMD_NOP;
|
||||
READFORMAT(ptr)->txsize = CONT_CMD_READ_MEMPACK_TX;
|
||||
READFORMAT(ptr)->rxsize = CONT_CMD_READ_MEMPACK_RX;
|
||||
READFORMAT(ptr)->cmd = CONT_CMD_READ_MEMPACK;
|
||||
READFORMAT(ptr)->datacrc = CONT_CMD_NOP;
|
||||
// Received bytes are 6-26 inclusive
|
||||
bufptr[sizeof(__OSContRamHeader)] = CONT_CMD_END; // End of commands
|
||||
ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END; // End of commands
|
||||
} else {
|
||||
bufptr += channel;
|
||||
ptr += channel;
|
||||
}
|
||||
|
||||
((__OSContRamHeader*)bufptr)->hi = addr >> 3; // send byte 1
|
||||
((__OSContRamHeader*)bufptr)->lo = (s8)(__osContAddressCrc(addr) | (addr << 5)); // send byte 2
|
||||
__osSiRawStartDma(OS_WRITE, &gPifMempakBuf);
|
||||
READFORMAT(ptr)->hi = addr >> 3;
|
||||
READFORMAT(ptr)->lo = (s8)(__osContAddressCrc(addr) | (addr << 5));
|
||||
__osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(ctrlrqueue, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &gPifMempakBuf);
|
||||
__osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(ctrlrqueue, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = (((__OSContRamHeader*)bufptr)->rxsize & 0xC0) >> 4;
|
||||
ret = CHNL_ERR(*READFORMAT(ptr));
|
||||
if (!ret) {
|
||||
if (((__OSContRamHeader*)bufptr)->datacrc != __osContDataCrc(bufptr + 6)) {
|
||||
if (READFORMAT(ptr)->datacrc != __osContDataCrc(ptr + 6)) {
|
||||
ret = __osPfsGetStatus(ctrlrqueue, channel);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
ret = 4; // Retry
|
||||
} else {
|
||||
bcopy(bufptr + 6, data, BLOCKSIZE);
|
||||
bcopy(ptr + 6, data, BLOCKSIZE);
|
||||
}
|
||||
} else {
|
||||
ret = 1; // Error
|
||||
|
@ -15,43 +15,43 @@ s32 __osContRamWrite(OSMesgQueue* mq, s32 channel, u16 address, u8* buffer, s32
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
ptr = (u8*)(&gPifMempakBuf);
|
||||
ptr = (u8*)&__osPfsPifRam;
|
||||
|
||||
if (__osContLastPoll != CONT_CMD_WRITE_MEMPACK || __osPfsLastChannel != channel) {
|
||||
__osContLastPoll = CONT_CMD_WRITE_MEMPACK;
|
||||
if (__osContLastCmd != CONT_CMD_WRITE_MEMPACK || __osPfsLastChannel != channel) {
|
||||
__osContLastCmd = CONT_CMD_WRITE_MEMPACK;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
// clang-format off
|
||||
for (i = 0; i < channel; i++) { *ptr++ = 0; }
|
||||
// clang-format on
|
||||
|
||||
gPifMempakBuf.status = 1;
|
||||
__osPfsPifRam.status = CONT_CMD_EXE;
|
||||
|
||||
((__OSContRamHeader*)ptr)->unk_00 = 0xFF;
|
||||
((__OSContRamHeader*)ptr)->txsize = 35;
|
||||
((__OSContRamHeader*)ptr)->rxsize = 1;
|
||||
((__OSContRamHeader*)ptr)->poll = CONT_CMD_WRITE_MEMPACK;
|
||||
((__OSContRamHeader*)ptr)->datacrc = 0xFF;
|
||||
READFORMAT(ptr)->unk_00 = CONT_CMD_NOP;
|
||||
READFORMAT(ptr)->txsize = CONT_CMD_WRITE_MEMPACK_TX;
|
||||
READFORMAT(ptr)->rxsize = CONT_CMD_WRITE_MEMPACK_RX;
|
||||
READFORMAT(ptr)->cmd = CONT_CMD_WRITE_MEMPACK;
|
||||
READFORMAT(ptr)->datacrc = CONT_CMD_NOP;
|
||||
|
||||
ptr[sizeof(__OSContRamHeader)] = CONT_CMD_END;
|
||||
ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr += channel;
|
||||
}
|
||||
((__OSContRamHeader*)ptr)->hi = address >> 3;
|
||||
((__OSContRamHeader*)ptr)->lo = ((address << 5) | __osContAddressCrc(address));
|
||||
READFORMAT(ptr)->hi = address >> 3;
|
||||
READFORMAT(ptr)->lo = ((address << 5) | __osContAddressCrc(address));
|
||||
|
||||
bcopy(buffer, ((__OSContRamHeader*)ptr)->data, BLOCKSIZE);
|
||||
bcopy(buffer, READFORMAT(ptr)->data, BLOCKSIZE);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &gPifMempakBuf);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
crc = __osContDataCrc(buffer);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &gPifMempakBuf);
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = ((((__OSContRamHeader*)ptr)->rxsize & 0xC0) >> 4);
|
||||
ret = CHNL_ERR(*READFORMAT(ptr));
|
||||
if (!ret) {
|
||||
if (crc != ((__OSContRamHeader*)ptr)->datacrc) {
|
||||
if (crc != READFORMAT(ptr)->datacrc) {
|
||||
if ((ret = __osPfsGetStatus(mq, channel))) {
|
||||
break;
|
||||
} else {
|
||||
|
@ -4,25 +4,26 @@ s32 osContStartReadData(OSMesgQueue* mq) {
|
||||
s32 ret;
|
||||
|
||||
__osSiGetAccess();
|
||||
if (__osContLastPoll != 1) {
|
||||
if (__osContLastCmd != CONT_CMD_READ_BUTTON) {
|
||||
__osPackReadData();
|
||||
__osSiRawStartDma(OS_WRITE, &__osPifInternalBuff);
|
||||
__osSiRawStartDma(OS_WRITE, &__osContPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPifInternalBuff);
|
||||
__osContLastPoll = CONT_CMD_READ_BUTTON;
|
||||
ret = __osSiRawStartDma(OS_READ, &__osContPifRam);
|
||||
__osContLastCmd = CONT_CMD_READ_BUTTON;
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void osContGetReadData(OSContPad* contData) {
|
||||
u8* bufptr = (u8*)(&__osPifInternalBuff);
|
||||
__OSContReadHeader read;
|
||||
u8* ptr = (u8*)&__osContPifRam;
|
||||
__OSContReadFormat read;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(read), contData++) {
|
||||
read = *((__OSContReadHeader*)bufptr);
|
||||
contData->errno = (read.rxsize & 0xC0) >> 4;
|
||||
for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(read), contData++) {
|
||||
read = *((__OSContReadFormat*)ptr);
|
||||
|
||||
contData->errno = CHNL_ERR(read);
|
||||
if (contData->errno == 0) {
|
||||
contData->button = read.button;
|
||||
contData->stick_x = read.joyX;
|
||||
@ -32,24 +33,25 @@ void osContGetReadData(OSContPad* contData) {
|
||||
}
|
||||
|
||||
void __osPackReadData(void) {
|
||||
u8* bufptr = (u8*)(&__osPifInternalBuff);
|
||||
__OSContReadHeader read;
|
||||
u8* ptr = (u8*)&__osContPifRam;
|
||||
__OSContReadFormat read;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
__osPifInternalBuff.ram[i] = 0;
|
||||
for (i = 0; i < ARRAY_COUNT(__osContPifRam.ram); i++) {
|
||||
__osContPifRam.ram[i] = 0;
|
||||
}
|
||||
__osPifInternalBuff.status = 1;
|
||||
read.align = 0xFF;
|
||||
read.txsize = 1;
|
||||
read.rxsize = 4;
|
||||
read.poll = CONT_CMD_READ_BUTTON;
|
||||
__osContPifRam.status = CONT_CMD_EXE;
|
||||
|
||||
read.align = CONT_CMD_NOP;
|
||||
read.txsize = CONT_CMD_READ_BUTTON_TX;
|
||||
read.rxsize = CONT_CMD_READ_BUTTON_RX;
|
||||
read.cmd = CONT_CMD_READ_BUTTON;
|
||||
read.button = 0xFFFF;
|
||||
read.joyX = 0xFF;
|
||||
read.joyY = 0xFF;
|
||||
read.joyX = -1;
|
||||
read.joyY = -1;
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContReadHeader*)bufptr) = read;
|
||||
bufptr += sizeof(read);
|
||||
*((__OSContReadFormat*)ptr) = read;
|
||||
ptr += sizeof(read);
|
||||
}
|
||||
*((u8*)bufptr) = CONT_CMD_END;
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
#include "global.h"
|
||||
|
||||
OSPifRam __osPifInternalBuff;
|
||||
u8 __osContLastPoll;
|
||||
OSPifRam __osContPifRam;
|
||||
u8 __osContLastCmd;
|
||||
u8 __osMaxControllers; // always 4
|
||||
|
||||
OSTimer __osEepromTimer;
|
||||
OSMesgQueue __osEepromTimerMsgQueue;
|
||||
OSMesg __osEepromTimerMsg;
|
||||
|
||||
u32 gOSContInitialized = 0;
|
||||
u32 __osContInitialized = false;
|
||||
|
||||
#define HALF_SECOND OS_USEC_TO_CYCLES(500000)
|
||||
|
||||
@ -17,78 +17,82 @@ s32 osContInit(OSMesgQueue* mq, u8* ctlBitfield, OSContStatus* status) {
|
||||
s32 ret = 0;
|
||||
OSTime currentTime;
|
||||
OSTimer timer;
|
||||
OSMesgQueue timerqueue;
|
||||
OSMesgQueue timerMesgQueue;
|
||||
|
||||
if (gOSContInitialized) {
|
||||
if (__osContInitialized) {
|
||||
return 0;
|
||||
}
|
||||
__osContInitialized = true;
|
||||
|
||||
gOSContInitialized = 1;
|
||||
currentTime = osGetTime();
|
||||
if (HALF_SECOND > currentTime) {
|
||||
osCreateMesgQueue(&timerqueue, &msg, 1);
|
||||
osSetTimer(&timer, HALF_SECOND - currentTime, 0, &timerqueue, &msg);
|
||||
osRecvMesg(&timerqueue, &msg, OS_MESG_BLOCK);
|
||||
if (currentTime < HALF_SECOND) {
|
||||
osCreateMesgQueue(&timerMesgQueue, &msg, 1);
|
||||
osSetTimer(&timer, HALF_SECOND - currentTime, 0, &timerMesgQueue, &msg);
|
||||
osRecvMesg(&timerMesgQueue, &msg, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
__osMaxControllers = MAXCONTROLLERS;
|
||||
__osPackRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPifInternalBuff);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPifInternalBuff);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &__osContPifRam);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
__osContGetInitData(ctlBitfield, status);
|
||||
__osContLastPoll = CONT_CMD_REQUEST_STATUS;
|
||||
__osContLastCmd = CONT_CMD_REQUEST_STATUS;
|
||||
__osSiCreateAccessQueue();
|
||||
osCreateMesgQueue(&__osEepromTimerMsgQueue, &__osEepromTimerMsg, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osContGetInitData(u8* ctlBitfield, OSContStatus* status) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeader req;
|
||||
void __osContGetInitData(u8* ctlBitfield, OSContStatus* data) {
|
||||
u8* ptr;
|
||||
__OSContRequesFormat req;
|
||||
s32 i;
|
||||
u8 bitfieldTemp = 0;
|
||||
|
||||
bufptr = (u8*)(&__osPifInternalBuff);
|
||||
ptr = (u8*)&__osContPifRam;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(req), status++) {
|
||||
req = *((__OSContRequestHeader*)bufptr);
|
||||
status->errno = (req.rxsize & 0xC0) >> 4;
|
||||
if (status->errno) {
|
||||
for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(req), data++) {
|
||||
req = *(__OSContRequesFormat*)ptr;
|
||||
data->errno = CHNL_ERR(req);
|
||||
if (data->errno) {
|
||||
continue;
|
||||
}
|
||||
status->type = req.typel << 8 | req.typeh;
|
||||
status->status = req.status;
|
||||
data->type = req.typel << 8 | req.typeh;
|
||||
data->status = req.status;
|
||||
bitfieldTemp |= 1 << i;
|
||||
}
|
||||
*ctlBitfield = bitfieldTemp;
|
||||
}
|
||||
|
||||
void __osPackRequestData(u8 poll) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeader req;
|
||||
u8* ptr;
|
||||
__OSContRequesFormat req;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 0xF; i++) {
|
||||
__osPifInternalBuff.ram[i] = 0;
|
||||
for (i = 0; i < ARRAY_COUNT(__osContPifRam.ram); i++) {
|
||||
__osContPifRam.ram[i] = 0;
|
||||
}
|
||||
__osPifInternalBuff.status = 1;
|
||||
__osContPifRam.status = CONT_CMD_EXE;
|
||||
|
||||
bufptr = (u8*)(&__osPifInternalBuff);
|
||||
ptr = (u8*)&__osContPifRam;
|
||||
|
||||
req.align = 0xFF;
|
||||
req.txsize = 1;
|
||||
req.rxsize = 3;
|
||||
req.poll = poll;
|
||||
req.typeh = 0xFF;
|
||||
req.typel = 0xFF;
|
||||
req.status = 0xFF;
|
||||
req.align1 = 0xFF;
|
||||
req.align = CONT_CMD_NOP;
|
||||
req.txsize = CONT_CMD_RESET_TX;
|
||||
req.rxsize = CONT_CMD_RESET_RX;
|
||||
req.cmd = poll;
|
||||
req.typeh = CONT_CMD_NOP;
|
||||
req.typel = CONT_CMD_NOP;
|
||||
req.status = CONT_CMD_NOP;
|
||||
req.align1 = CONT_CMD_NOP;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContRequestHeader*)bufptr) = req;
|
||||
bufptr += sizeof(req);
|
||||
*((__OSContRequesFormat*)ptr) = req;
|
||||
ptr += sizeof(req);
|
||||
}
|
||||
*((u8*)bufptr) = 254;
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ s32 osContSetCh(u8 ch) {
|
||||
__osMaxControllers = ch;
|
||||
}
|
||||
|
||||
__osContLastPoll = -2;
|
||||
__osContLastCmd = CONT_CMD_END;
|
||||
__osSiRelAccess();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,40 +1,40 @@
|
||||
#include "global.h"
|
||||
|
||||
#define BANK_ADDR 0x400
|
||||
#define MOTOR_ID 0x80
|
||||
|
||||
OSPifRam osPifBuffers[MAXCONTROLLERS];
|
||||
OSPifRam __MotorDataBuf[MAXCONTROLLERS];
|
||||
|
||||
s32 __osMotorAccess(OSPfs* pfs, u32 vibrate) {
|
||||
s32 i;
|
||||
s32 ret;
|
||||
u8* buf = (u8*)&osPifBuffers[pfs->channel];
|
||||
u8* ptr = (u8*)&__MotorDataBuf[pfs->channel];
|
||||
|
||||
if (!(pfs->status & 8)) {
|
||||
return 5;
|
||||
if (!(pfs->status & PFS_MOTOR_INITIALIZED)) {
|
||||
return PFS_ERR_INVALID;
|
||||
}
|
||||
|
||||
__osSiGetAccess();
|
||||
osPifBuffers[pfs->channel].status = 1;
|
||||
buf += pfs->channel;
|
||||
__MotorDataBuf[pfs->channel].status = CONT_CMD_EXE;
|
||||
ptr += pfs->channel;
|
||||
|
||||
for (i = 0; i < BLOCKSIZE; i++) {
|
||||
((__OSContRamHeader*)buf)->data[i] = vibrate;
|
||||
READFORMAT(ptr)->data[i] = vibrate;
|
||||
}
|
||||
|
||||
__osContLastPoll = CONT_CMD_END;
|
||||
__osSiRawStartDma(OS_WRITE, &osPifBuffers[pfs->channel]);
|
||||
__osContLastCmd = CONT_CMD_END;
|
||||
__osSiRawStartDma(OS_WRITE, &__MotorDataBuf[pfs->channel]);
|
||||
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
|
||||
__osSiRawStartDma(OS_READ, &osPifBuffers[pfs->channel]);
|
||||
__osSiRawStartDma(OS_READ, &__MotorDataBuf[pfs->channel]);
|
||||
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = ((__OSContRamHeader*)buf)->rxsize & 0xC0;
|
||||
ret = READFORMAT(ptr)->rxsize & CHNL_ERR_MASK;
|
||||
if (!ret) {
|
||||
if (!vibrate) {
|
||||
if (((__OSContRamHeader*)buf)->datacrc != 0) {
|
||||
if (READFORMAT(ptr)->datacrc != 0) {
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
if (((__OSContRamHeader*)buf)->datacrc != 0xEB) {
|
||||
if (READFORMAT(ptr)->datacrc != 0xEB) {
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
}
|
||||
@ -45,32 +45,32 @@ s32 __osMotorAccess(OSPfs* pfs, u32 vibrate) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _MakeMotorData(s32 channel, OSPifRam* buf) {
|
||||
u8* bufptr = (u8*)buf;
|
||||
__OSContRamHeader mempakwr;
|
||||
void _MakeMotorData(s32 channel, OSPifRam* mdata) {
|
||||
u8* ptr = (u8*)mdata;
|
||||
__OSContRamReadFormat ramreadformat;
|
||||
s32 i;
|
||||
|
||||
mempakwr.unk_00 = 0xFF;
|
||||
mempakwr.txsize = 0x23;
|
||||
mempakwr.rxsize = 1;
|
||||
mempakwr.poll = 3; // write mempak
|
||||
mempakwr.hi = 0x600 >> 3;
|
||||
mempakwr.lo = (u8)(__osContAddressCrc(0x600) | (0x600 << 5));
|
||||
ramreadformat.unk_00 = CONT_CMD_NOP;
|
||||
ramreadformat.txsize = CONT_CMD_WRITE_MEMPACK_TX;
|
||||
ramreadformat.rxsize = CONT_CMD_WRITE_MEMPACK_RX;
|
||||
ramreadformat.cmd = CONT_CMD_WRITE_MEMPACK;
|
||||
ramreadformat.hi = CONT_BLOCK_RUMBLE >> 3;
|
||||
ramreadformat.lo = (u8)(__osContAddressCrc(CONT_BLOCK_RUMBLE) | (CONT_BLOCK_RUMBLE << 5));
|
||||
|
||||
if (channel != 0) {
|
||||
for (i = 0; i < channel; ++i) {
|
||||
*bufptr++ = 0;
|
||||
*ptr++ = CONT_CMD_SKIP_CHNL;
|
||||
}
|
||||
}
|
||||
|
||||
*(__OSContRamHeader*)bufptr = mempakwr;
|
||||
bufptr += sizeof(mempakwr);
|
||||
*bufptr = 0xFE;
|
||||
*READFORMAT(ptr) = ramreadformat;
|
||||
ptr += sizeof(ramreadformat);
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
||||
s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel) {
|
||||
s32 ret;
|
||||
u8 sp24[BLOCKSIZE];
|
||||
u8 temp[BLOCKSIZE];
|
||||
|
||||
pfs->queue = ctrlrqueue;
|
||||
pfs->channel = channel;
|
||||
@ -78,43 +78,49 @@ s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel) {
|
||||
pfs->status = 0;
|
||||
|
||||
ret = __osPfsSelectBank(pfs, 0xFE);
|
||||
if (ret == 2) {
|
||||
if (ret == PFS_ERR_NEW_PACK) {
|
||||
ret = __osPfsSelectBank(pfs, MOTOR_ID);
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = __osContRamRead(ctrlrqueue, channel, BANK_ADDR, sp24);
|
||||
if (ret == 2) {
|
||||
ret = 4; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (sp24[BLOCKSIZE - 1] == 0xFE) {
|
||||
return 0xB;
|
||||
}
|
||||
ret = __osPfsSelectBank(pfs, MOTOR_ID);
|
||||
if (ret == 2) {
|
||||
ret = 4; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = __osContRamRead(ctrlrqueue, channel, BANK_ADDR, sp24);
|
||||
if (ret == 2) {
|
||||
ret = 4; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if (sp24[BLOCKSIZE - 1] != MOTOR_ID) {
|
||||
return 0xB;
|
||||
}
|
||||
if ((pfs->status & PFS_MOTOR_INITIALIZED) == 0) {
|
||||
_MakeMotorData(channel, &osPifBuffers[channel]);
|
||||
}
|
||||
pfs->status = PFS_MOTOR_INITIALIZED;
|
||||
|
||||
ret = __osContRamRead(ctrlrqueue, channel, CONT_BLOCK_DETECT, temp);
|
||||
if (ret == PFS_ERR_NEW_PACK) {
|
||||
ret = PFS_ERR_CONTRFAIL; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (temp[BLOCKSIZE - 1] == 0xFE) {
|
||||
return PFS_ERR_DEVICE;
|
||||
}
|
||||
|
||||
ret = __osPfsSelectBank(pfs, MOTOR_ID);
|
||||
if (ret == PFS_ERR_NEW_PACK) {
|
||||
ret = PFS_ERR_CONTRFAIL; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = __osContRamRead(ctrlrqueue, channel, CONT_BLOCK_DETECT, temp);
|
||||
if (ret == PFS_ERR_NEW_PACK) {
|
||||
ret = PFS_ERR_CONTRFAIL; // "Controller pack communication error"
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (temp[BLOCKSIZE - 1] != MOTOR_ID) {
|
||||
return PFS_ERR_DEVICE;
|
||||
}
|
||||
|
||||
if (!(pfs->status & PFS_MOTOR_INITIALIZED)) {
|
||||
_MakeMotorData(channel, &__MotorDataBuf[channel]);
|
||||
}
|
||||
|
||||
pfs->status = PFS_MOTOR_INITIALIZED;
|
||||
return 0; // "Recognized rumble pak"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
OSPifRam gPifMempakBuf;
|
||||
OSPifRam __osPfsPifRam;
|
||||
|
||||
s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel) {
|
||||
s32 ret = 0;
|
||||
@ -11,60 +11,60 @@ s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel) {
|
||||
__osPfsInodeCacheBank = 250;
|
||||
|
||||
__osPfsRequestOneChannel(channel, CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &gPifMempakBuf);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(queue, &msg, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &gPifMempakBuf);
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(queue, &msg, OS_MESG_BLOCK);
|
||||
|
||||
__osPfsGetOneChannelData(channel, &data);
|
||||
if (((data.status & CONT_CARD_ON) != 0) && ((data.status & CONT_CARD_PULL) != 0)) {
|
||||
if ((data.status & CONT_CARD_ON) && (data.status & CONT_CARD_PULL)) {
|
||||
return PFS_ERR_NEW_PACK;
|
||||
} else if (data.errno || ((data.status & CONT_CARD_ON) == 0)) {
|
||||
} else if (data.errno != 0 || !(data.status & CONT_CARD_ON)) {
|
||||
return PFS_ERR_NOPACK;
|
||||
} else if ((data.status & CONT_ADDR_CRC_ER) != 0) {
|
||||
} else if (data.status & CONT_ADDR_CRC_ER) {
|
||||
return PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPfsRequestOneChannel(s32 channel, u8 poll) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeaderAligned req;
|
||||
void __osPfsRequestOneChannel(s32 channel, u8 cmd) {
|
||||
u8* ptr;
|
||||
__OSContRequesFormatShort req;
|
||||
s32 idx;
|
||||
|
||||
__osContLastPoll = CONT_CMD_END;
|
||||
gPifMempakBuf.status = CONT_CMD_READ_BUTTON;
|
||||
__osContLastCmd = CONT_CMD_END;
|
||||
__osPfsPifRam.status = CONT_CMD_EXE;
|
||||
|
||||
bufptr = (u8*)&gPifMempakBuf;
|
||||
ptr = (u8*)&__osPfsPifRam;
|
||||
|
||||
req.txsize = 1;
|
||||
req.rxsize = 3;
|
||||
req.poll = poll;
|
||||
req.typeh = 0xFF;
|
||||
req.typel = 0xFF;
|
||||
req.status = 0xFF;
|
||||
req.txsize = CONT_CMD_REQUEST_STATUS_TX;
|
||||
req.rxsize = CONT_CMD_REQUEST_STATUS_RX;
|
||||
req.cmd = cmd;
|
||||
req.typeh = CONT_CMD_NOP;
|
||||
req.typel = CONT_CMD_NOP;
|
||||
req.status = CONT_CMD_NOP;
|
||||
|
||||
for (idx = 0; idx < channel; idx++) {
|
||||
*bufptr++ = 0;
|
||||
*ptr++ = CONT_CMD_SKIP_CHNL;
|
||||
}
|
||||
|
||||
*((__OSContRequestHeaderAligned*)bufptr) = req;
|
||||
bufptr += sizeof(req);
|
||||
*((u8*)bufptr) = CONT_CMD_END;
|
||||
*((__OSContRequesFormatShort*)ptr) = req;
|
||||
ptr += sizeof(req);
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
||||
void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData) {
|
||||
u8* bufptr = (u8*)&gPifMempakBuf;
|
||||
__OSContRequestHeaderAligned req;
|
||||
u8* ptr = (u8*)&__osPfsPifRam;
|
||||
__OSContRequesFormatShort req;
|
||||
s32 idx;
|
||||
|
||||
for (idx = 0; idx < channel; idx++) {
|
||||
bufptr++;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
req = *((__OSContRequestHeaderAligned*)bufptr);
|
||||
contData->errno = (req.rxsize & 0xC0) >> 4;
|
||||
req = *((__OSContRequesFormatShort*)ptr);
|
||||
contData->errno = CHNL_ERR(req);
|
||||
if (contData->errno) {
|
||||
return;
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) {
|
||||
do {
|
||||
__osPfsRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &gPifMempakBuf);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &gPifMempakBuf);
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
__osPfsGetInitData(&bitpattern, &contData[0]);
|
||||
@ -44,42 +44,42 @@ s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPfsRequestData(u8 poll) {
|
||||
u8* bufPtr = (u8*)&gPifMempakBuf;
|
||||
__OSContRequestHeader req;
|
||||
void __osPfsRequestData(u8 cmd) {
|
||||
u8* ptr = (u8*)&__osPfsPifRam;
|
||||
__OSContRequesFormat req;
|
||||
s32 i;
|
||||
|
||||
__osContLastPoll = poll;
|
||||
__osContLastCmd = cmd;
|
||||
|
||||
gPifMempakBuf.status = 1;
|
||||
__osPfsPifRam.status = CONT_CMD_EXE;
|
||||
|
||||
req.align = 0xFF;
|
||||
req.txsize = 1;
|
||||
req.rxsize = 3;
|
||||
req.poll = poll;
|
||||
req.typeh = 0xFF;
|
||||
req.typel = 0xFF;
|
||||
req.status = 0xFF;
|
||||
req.align1 = 0xFF;
|
||||
req.align = CONT_CMD_NOP;
|
||||
req.txsize = CONT_CMD_REQUEST_STATUS_TX;
|
||||
req.rxsize = CONT_CMD_REQUEST_STATUS_RX;
|
||||
req.cmd = cmd;
|
||||
req.typeh = CONT_CMD_NOP;
|
||||
req.typel = CONT_CMD_NOP;
|
||||
req.status = CONT_CMD_NOP;
|
||||
req.align1 = CONT_CMD_NOP;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContRequestHeader*)bufPtr) = req;
|
||||
bufPtr += sizeof(req);
|
||||
*((__OSContRequesFormat*)ptr) = req;
|
||||
ptr += sizeof(req);
|
||||
}
|
||||
*((u8*)bufPtr) = CONT_CMD_END;
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
||||
void __osPfsGetInitData(u8* pattern, OSContStatus* contData) {
|
||||
u8* bufptr;
|
||||
__OSContRequestHeader req;
|
||||
u8* ptr;
|
||||
__OSContRequesFormat req;
|
||||
s32 i;
|
||||
u8 bits = 0;
|
||||
|
||||
bufptr = (u8*)&gPifMempakBuf;
|
||||
ptr = (u8*)&__osPfsPifRam;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(req), contData++) {
|
||||
req = *((__OSContRequestHeader*)bufptr);
|
||||
contData->errno = ((req.rxsize & 0xC0) >> 4);
|
||||
for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(req), contData++) {
|
||||
req = *((__OSContRequesFormat*)ptr);
|
||||
contData->errno = CHNL_ERR(req);
|
||||
|
||||
if (contData->errno) {
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user