diff options
Diffstat (limited to 'lib/ultralib/include/PRinternal/controller.h')
| -rw-r--r-- | lib/ultralib/include/PRinternal/controller.h | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/lib/ultralib/include/PRinternal/controller.h b/lib/ultralib/include/PRinternal/controller.h new file mode 100644 index 0000000..e77b38e --- /dev/null +++ b/lib/ultralib/include/PRinternal/controller.h @@ -0,0 +1,289 @@ +#ifndef _CONTROLLER_H +#define _CONTROLLER_H + +#include "PR/os_internal.h" +#include "PR/os_version.h" +#include "PR/rcp.h" + +#include "PRinternal/macros.h" + +#define CHNL_ERR(format) (((format).rxsize & CHNL_ERR_MASK) >> 4) + +typedef struct +{ + /* 0x0 */ u32 ramarray[15]; + /* 0x3C */ u32 pifstatus; +} OSPifRam ALIGNED(0x10); + +typedef struct +{ + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; + /* 0x4 */ u16 button; + /* 0x6 */ s8 stick_x; + /* 0x7 */ s8 stick_y; +} __OSContReadFormat; + +typedef struct +{ + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; + /* 0x4 */ u8 typeh; + /* 0x5 */ u8 typel; + /* 0x6 */ u8 status; + /* 0x7 */ u8 dummy1; +} __OSContRequesFormat; + +typedef struct +{ + /* 0x0 */ u8 txsize; + /* 0x1 */ u8 rxsize; + /* 0x2 */ u8 cmd; + /* 0x3 */ u8 typeh; + /* 0x4 */ u8 typel; + /* 0x5 */ u8 status; +} __OSContRequesFormatShort; + +typedef struct +{ + /* 0x0 */ u8 dummy; + /* 0x1 */ u8 txsize; + /* 0x2 */ u8 rxsize; + /* 0x3 */ u8 cmd; +#if BUILD_VERSION >= VERSION_J + /* 0x4 */ u8 addrh; + /* 0x5 */ u8 addrl; +#else + /* 0x4 */ u16 address; +#endif + /* 0x6 */ u8 data[BLOCKSIZE]; + /* 0x26 */ u8 datacrc; +} __OSContRamReadFormat; + +typedef union { + /* 0x0 */ struct + { + /* 0x0 */ u8 bank; + /* 0x1 */ u8 page; + } inode_t; + /* 0x0 */ u16 ipage; +} __OSInodeUnit; + +typedef struct +{ + /* 0x0 */ u32 game_code; + /* 0x4 */ u16 company_code; + /* 0x6 */ __OSInodeUnit start_page; + /* 0x8 */ u8 status; + /* 0x9 */ s8 reserved; + /* 0xA */ u16 data_sum; + /* 0xC */ u8 ext_name[PFS_FILE_EXT_LEN]; + /* 0x10 */ u8 game_name[PFS_FILE_NAME_LEN]; +} __OSDir; + +typedef struct +{ + /* 0x0 */ __OSInodeUnit inode_page[128]; +} __OSInode; + +typedef struct +{ + /* 0x0 */ u32 repaired; + /* 0x4 */ u32 random; + /* 0x8 */ u64 serial_mid; + /* 0x10 */ u64 serial_low; + /* 0x18 */ u16 deviceid; + /* 0x1A */ u8 banks; + /* 0x1B */ u8 version; + /* 0x1C */ u16 checksum; + /* 0x1E */ u16 inverted_checksum; +} __OSPackId; + +typedef struct +{ + /* 0x0 */ u8 txsize; + /* 0x1 */ u8 rxsize; + /* 0x2 */ u8 cmd; + /* 0x3 */ u8 address; + /* 0x4 */ u8 data[EEPROM_BLOCK_SIZE]; +} __OSContEepromFormat; + +// Joybus commands +//from: http://en64.shoutwiki.com/wiki/SI_Registers_Detailed#CONT_CMD_Usage +#define CONT_CMD_REQUEST_STATUS 0 +#define CONT_CMD_READ_BUTTON 1 +#define CONT_CMD_READ_PAK 2 +#define CONT_CMD_WRITE_PAK 3 +#define CONT_CMD_READ_EEPROM 4 +#define CONT_CMD_WRITE_EEPROM 5 +#define CONT_CMD_READ36_VOICE 9 +#define CONT_CMD_WRITE20_VOICE 10 +#define CONT_CMD_READ2_VOICE 11 +#define CONT_CMD_WRITE4_VOICE 12 +#define CONT_CMD_SWRITE_VOICE 13 +#define CONT_CMD_CHANNEL_RESET 0xFD +#define CONT_CMD_RESET 0xFF + +// Bytes transmitted for each joybus command +#define CONT_CMD_REQUEST_STATUS_TX 1 +#define CONT_CMD_READ_BUTTON_TX 1 +#define CONT_CMD_READ_PAK_TX 3 +#define CONT_CMD_WRITE_PAK_TX 35 +#define CONT_CMD_READ_EEPROM_TX 2 +#define CONT_CMD_WRITE_EEPROM_TX 10 +#define CONT_CMD_READ36_VOICE_TX 3 +#define CONT_CMD_WRITE20_VOICE_TX 23 +#define CONT_CMD_READ2_VOICE_TX 3 +#define CONT_CMD_WRITE4_VOICE_TX 7 +#define CONT_CMD_SWRITE_VOICE_TX 3 +#define CONT_CMD_RESET_TX 1 + +// Bytes received for each joybus command +#define CONT_CMD_REQUEST_STATUS_RX 3 +#define CONT_CMD_READ_BUTTON_RX 4 +#define CONT_CMD_READ_PAK_RX 33 +#define CONT_CMD_WRITE_PAK_RX 1 +#define CONT_CMD_READ_EEPROM_RX 8 +#define CONT_CMD_WRITE_EEPROM_RX 1 +#define CONT_CMD_READ36_VOICE_RX 37 +#define CONT_CMD_WRITE20_VOICE_RX 1 +#define CONT_CMD_READ2_VOICE_RX 3 +#define CONT_CMD_WRITE4_VOICE_RX 1 +#define CONT_CMD_SWRITE_VOICE_RX 1 +#define CONT_CMD_RESET_RX 3 + +#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 DIR_STATUS_EMPTY 0 +#define DIR_STATUS_UNKNOWN 1 +#define DIR_STATUS_OCCUPIED 2 + +// Controller accessory addresses +// https://github.com/joeldipops/TransferBoy/blob/master/docs/TransferPakReference.md + +// Accesory 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) + + +// Transfer pak + +#define GB_POWER_ON 0x84 +#define GB_POWER_OFF 0xFE + + +typedef struct +{ + /* 0x0 */ __OSInode inode; + /* 0x100 */ u8 bank; + /* 0x101 */ u8 map[PFS_INODE_DIST_MAP]; +} __OSInodeCache; + +extern s32 __osEepStatus(OSMesgQueue *, OSContStatus *); +u16 __osSumcalc(u8 *ptr, int length); +s32 __osIdCheckSum(u16 *ptr, u16 *csum, u16 *icsum); +s32 __osRepairPackId(OSPfs *pfs, __OSPackId *badid, __OSPackId *newid); +s32 __osCheckPackId(OSPfs *pfs, __OSPackId *temp); +s32 __osGetId(OSPfs *pfs); +s32 __osCheckId(OSPfs *pfs); +s32 __osPfsRWInode(OSPfs *pfs, __OSInode *inode, u8 flag, u8 bank); +#if BUILD_VERSION >= VERSION_J +s32 __osPfsSelectBank(OSPfs *pfs, u8 bank); +#else +s32 __osPfsSelectBank(OSPfs *pfs); +#endif +s32 __osPfsDeclearPage(OSPfs *pfs, __OSInode *inode, int file_size_in_pages, int *first_page, u8 bank, int *decleared, int *last_page); +#if BUILD_VERSION >= VERSION_J +s32 __osPfsReleasePages(OSPfs *pfs, __OSInode *inode, u8 start_page, u8 bank, __OSInodeUnit *last_page); +#else +s32 __osPfsReleasePages(OSPfs *pfs, __OSInode *inode, u8 start_page, u16 *sum, u8 bank, __OSInodeUnit *last_page, int flag); +#endif +s32 __osBlockSum(OSPfs *pfs, u8 page_no, u16 *sum, u8 bank); +s32 __osContRamRead(OSMesgQueue *mq, int channel, u16 address, u8 *buffer); +s32 __osContRamWrite(OSMesgQueue *mq, int channel, u16 address, u8 *buffer, int force); +void __osContGetInitData(u8 *pattern, OSContStatus *data); +void __osPackRequestData(u8 cmd); +void __osPfsRequestData(u8 cmd); +void __osPfsGetInitData(u8* pattern, OSContStatus* data); +u8 __osContAddressCrc(u16 addr); +u8 __osContDataCrc(u8 *data); +s32 __osPfsGetStatus(OSMesgQueue *queue, int channel); + +extern u8 __osContLastCmd; +extern OSTimer __osEepromTimer; +extern OSMesg __osEepromTimerMsg; +extern OSMesgQueue __osEepromTimerQ; +extern OSPifRam __osEepPifRam; +extern OSPifRam __osContPifRam; +extern OSPifRam __osPfsPifRam; +extern u8 __osMaxControllers; + +//some version of this almost certainly existed since there's plenty of times where it's used right before a return 0 +#define ERRCK(fn) \ + ret = fn; \ + if (ret != 0) \ + return ret + +#if BUILD_VERSION >= VERSION_J + +#define SELECT_BANK(pfs, bank) \ + __osPfsSelectBank((pfs), (bank)) + +#define SET_ACTIVEBANK_TO_ZERO() \ + if (pfs->activebank != 0) \ + { \ + ERRCK(__osPfsSelectBank(pfs, 0)); \ + } (void)0 + +#else + +#define SELECT_BANK(pfs, bank) \ + (pfs->activebank = (bank), __osPfsSelectBank((pfs))) + +#define SET_ACTIVEBANK_TO_ZERO() \ + if (pfs->activebank != 0) \ + { \ + pfs->activebank = 0; \ + ERRCK(__osPfsSelectBank(pfs)); \ + } (void)0 + +#endif + +#define PFS_CHECK_ID() \ + if (__osCheckId(pfs) == PFS_ERR_NEW_PACK) \ + return PFS_ERR_NEW_PACK + +#define PFS_CHECK_STATUS() \ + if ((pfs->status & PFS_INITIALIZED) == 0) \ + return PFS_ERR_INVALID + +#define PFS_GET_STATUS() \ + __osSiGetAccess(); \ + ret = __osPfsGetStatus(queue, channel); \ + __osSiRelAccess(); \ + if (ret != 0) \ + return ret + +#endif |
