// // Action Replay FileServer // // (C)1997,by Craig Graham // #include #include #include #include #include #include #include "ansicons.h" // Defaults // maximum number of files open at once #define MAX_SERV_HANDLES 10 // io port for the action replay card - can be set at runtime with the /I switch, this is just a default #define DEFAULT_IOPORT 0x320 // IO port access for Win95/DOS using Visual C++ #define inp(x) ((unsigned char)_inp((unsigned short)(x))) #define outp _outp typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned long ulong; unsigned short io_port=0x320; // 0x300 short quiet_mode=0,connected=0,stat=0; jmp_buf recovery_jump; unsigned char *fbuffer; // pointer to a buffer used for file io FILE *serv_handles[MAX_SERV_HANDLES+1]; // file handles we have available/used long last_file_pos[MAX_SERV_HANDLES+1]; // used for retry on a read short activity=0,act_t=1; char *status_chars="SDLOCR"; void DisplayStatusLine(void) { SetTextColour(CON_FYELLOW); SetTextColour(CON_BBLUE); printf("\033[s"); SetTextXY(0,0); printf("AR FileServer For Playstation | IOPORT=%3x | quiet=",io_port); if(quiet_mode) printf("ON "); else printf("OFF"); if(connected) printf(" | online"); else printf(" | "); printf(" | status:%c ",status_chars[stat]); SetTextColour(CON_FWHITE); SetTextColour(CON_BBLACK); printf("\033[u"); } void BaseCheckForEsape(void) { char key; if (kbhit()) { key=getch(); if(key=0x1B) { printf("ABORTED!\n"); exit(-1); } } } void ResetPSX(void) { char data; // outp(io_port, 0x69); outp(io_port, 0x69); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0x6E); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0x14); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0xbf); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0xc0); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0); while(inp(io_port+2) & 0x01) BaseCheckForEsape(); data=inp(io_port); outp(io_port, 0); connected=0; } void CheckForEscape(void) { char key; if (kbhit()) { key=getch(); switch(key) { case 0x1B: printf("ABORTED!\n"); exit(-1); break; case 'r': case 'R': SetTextColour(CON_FRED); printf("**REBOOT\n"); DisplayStatusLine(); ResetPSX(); longjmp(recovery_jump,'r'); break; } } } unsigned char read_byte(void) { if((act_t)&&(((activity++)&0x1ff)==0)) { printf("\033[s"); SetTextXY(77,0); SetTextColour(CON_FGREEN); SetTextColour(CON_BBLUE); if(activity&0x200) { printf("I"); }else{ printf(" "); } printf("\033[u"); SetTextColour(CON_FWHITE); SetTextColour(CON_BBLACK); } while(inp(io_port+2) & 0x01) CheckForEscape(); return inp(io_port); } // Send long void ServSendLong(long v) { long temp; char data; temp=v>>24; outp(io_port, temp&0xff); data=read_byte(); temp=v>>16; outp(io_port, temp&0xff); data=read_byte(); temp=v>>8; outp(io_port, temp&0xff); data=read_byte(); outp(io_port, v&0xff); data=read_byte(); } void diags(void) { char data; // Send ACK for printing outp(io_port, 'p'); // Skip first byte data=read_byte(); SetTextColour(CON_FWHITE); // Get text string do{ outp(io_port, 'p'); data=read_byte(); if(data) printf("%c",data); }while(data); DisplayStatusLine(); } void serv_close_all_files(void) { short f; for(f=0; fMAX_SERV_HANDLES)||(serv_handles[file_handle_index]==NULL)) { SetTextColour(CON_FRED); printf("**SERV_READ:INVALID FILE HANDLE[%d]\n"); DisplayStatusLine(); ServSendLong(-1); return; } // Get read length outp(io_port, 'z'); temp=read_byte(); read_len=temp<<24; outp(io_port, 'z'); temp=read_byte(); read_len|=temp<<16; outp(io_port, 'z'); temp=read_byte(); read_len|=temp<<8; outp(io_port, 'z'); temp=read_byte(); read_len|=temp; last_file_pos[file_handle_index]=ftell(serv_handles[file_handle_index]); // Read file into buffer temp=read_len; read_len=fread((void*)fbuffer, 1, read_len, serv_handles[file_handle_index]); if(!quiet_mode) { SetTextColour(CON_FGREEN); printf("**SERV_READ:h=%d, rql=%ld rdl=%ld\n",file_handle_index+5,temp,read_len); DisplayStatusLine(); } // Send read size to psx ServSendLong(read_len); data=0xff; // Send file data out to PSX for(temp=0; (temp] [/Q] [/N]\n"); printf(" /I use IO port for Action Replay card (default=0x%x)\n",DEFAULT_IOPORT); printf(" /Q quiet mode - supress all none-error messages in FileServer mode\n"); printf(" /N disable the link activity indicator (slightly better performance)\n"); } void main(int argc, char *argv[]) { char *fname; SetTextMode(CON_MODE80x25); ClearScreen(); DisplayStatusLine(); SetTextColour(CON_BGREEN); SetTextColour(CON_FRED); printf("\nAction Replay FileServer"); SetTextColour(CON_BBLACK); printf("\n"); DisplayStatusLine(); printf("Version:%s\n",__DATE__); DisplayStatusLine(); printf("(C)1997,by Craig Graham\n"); DisplayStatusLine(); fbuffer=(unsigned char *)malloc(500000); // check for command line parameters while (--argc) { if (argv[argc][0] != '/') { fname = argv[argc]; }else{ switch (argv[argc][1]) { case 'Q': // Quite mode case 'q': quiet_mode=1; printf("Quiet mode is ON\n"); break; case 'N': // No activity indication act_t=0; printf("Activity indicator is OFF\n"); break; case 'I': // Set IO port case 'i': sscanf(argv[argc] + (argv[argc][2] == ':' ? 3 : 2), "%X",&io_port); break; default: instructions(); exit(-1); break; } } } Server(); exit(0); }