summaryrefslogtreecommitdiff
path: root/lib/ultralib/include/PRinternal/controller.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ultralib/include/PRinternal/controller.h')
-rw-r--r--lib/ultralib/include/PRinternal/controller.h289
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