Libcyc.a Library Functions v2.0 16/06/99 Copyright(C)1999 Peter Armstrong /------- File Server & Block Transfer Functions -------/ -------- Read in a data block from a second playstation int block_read(int id, char **buf, int size) id data block identifier, application specific **buf a pointer either to a pointer containing the read buffer address, or a ptr used to store the malloc() return value size size of block to read, if zero ignore size, if -1, use malloc() to allocate block storage space Return value >0 - number of bytes read and stored 0 (B_CNT_ERROR) - not connected to second playstation (via link cable) -1 (B_TIMEOUT) - comms error, no response -2 (B_CMD_MISMATCH) - read command not matched by write command -3 (B_ID_MISMATCH) - block identifiers not the same -4 (B_SIZE_MISMATCH) - size of block not the same as 'size' -5 (B_MEM_FAIL) - unable to allocate block space Currently, block transfers are only possible between playstations connected via a link cable. If the buffer space is dynamically allocated it's the responsibility of the application to free() it when it's no longer required. Block transfers between playstations are approximately six times faster than file data transfers between PC and playstation. Examples Read in a data block, id number 5, 20,000 bytes in size, store at address pointed to by buffer_p. char *buffer_p = (char *)0x80140000; block_size = block_read(5,&buffer_p,20000); Read in a data block, id number 9, do not check data size, store at address pointed to by the pointer stored in buf_2ptr; char *buffer_p = (char *)0x80140000; char **buf_2ptr = &buffer_p; block_size = block_read(9,buf_2ptr,0); Read in a data block, id number 1, have the storage memory for the buffer dynamically allocated using malloc(). char *buffer; block_size = block_read(1,&buffer,-1); . . . free(buffer); /* free memory when finished with */ ------- -------- Write a data block to a second playstation int block_write(int id, char *buf, int size) id data block identifier, application specific *buf pointer to block to send size size of block, number of bytes to write Return value >0 - number of bytes written 0 (B_CNT_ERROR) - not connected to second playstation (via link cable) -1 (B_TIMEOUT) - comms error, no response -2 (B_CMD_MISMATCH) - write command not matched by read command -3 (B_ID_MISMATCH) - block identifiers not the same -4 (B_SIZE_MISMATCH) - block size mismatch on other playstation -5 (B_MEM_FAIL) - malloc() failure on other playstation Currently, block transfers are only possible between playstations connected via a link cable. Example Send a data block, id number 5, 20,000 bytes in size, block start address pointed to by buffer_p: char *buffer_p = (char *)0x80140000; bytes_sent = block_write(5,buffer_p,20000); ------- ------- Close a PC file int cyc_close(int fd); fd file descriptor Return value Zero if the file is closed, -1 if an error occurred. -2 is returned if there's a comms error. The file descriptor belongs to a file previously opened with cyc_creat() or cyc_open(). -------- -------- Create and open a new file on the PC int cyc_creat(char *fname, int pmode); fname path/name of file to open, 96 characters max pmode permission mode, file's access setting pmode macros C_IREAD read only C_IWRITE write only C_IRDWR read/write Return value The associated file descriptor, or -1 if the file cannot be opened. -2 is returned if there's a comms error. Creating a new file will erase an existing file with the same name. Newly created files must be closed immediately after their creation. Example Create a new file in the current directory, that can be read and written to: if((fd = cyc_creat("psxmem.dat", C_IRDWR) != -1) cyc_close(fd); /* close immediately */ -------- -------- Test for end of file int cyc_eof(int fd); fd file desciptor Return value 1 is returned if at end of file, 0 if not. -1 is returned if an error has occurred. -2 will be returned if there's a comms error. -------- -------- Start search for PC file int cyc_findfirst(char *fname, int attr, struct c_find *ptr) *fname file name to search for, * and ? acceptable wildcards attr file attributes to search for *ptr pointer to structure storing file information attr macros CA_NORMAL ordinary file, no attributes CA_RDONLY read-only CA_HIDDEN hidden file CA_SYSTEM system file CA_VOLID volume label CA_SUBDIR directory CA_ARCH archive bit set Return value Zero is returned if a matching file is found, and the c_find structure will contain the following information: ptr->attrib attribute bits set for file (CA_ macro values) ptr->wr_time time file was last written to, 16 bit value encoded as:- bits 0-4 seconds/2(0-29) 5-10 minutes(0-59) 11-15 hours(0-23) ptr->wr_date date file was last written to, 16 bit value encoded as- bits 0-4 day(1-31) 5-8 month(1-12) 9-15 years from 1980 ptr->size file size in bytes ptr->name file name in dos 8.3 format A value greater than zero is returned if there is an error or the file cannot be found, and -2 is returned if there's a comms error. Always check the attributes of the file being returned, the function may return files with more attributes set than is specified. Fot instance, CA_NORMAL returns CA_NORMAL files and also files with only their CA_ARCH or CA_RDONLY bits set. CA_SUBDIR returns CA_NORMAL files and files/directories with only CA_ARCH, CA_RDONLY, or CA_SUBDIR bits set. Examples Start search for all files in the current directory with normal attributes: struct c_find f; rtn_val = cyc_findfirst("*.*",CA_NORMAL,&f); Start search for tim files in the current directory with normal or hidden attributes: rtn_val = cyc_findfirst("*.tim",CA_NORMAL | CA_HIDDEN,&f); Start search for files matching '*.dat' in the 'memcard' directory, normal attributes: rtn_val = cyc_findfirst("memcard/*.dat",CA_NORMAL,&f); Start search for directories in the current directory: if(!cyc_findfirst("*.*",CA_SUBDIR,&f)) /* zero equals success */ { if(f.attrib & CA_SUBDIR) { /* directory found */ } } -------- -------- Continue search for PC files int cyc_findnext(struct c_find *ptr) *ptr pointer to structure storing file information Return value Zero is returned if another file is found that matches the parameters specified in the previous call to cyc_readnext(). See the description of cyc_findfirst above for details of the file information returned in the c_find *ptr structure. A value greater than zero is returned if there is an error or no more matching files can be found, -2 is returned if there's a comms error. Each call to cyc_findnext() retrieves the file information belonging to the next file in the directory that matches the parameters specified in the previous call to cyc_findfirst(). Example Read in the information for up to the first ten tim files in the current directory: struct c_find find[10]; struct c_find *find_p = find; if(!cyc_findfirst("*.tim",CA_NORMAL,find_p++)) { for(i = 1, i < 10; i++) { if(cyc_findnext(find_p++)) break; } } -------- -------- Read the attributes of a PC file int cyc_getfileattr(char *fname, u_int *attrib); *fname name of file *attrib pointer to attribute storage Return value Zero is returned if successful, with the value of attrib corresponding to one or more of the following: CA_NORMAL ordinary file, no attributes CA_RDONLY read-only CA_HIDDEN hidden file CA_SYSTEM system file CA_VOLID volume label CA_SUBDIR directory CA_ARCH archive bit set A value greater than zero is returned if the file cannot be found, -2 is returned if there is a comms error. Example Get the file attributes of the file data.dat: u_int attribs; if(!cyc_getfileattr("data.dat",&attribs)) { /* attributes stored */ } -------- -------- Move the file position indicator, set the position for the start of a read or write. long cyc_lseek(int fd, int offset, int origin); fd file descriptor offset offset from origin in bytes origin either the start,end or current file position origin macros C_SEEK_SET start of file C_SEEK_CUR current file position C_SEEK_END end of file Return value The new file position, which is the number of bytes from the start of the file. -1 is returned on failure. -2 is returned if there's a comms error. Examples Move the file position indicator to the end of the file, thus returning the file's size: file_size = cyc_lseek(fd, 0, C_SEEK_END); Move file position indicator to 100 bytes before current position: file_pos = cyc_lseek(fd,-100,C_SEEK_CUR); -------- -------- Open a file on the PC int cyc_open(char *fname, int mode); fname path/name of file to open mode open mode mode macros C_RDONLY read only C_WRONLY write only C_RDWR read/write C_CREAT create and open file C_TRUNC open with truncation C_EXCL open only if non-existant C_APPEND append data to end of file C_BINARY binary file types C_TEXT text files Return value The associated file descriptor, -1 upon failure. -2 is returned if there's a comms error. Example Open for reading/writing picture.tim, located in the tims directory: fd = cyc_open("tims/picture.tim",C_RDWR | C_BINARY); -------- -------- Prints formatted string output on the PC monitor int cyc_printf(char *format_str,....) format_str printf format string ... variable number of arguments passed to function Return value The number of characters printed. cyc_printf() works in the same way as the standard printf function, except floating point numbers, %n and %% are not supported. -------- -------- Read data from a PC file int cyc_read(int fd,char *buf,u_int num); fd file descriptor buf read buffer address num number of bytes to read Return value The number of bytes read, which may be less than 'num' if end of file was reached, -1 is returned if an error occurred. -2 is returned if there's a comms error, and -3 is returned if buffer space cannot be allocated. Example Read 10k bytes from file to playstation memory: read_num = cyc_read(fd, (u_char *)0x80140000, 10240); -------- -------- Set the attributes of a PC file int cyc_setfileattr(char *fname, u_int attrib); *fname name of file attrib attribute bits to set, which are one or more of the following: attrib macros CA_NORMAL ordinary file, no attributes CA_RDONLY read-only CA_HIDDEN hidden file CA_SYSTEM system file CA_VOLID volume label CA_SUBDIR directory CA_ARCH archive bit Return value Zero is returned if successful, a value greater than zero is returned if the file could not be accessed (not found or access denied), -2 is returned if there is a comms error. Example Make the file data.dat read-only, keep any other attributes that are already set: u_int attribs; if(!cyc_getfileattr("data.dat",&attribs)) /* get original attributes */ { if(!cyc_setfileattr("data.dat",attribs | CA_RDONLY)) { /* file is now read-only */ } } -------- -------- Send a command to the PC's command processor int cyc_system(char *cmd); cmd command to be executed, 96 characters max Return value Zero if successful, -1 if the command cannot be processed, -2 if there's a comms error. Example Create a directory called 'tims' within the current directory: cyc_system("md tims"); Clear the PC screen: cyc_system("cls"); -------- -------- Receive the current value of the file's in-file position indicator long cyc_tell(int fd); fd file descriptor Return value The current file position, which is the number of bytes from the start of the file. -1 is returned on failure. -2 is returned if there's a comms error. Example file_pos = cyc_tell(fd); -------- -------- Delete a file on the PC int cyc_unlink(char *fname); fname path/name of file to be deleted, 96 characters max Return value Zero if successful, -1 if the file cannot be closed. -2 is returned if there's a comms error. Example Delete the file picture.tim in the tims directory: rtn = cyc_unlink("tims/picture.tim"); -------- -------- Write data to a PC file int cyc_write(int fd,char *buf,u_int num); fd file descriptor buf write data address num number of bytes to write Return value The number of bytes written, which may be less if an error occurred. -1 is returned if a fundamental error occurs. -2 is returned if there's a comms error. Example Write 5000 bytes to file from playstation memory: write_num = cyc_write(fd, (u_char *)buffer_p, 5000); -------- /--------------------------------------/ /------ Miscellaneous Functions ------/ -------- Send notification to the PC and/or other playstation that this playstation is about to exit void cyc_exit(void); Return value 1 - exit command received by PC/other playstation 0 - cannot send command, not connected to PC or another playstation -1 - comms error, no response -------- -------- Test connection type int cyc_ping(void); Return value 1 (PNG_PC) connected to PC file server 0 (PNG_PSX) connected to another playstation -1 (PNG_NG) not currently connected to another playstation The return value of cyc_ping() is also stored in the main link structure as link.ping. cyc_ping is called automatically within sio_open(), if a PC connection is not found an eventual psx-to-psx connection is assumed and the port baud rate increased. -------- -------- Chain application's VSyncCallback function to library's own callback function void chain_callback(void (*func)()) *func application's callback function Return value None. Call chain_callback(NULL) to clear the callback function. -------- -------- Close the playstation's serial port void sio_close(void); Return value None. Closes the serial port previously opened by sio_open(). The library's vsync callback function is also freed. -------- -------- Open and initialize the playstation's serial port int sio_open(void); Return value 1 if successful, zero upon failure. The library's vsync callback function, vsync timer values and the connection type are also initialized within this function. -------- /-------------------------------------/ /------ Connection and Packet Transfer Functions -----/ -------- Create a connection to a second playstation struct link *link_connect(volatile char *padbuf); *padbuf pointer to controller buffer Return value address of link structure always returned, the following fields should be checked: link_p->loc_status: 1(I_CONNECTED) - connection established 0(I_USER_INT) - connection attempt cancelled by user -1(I_CNT_FAIL) - a connection could not be established if connection established: link_p->connected = 1(I_CONNECTED) link_p->lk_type, the connection type 2(LK_MODEM) - PC modem connection to remote playstation 1(LK_PC) - 2 psx's connected to one PC 0(LK_PSX) - direct psx-to-psx connection via a link cable link_p->m_state, master or slave status of playstation 3(MASTER) - master 2(SLAVE) - slave Example link_p = pkt_connect(NULL); if(link_p->connected) /* connection made */ -------- -------- Break connection to second playstation void link_disconnect(void); Return value None. -------- -------- End packet transfer session void pkt_end(void); Return value None. pkt_end() ends the transfer session by sending an end_transfer packet to the other playstation, and returns when the remote has done the same, or the connection has been broken. -------- -------- Start packet transfer session int pkt_start(u_int size, int mode); size number of bytes to transfer per frame, 6 max mode transfer mode type mode macros P_TFR_REAL 0 transfer packets for real P_TFR_TEST 1 test transfer Return value 1 (S_READY) - session started 0 (S_NOT_CONNECTED) - not connected -1 (S_START_FAIL) - mismatch in data size or transfer failed -2 (S_BAD_SIZE) - data 'size' out of range -3 (S_MEM_FAIL) - malloc failure Test transfers can only be run when the playstation is connected to the PC. An error will be reported if a test transfer is attempted when a PC modem connection has been made. Example Start a test transfer session, with a packet data size of 6 bytes: if(pkt_start(6, P_TFR_TEST) == S_READY) { // transfer session started } -------- -------- Send and receive packet frame data within a transfer session int pkt_transfer(u_char *data_p); data_p pointer to data to be sent Return value 1 (T_DATA_AVAIL) - local and remote data is available for the next game frame 0 (T_NO_DATA) - no (remote) data available -1 (T_TFR_ENDED) - remote psx is ending transfer session -2 (T_TIMEOUT) - a timeout occurred, no packets being received from remote psx If pkt_transfer returned 1, the pointers link_p->loc_data and link_p->rem_data point to the local and remote data for the next frame. The number of data bytes stored depends on the value of 'size' in the call to pkt_start(). Example Call pkt_transfer(), if successful store the local and remote frame data, if not test remote status, link_p is a pointer to the main link structure, returned by link_connect(): #define SIZE 2 u_short locdata,remdata; u_char *loc_p = &locdata; u_char *rem_p = &remdata; // start transfer, 2 bytes of data sent/received per frame if(pkt_start(SIZE,P_TFR_REAL) == S_READY) . . . // send/receive data if((t_status = pkt_transfer((u_char *)&local_data_long)) { if(t_status == T_DATA_AVAIL) { // local & remote frame data received for(i = 0; i < SIZE; i++) { loc_p[i] = link_p->loc_data[i]; ren_p[i] = link_p->rem_data[i]; } } else { if(t_status < 0) pkt_end(); // end of transfer } } -------- /-------------------------------------/