diff --git a/include/ultra64/controller.h b/include/ultra64/controller.h index 3b92328127..313809bf64 100644 --- a/include/ultra64/controller.h +++ b/include/ultra64/controller.h @@ -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 diff --git a/include/ultra64/pfs.h b/include/ultra64/pfs.h index 730c224b8b..019f29350c 100644 --- a/include/ultra64/pfs.h +++ b/include/ultra64/pfs.h @@ -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]; diff --git a/include/variables.h b/include/variables.h index b7c2ea48b8..2e39bdf97e 100644 --- a/include/variables.h +++ b/include/variables.h @@ -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 diff --git a/src/libultra/io/contpfs.c b/src/libultra/io/contpfs.c index a343bf0bc6..026237a802 100644 --- a/src/libultra/io/contpfs.c +++ b/src/libultra/io/contpfs.c @@ -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); } } diff --git a/src/libultra/io/contquery.c b/src/libultra/io/contquery.c index 21cb884d46..660e2dcd42 100644 --- a/src/libultra/io/contquery.c +++ b/src/libultra/io/contquery.c @@ -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; } diff --git a/src/libultra/io/contramread.c b/src/libultra/io/contramread.c index 97d5db651c..058f58e80f 100644 --- a/src/libultra/io/contramread.c +++ b/src/libultra/io/contramread.c @@ -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 diff --git a/src/libultra/io/contramwrite.c b/src/libultra/io/contramwrite.c index d8fb594e95..6a776a13b8 100644 --- a/src/libultra/io/contramwrite.c +++ b/src/libultra/io/contramwrite.c @@ -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 { diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c index a85a3337bd..ff44bc15b8 100644 --- a/src/libultra/io/contreaddata.c +++ b/src/libultra/io/contreaddata.c @@ -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; } diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c index bb13787ed3..290f1b5854 100644 --- a/src/libultra/io/controller.c +++ b/src/libultra/io/controller.c @@ -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; } diff --git a/src/libultra/io/contsetch.c b/src/libultra/io/contsetch.c index 0e7502b0cf..feab63cdb4 100644 --- a/src/libultra/io/contsetch.c +++ b/src/libultra/io/contsetch.c @@ -15,7 +15,7 @@ s32 osContSetCh(u8 ch) { __osMaxControllers = ch; } - __osContLastPoll = -2; + __osContLastCmd = CONT_CMD_END; __osSiRelAccess(); return 0; } diff --git a/src/libultra/io/motor.c b/src/libultra/io/motor.c index 5b5abb9e12..b63dd38f51 100644 --- a/src/libultra/io/motor.c +++ b/src/libultra/io/motor.c @@ -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" } diff --git a/src/libultra/io/pfsgetstatus.c b/src/libultra/io/pfsgetstatus.c index 3a1e962a2e..c0b05e45e4 100644 --- a/src/libultra/io/pfsgetstatus.c +++ b/src/libultra/io/pfsgetstatus.c @@ -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; } diff --git a/src/libultra/io/pfsisplug.c b/src/libultra/io/pfsisplug.c index a1b73cf8e7..dd51933752 100644 --- a/src/libultra/io/pfsisplug.c +++ b/src/libultra/io/pfsisplug.c @@ -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;