Some notes about the USB: It is very hard to synchronize the USB link properly. There are 2 ways to transfer something:
* transfer without waiting: This is easy, just use USB_SendData and USB_ReceiveData. There are no host/client considerations here, the routines work for both sides. But they only wait up to some fixed timeout in the seconds range. This probably works fine for games which continuously transfer something (such as Ice Hockey 68k), but for turn-based games such as Backgammon, the receiving calculator will time out while waiting for input from the sending calculator.
* transfer with waiting: This gets tricky. For the waiting, DetectReceiveInterface(FALSE); has to be used on the receiving side and DetectUSB(); on the sending side (and then you use USB_SendData and USB_RecvData just as in the non-waiting case), but you need to reset the USB link before switching sides. See the notes about DetectReceiveInterface below.
Note that resetting the link and detecting it all over again takes some time, so you should avoid it when there is nothing to actually wait for. And worse, waiting where there is no real wait might even cause synchronization issues. So make sure you use waiting if and only if there is something to wait for.
Here's the preliminary documentation of the routines:
unsigned char DetectLinkInterface(void); (0x8d2572)Detects if the USB link is usable. Returns 1 (USB preferred) if it is and 2(legacy DBus IO preferred) if it isn't. This routine uses DetectUSB first,and then runs a complex test transfer to double-check. This test transferneeds to be handled on the receiving side as well, so it is usually easierto just use DetectUSB.short DetectUSB(void); (0x94a174)Quickly detects if the USB link is usable. Returns 0 if USB is available,or a non-zero error code if it isn't.unsigned char DetectReceiveInterface(short allowLIO); (0x8d25a4)Waits for a calculator to connect on either the USB or the LIO interface.Returns:* 0 if something is detected on the USB link.* 2 if allowLIO is non-zero, nothing is detected on the USB link and something is detected on the LIO link.* 3 if interrupted by the user ([ON] key).If you want to wait for something to be received on the USB link,DetectReceiveInterface(FALSE) is the function to use, but there's a catch:only one calculator can use DetectReceiveInterface for each transfer. (USB isa host/client protocol.) You absolutely MUST call USBReset on both calculatorsbefore using DetectReceiveInterface on the other calculator. This is very muchunlike the LIO interface, which is peer-to-peer. Also, the other calculatorMUST call DetectUSB to synchronize with a DetectReceiveInterface call. To sumup, for a transfer which is synchronized by the sender (such as a move in aturn-based game), the sending calculator should call: USBLinkClose();USBLinkReset(); DetectUSB(); USB_SendData(src,size,2000);, the receivingcalculator should call: USBLinkClose(); USBLinkReset();DetectReceiveInterface(FALSE); USB_RecvData(src,size,2000);.short USB_SendData(const void *buffer, size_t size, long timeout); (0x949b86)Sends size bytes from buffer over the USB link. For "timeout", try 2000. (Iam not sure this is actually a timeout. AMS always uses 2000, so you shoulddo the same.) Returns 0 if successful, some non-0 error code otherwise.short USB_RecvData(void *buffer, size_t size, long timeout); (0x949c7e)Receives size bytes into buffer from the USB link. For "timeout", try 2000. (Iam not sure this is actually a timeout. AMS always uses 2000, so you shoulddo the same.) Returns 0 if successful, some non-0 error code otherwise.short USBLinkClose(void); (0x949c6a)This function is used by AMS to finalize a file transfer.Returns 0 if successful, some non-0 error code otherwise.void USBLinkReset(void); (0x94a284)This function closes and resets the USB link. It is used by AMS when done withan USB transfer, and sometimes also before initiating one. You should alwayscall this function when done with a transfer.and their current definition:
#define XR_stringPtr_addr (_rom_call_addr(293))#define IsSupportedAMS300() (*(long long*)(XR_stringPtr_addr-116)\==0x76021003261f4e75ll)#define DetectLinkInterface ((unsigned char(*)(void))(XR_stringPtr_addr-158))#define DetectReceiveInterface ((unsigned char(*)(short))(XR_stringPtr_addr\-108))#define DetectUSB (*(short(**)(void))(DetectLinkInterface+4))#define USB_SendData ((short (*)(const void *, size_t, long))(DetectUSB-1518))#define USB_RecvData ((short (*)(void *, size_t, long))(DetectUSB-1270))#define USBLinkClose ((short(*)(void))(DetectUSB-1290))#define USBLinkReset (*(void(**)(void))(DetectLinkInterface+36))
