/* * siocons.c -- console program for DTL-H3000 * * Copyright (C) 1997 by Sony Computer Entertainment * All rights Reserved */ #include #include #include #include #include #include #include #include #include #include "misc.h" #include "getioadr.h" #include "inputhis.h" #include "dosint.h" #include "cmdport.h" #include "fifoport.h" #include "download.h" #include "keyin.h" #include "display.h" #include "strtrap.h" #include "rs.h" #ifndef R_OK #define R_OK 4 #define W_OK 2 #define X_OK 1 #define F_OK 0 #endif #define EDITBUFMAX 64 /* ---- define event ---- */ #define KEYIN 0x0001 #define CTRLC 0x0002 #define DISPCH 0x0004 #define LOCAL 0x0008 #define QUIT 0x00ff char *usage = "\033[%d;1m" "siocons -- PlayStation debug system console program\n" " for DTLH3000 1996/05/10 00:00:03\n" " type \033[7m F1 \033[0;%d;1m ----> display help\n" " when hung up try type \033[7m ESC \033[0m\n" ; char *susage = "\033[36m" " [F1] [F2] [F3] [F4] [F5] [F6] [F7] [F8] [F9] [F10]\r\n" " help dos auto load log edit - - \r\n" "[F9]+ help dload logstop \r\n" "[F10]+ help quit dsave \r\n" "\033[0m" ; char *lusage = "\033[36m" " Key functions Local command for auto\r\n" "-------------------------------------- | --------------------------------------\r\n" " F1 - display this message | help\r\n" " F2 - execute dos command | dos{sh,!} \r\n" " F10 F2 - exit this program | quit\r\n" " F3 - auto operation | auto \r\n" " F4 - formated file down load | load \r\n" " F9 F4 - binary file down load | dload
\r\n" " F10 F4 - binary file up load | dsave
\r\n" " F5 - operation logging start | log \r\n" " F9 F5 - logging stop | log\r\n" " F8 - local edit mode toggle | \r\n" " | auto-again\r\n" " | wait-prompt\r\n" " | sleep \r\n" " | pause []\r\n" " | echo \r\n" " | beep\r\n" "\033[0m"; char *f10usage = "\033[36m" " F10 F2 - exit this program\r\n" " F10 F4 - binary file up load\r\n" "\033[0m" ; char *f9usage = "\033[36m" " F9 F4 - binary file down load\r\n" " F9 F5 - logging stop\r\n" "\033[0m" ; /* ---- functions prototype ----*/ int nop_ent(); int help_auto(char *cmd), help_ent(); int helpf9_auto(char *cmd), helpf9_ent(); int helpf10_auto(char *cmd), helpf10_ent(); int quit_auto(char *cmd), quit_ent(); int ld_auto(char *cmd), ld_ent(); int save_auto(char *cmd), sv_ent(); int ld2_auto(char *cmd), ld2_ent(); int dos_auto(char *cmd), dos_ent(); int log_auto(char *cmd), log_ent(); int logoff_ent(); int auto_auto(char *cmd), auto_ent(); int autoagain_auto(char *cmd); int beep_auto(char *cmd), beep_ent(); int echo_auto(char *cmd); int pause_auto(char *cmd); int sleep_auto(char *cmd); int edtgl_auto(char *cmd), edtgl_ent(); int wait_prompt_auto(char *cmd); void autoclean(); int exeauto(); int getnextauto(); static int lcmdkick(int fkey, int prefix); static int lcmdexec(char *cmd); /* ---- global variables ---- */ static nibble_table; FILE *logfp = NULL; int prompt_catch_flag = 0; int localeditmode = 0; String_trap_element *prompttrap = NULL; struct _autostack { struct _autostack *next; FILE *fd; } *autostack = NULL; int autonest = 0; int autowaitprompt = 0; int autosleeptime = 0; time_t autostarttime; char autolinebuf[CHRBUFMAX]; struct cmdtable { unsigned char fkey[3]; /* FUNC, PRE1+FUNC, PRE2+FUNC */ char *cmdname; int (* entry)(); /* Function key entry */ int (* action)(char *); /* auto command entry */ } commandtable[] = { { 0, KEY_F1, 0, "helpf9", helpf9_ent, helpf9_auto }, { 0, 0, KEY_F1, "helpf10",helpf10_ent, helpf10_auto }, { KEY_F1, 0, 0, "help", help_ent, help_auto }, { KEY_F2, KEY_F2, 0, "dos", dos_ent, dos_auto }, { KEY_F2, KEY_F2, 0, "sh", dos_ent, dos_auto }, { KEY_F2, KEY_F2, 0, "!", dos_ent, dos_auto }, { 0, 0, KEY_F2, "quit", quit_ent, quit_auto }, { 0, 0, 0, "auto-again", nop_ent, autoagain_auto }, { KEY_F3, KEY_F3, KEY_F3, "auto", auto_ent, auto_auto }, { KEY_F4, 0, 0, "load", ld2_ent, ld2_auto }, { KEY_F4, 0, 0, "lds", ld2_ent, ld2_auto }, { 0, KEY_F4, 0, "dload", ld_ent, ld_auto }, { 0, KEY_F4, 0, "ld", ld_ent, ld_auto }, { 0, 0, KEY_F4, "dsave", sv_ent, save_auto }, { KEY_F5, 0, 0, "log", log_ent, log_auto }, { 0, KEY_F5, KEY_F5, "log", logoff_ent, log_auto }, { KEY_F8, KEY_F8, KEY_F8, "edittgl", edtgl_ent, edtgl_auto }, { 0, 0, 0, "beep", beep_ent, beep_auto }, { 0, 0, 0, "echo", nop_ent, echo_auto }, { 0, 0, 0, "pause", nop_ent, pause_auto }, { 0, 0, 0, "sleep", nop_ent, sleep_auto }, { 0, 0, 0, "wait-prompt", nop_ent, wait_prompt_auto }, { 0,0,0, NULL, NULL, NULL } }; char *skipsp(char *p) { while( p && *p && isspace(*p) ) p++; return p; } char *skipnonsp(char *p) { while( p && *p && !isspace(*p) ) p++; return p; } /***************************************************************** * compare command name & if match then return arg string */ char *cmdstrcmp(char *table, char *cmd) { while( *table && *cmd && tolower(*table) == tolower(*cmd) ) { table ++; cmd ++; } if( *table ) { return NULL; } return skipsp(cmd); } /***************************************************************** * local line input routine */ void consgets(char *prompt, char *buf, int max) { input_with_history(prompt, buf, max, WITHCR); } /*---------------- each local command actions ----------------*/ int nop_ent() { /* do nothing */ return OK; } int help_ent() { int ch; disps(susage); disps("\033[32mmore ?(y/N)\033[0m "); if( (ch=getkey()) == 'y' || ch == 'Y') { disps("\r\033[K\n"); disps(lusage); } else { dispf("%c\r\n", ch); } return OK; } int help_auto(char *cmd) { disps(lusage); return OK; } int helpf9_ent() { disps(f9usage); return OK; } int helpf9_auto(char *cmd) { disps(f9usage); return OK; } int helpf10_ent() { disps(f10usage); return OK; } int helpf10_auto(char *cmd) { disps(f10usage); return OK; } int ld_ent() { char linebuf[CHRBUFMAX]; consgets("\033[32mDload%s:\033[0m ", linebuf, EDITBUFMAX-1); if( logfp != NULL ) fprintf(logfp,"local dload %s\n",linebuf); return ld_auto(linebuf); } int sv_ent() { char linebuf[CHRBUFMAX]; consgets("\033[32mDsave%s:\033[0m ", linebuf, EDITBUFMAX-1); if( logfp != NULL ) fprintf(logfp,"local dsave %s\n",linebuf); return save_auto(linebuf); } #define DATA_BUF (2048*2*4) int save_auto(char *cmd) { time_t start_time; int ret; long size, _size; unsigned long addr; static char filename[1024]; void *p; FILE *fp; start_time = time(NULL); p = strtok(cmd," "); if( p == NULL) { printf("filename adr size\n"); return NG; } sscanf( p,"%s", filename); p = strtok(NULL," "); if( p == NULL) { printf("filename adr size\n"); return NG; } sscanf( p,"%lx", &addr); p = strtok(NULL," "); if( p == NULL) { printf("filename adr size\n"); return NG; } sscanf( p,"%lx", &size); if( start_smon_brd() != OK) return NG; fp = fopen( filename, "wb"); _size = size; while( size > 0) { printf( "DSAVE %s %lx %lx/%lx\n", filename, addr, _size - size, _size); if( fifo_memset_cmd( addr, DATA_BUF) != OK) return NG; addr += DATA_BUF; ret = fiforead( databuf, DATA_BUF ); if( ret != OK) { fclose(fp); return NG; } if( size >= DATA_BUF) { if( fwrite( databuf, 1, DATA_BUF, fp) != DATA_BUF) { fclose(fp); return NG; } } else { if( fwrite( databuf, 1, (size_t)size, fp) != (unsigned)size) { fclose(fp); return NG; } } size -= DATA_BUF; } fclose(fp); rs_putch('\r'); if( quit_smon() != OK) return NG; printf("%ld(sec)\n", time(NULL) - start_time); return OK; } int ld_auto(char *cmd) { int fcnt, i; unsigned long addr[20]; char *filenames[20]; cmd = skipsp(cmd); for( fcnt = 0; fcnt < 20 && *cmd; ) { filenames[fcnt] = cmd; cmd = skipnonsp(cmd); if( *cmd ) { *cmd = 0; cmd = skipsp(cmd+1); } if( *cmd == 0 || ! isxdigit(*cmd) || 1 != sscanf(cmd,"%lx",addr+fcnt) ) { dispf("\"%s\" file address missing\n",filenames[fcnt]); return NG; } fcnt ++; cmd = skipnonsp(cmd); cmd = skipsp(cmd); } if( fcnt > 0 ) { if( start_smon() != OK ) return NG; for( i = 0; i < fcnt; i ++ ) { if( bload(filenames[i],addr[i]) == NG ) return NG; } quit_smon(); return OK; } return NG; } int ld2_ent() { char linebuf[CHRBUFMAX]; consgets("\033[32mLoad%s:\033[0m ", linebuf, EDITBUFMAX-1); if( logfp != NULL ) fprintf(logfp,"local load %s\n",linebuf); return ld2_auto(linebuf); } int ld2_a_file(char *file, int verbose) { if( *file == 0 ) return NG; if( access( file , F_OK ) == 0 && access( file , R_OK ) == 0 ) { char *cp; switch(filetype(file)) { case SFMT: cp = "ld2\r"; while( *cp ) { put_cmd_port(*cp++); /* put "LD2" command */ } if( xfersfmt(skipsp(file),verbose) == NG ) { if( ctrlcflag ) ctrlcflag = 0; return NG; } break; case EXEF: if( start_smon() != OK ) return NG; if( loadexe(skipsp(file),verbose) == NG ) { if( ctrlcflag ) ctrlcflag = 0; return NG; } break; case AOUTF: if( start_smon() != OK ) return NG; if( loadaout(skipsp(file),verbose) == NG ) { if( ctrlcflag ) ctrlcflag = 0; return NG; } break; default: dispf( " \"%s\" unknown format\007\n\r", file ); return NG; } } else { dispf( " \"%s\" not found\007\n\r", file ); return NG; } return OK; } int ld2_trap(void *arg) { char linebuf[CHRBUFMAX]; int i; DWORD bytesRead; if( arg == NULL ) { consgets("\033[32mLoad%s:\033[0m ", linebuf, EDITBUFMAX-1); } else { put_cmd_port('F'); for( i = 0; i < CHRBUFMAX; i ++ ) { ReadFile(hFile, (LPVOID)&linebuf[i], 1, &bytesRead, NULL); scan_cmd_port(); if (bytesRead==0) { keyhit(); } if( linebuf[i] == '\r' ) { linebuf[i] = 0; break; } } } if( linebuf[0] == 0 ) { put_cmd_port(3); return NG; } if( access( linebuf , F_OK ) == 0 && access( linebuf , R_OK ) == 0 ) { if( xfersfmt(skipsp(linebuf),1) == NG ) { if( ctrlcflag ) ctrlcflag = 0; return NG; } } else { put_cmd_port(3); dispf( " \"%s\" not found\007\n\r", linebuf ); return NG; } return OK; } int ld2_auto(char *cmd) { char *file, *nfile; int verbose = 1; file = skipsp(cmd); if( *file ) { if( strncmp("-s ",file,3) == 0 ) { verbose = 0; file = skipsp(file+3); } else if( strncmp("-v ",file,3) == 0 ) { verbose = 2; file = skipsp(file+3); } } while( *file ) { nfile = skipnonsp(file); if( *nfile != 0 ) { *nfile = 0; nfile++; } if( ld2_a_file(file,verbose) == NG ) return NG; file = nfile; } return OK; } int dos_ent() { char linebuf[CHRBUFMAX]; consgets("\033[32mDos%s#\033[0m ", linebuf, EDITBUFMAX-1); if( linebuf[0] == 0 ) return OK; else { if( logfp != NULL ) fprintf(logfp,"local dos %s\n",linebuf); return dos_auto(linebuf); } } int dos_auto(char *cmd) { cmd = skipsp(cmd); system(cmd); return OK; } int log_ent() { char linebuf[CHRBUFMAX]; consgets("\033[32mLog%s:\033[0m ", linebuf, EDITBUFMAX-1); return log_auto(linebuf); } int logoff_ent() { disps("log off\n\r"); return(log_auto("")); } int log_auto(char *cmd) { FILE *newfp = NULL; if( logfp != NULL ) { fclose(logfp); logfp = NULL; } cmd = skipsp(cmd); if( strlen(cmd) > 0 ) { if( access( cmd , F_OK ) == 0 ) { newfp = fopen(cmd,"a"); if( newfp != NULL ) { logfp = newfp; dispf("start log append into \"%s\"\n\r",cmd); } else { dispf("\"%s\" can't open\n\r",cmd); } } else { newfp = fopen(cmd,"w"); if( newfp != NULL ) { logfp = newfp; dispf("start log into \"%s\"\n\r",cmd); } else { dispf("\"%s\" can't open\n\r",cmd); } } } return OK; } int execauto() { int i, result; char *cmd = skipsp(autolinebuf); result = OK; if( strncmp("local", cmd, 5) == 0 ) { cmd = skipsp(cmd+5); if( strlen(cmd) > 0 ) { result = lcmdexec(cmd); } if( result == NG ) autoclean(); } else { prompt_catch_flag = 0; for( i = 0; !breakflag && autolinebuf[i] && i < EDITBUFMAX; i++ ) { put_cmd_port(autolinebuf[i]); } if( !breakflag ) put_cmd_port('\r'); else { autoclean(); } /* here !!!! check echo */ } return result; } int getnextauto() { char *cmd; int result; result = OK; if( autostack == NULL ) return NG; if( fgets(autolinebuf,CHRBUFMAX,autostack->fd) != NULL ) { if( autolinebuf[strlen(autolinebuf)-1] == '\n' ) autolinebuf[strlen(autolinebuf)-1] = 0; cmd = skipsp(autolinebuf); if( strncmp("local", cmd, 5) == 0 ) { autowaitprompt = 0; } else { autowaitprompt = 1; } } else { struct _autostack *dp; dp = autostack; autostack = dp->next; fclose(dp->fd); free(dp); autonest --; result = getnextauto(); } return result; } void autoclean() { struct _autostack *dp; autosleeptime = 0; autowaitprompt = 0; for( dp = autostack; dp != NULL; dp = autostack ) { autostack = dp->next; fclose(dp->fd); free(dp); autonest --; if( autostack == NULL ) { disps("auto commands all stop\n\r"); } } } int auto_ent() { char linebuf[CHRBUFMAX]; if( autostack != NULL ) { autoclean(); return OK; } else { consgets("\033[32mAuto%s:\033[0m ", linebuf, EDITBUFMAX-1); if( linebuf[0] == 0 ) return OK; if( logfp != NULL ) fprintf(logfp,"local auto %s\n",linebuf); return auto_auto(linebuf); } } int auto_auto(char *cmd) { char *file; struct _autostack *np; if( autonest > 16 ) { disps("Too many nest Auto command \n\r"); return NG; } file = skipsp(cmd); if( access( file , F_OK ) == 0 && access( file , R_OK ) == 0 ) { np = malloc(sizeof(struct _autostack)); if( np == NULL ) { disps("Not enough memory for auto command \n\r"); return NG; } np->fd = fopen(file,"r"); if( np->fd == NULL ) { free(np); dispf( " \"%s\" can't open\n\r", file ); return NG; } np->next = autostack; autostack = np; autonest ++; getnextauto(); /* Decides whether or not to acquire the next autocommand and wail for prompt. */ } else { dispf( " \"%s\" not found\n\r", file ); return NG; } return OK; } int autoagain_auto(char *cmd) { if( autostack != NULL ) rewind(autostack->fd); return OK; } int beep_ent() { dispch(7); return OK; } int beep_auto(char *cmd) { dispch(7); return OK; } int echo_auto(char *cmd) { dispf("%s\n\r",cmd); return OK; } int pause_auto(char *cmd) { int ch; cmd = skipsp(cmd); if( strlen(cmd) ) dispf("%s ",cmd); else dispch('?'); while( (ch=getkey()) == 0xffff && !ctrlcflag && !breakflag ) {} dispf("\r\n"); if( ch == KEY_F3 && autostack != NULL ) autoclean(); return OK; } int sleep_auto(char *cmd) { autosleeptime = atoi(cmd); autostarttime = time(NULL); return OK; } int wait_prompt_auto(char *cmd) { autowaitprompt = 1; return OK; } int edtgl_ent() { localeditmode = localeditmode ? 0 : 1; put_cmd_port(0x15); prompt_catch_flag = 0; return OK; } int edtgl_auto(char *cmd) { localeditmode = localeditmode ? 0 : 1; put_cmd_port(0x15); prompt_catch_flag = 0; return OK; } int quit_auto(char *cmd) { return QUIT; } int quit_ent() { if( logfp != NULL ) fprintf(logfp,"local quit\n"); return QUIT; } /***************************************************************** * local command execute routine (for AUTO) */ int lcmdexec(char *cmd) { struct cmdtable *cp; char *arg; cmd = skipsp(cmd); for( cp = commandtable; cp->cmdname != NULL; cp++ ) { if((arg = cmdstrcmp( cp->cmdname , cmd))) { return (*cp->action)(arg); break; } } if( strlen(cmd) != 0 ) help_ent(); else disps("?\n\r"); return NG; } /***************************************************************** * local command execute routine (for FUNCTION KEY) */ int lcmdkick(int fkey, int prefix) { struct cmdtable *cp; for( cp = commandtable; cp->cmdname != NULL; cp++ ) { if( cp->fkey[prefix] == fkey ) { disps("\n\r"); return (*cp->entry)(); break; } } disps("?\n\r"); return NG; } /***************************************************************** * local edit for PSX command */ void prompt_catch() { prompt_catch_flag = 1; } /***************************************************************** * */ int waitevent() { int result = 0; if( keyhit() ) result |= KEYIN; if( ctrlcflag ) { result &= ~KEYIN; ctrlcflag = 0; result |= CTRLC; } if( breakflag ) { result &= ~KEYIN; breakflag = 0; result |= CTRLC; } result |= DISPCH; return result; } /***************************************************************** * main command loop */ void cmdloop() { int event, ch, prefix, i; unsigned char linebuf[CHRBUFMAX], *lp; DWORD bytesRead; setcursor_type(CURSOR_UL); prefix = 0; while(1) { event = 0; if( autosleeptime > 0 ) { /*---- 'local sleep ' executing ----*/ if( autosleeptime < time(NULL)-autostarttime ) { autosleeptime = 0; getnextauto(); /* Decides whether or not to acquire the next autocommand and wail for prompt. */ } else { event = waitevent(); if( event & KEYIN ) { ch = getkey(); } } } else if( autostack != NULL && !autowaitprompt ) { if( execauto() == QUIT ) /* autocommand(local) execution */ break; if( autosleeptime == 0 ) { if( ! autowaitprompt ) { getnextauto(); /* Decides whether or not to acquire the next autocommand and wail for prompt. */ } else { getnextauto(); /* Acquires the next autocommand. */ autowaitprompt = 1; /* Waits for prompt forcefully. */ } } } else if( prompt_catch_flag && autostack != NULL && autowaitprompt ) { execauto(); /* autocommand execution */ getnextauto(); /* Decides whether or not to acquire the next autocommand and wail for prompt. */ } else if ( prompt_catch_flag && localeditmode ) { dispch('\r'); input_with_history("%s>>", linebuf, EDITBUFMAX-1, RETILL); if( strlen(linebuf) == 1 && (linebuf[0] & 0x80) ) { event = KEYIN; ch = linebuf[0]; } else { prompt_catch_flag = 0; disps("\r\033[K>>"); for( i = 0; linebuf[i] && i < EDITBUFMAX; i++ ) { put_cmd_port(linebuf[i]); } put_cmd_port('\r'); } } else { event = waitevent(); if( event & KEYIN ) { ch = getkey(); } } if( event & KEYIN ) { if( ! isFUNC(ch) ) { setcursor_type(CURSOR_UL); prefix = 0; put_cmd_port(ch); } else { /* get function keys */ /* function key process */ if( prefix == 0 && ( ch == KEY_F9 || ch == KEY_F10 )) { setcursor_type(CURSOR_BOX); prefix = ch - KEY_F9+1; } else { if( lcmdkick(ch, prefix) == QUIT ) break; setcursor_type(CURSOR_UL); prefix = 0; } } } if( event & CTRLC ) { put_cmd_port('\003'); } if( event & DISPCH ) { prompt_catch_flag = 0; scan_cmd_port(); ReadFile(hFile, (LPVOID)linebuf, CHRBUFMAX-1, &bytesRead, NULL); lp=linebuf; if (bytesRead>0) { lp+=bytesRead; *lp = 0; disps(linebuf); if( logfp != NULL ) fputs(linebuf,logfp); /* input string check & action any special function */ if( trap_check(linebuf,lp-linebuf) == QUIT ) break; } } } } int wait_prompt() { int prompt1, prompt0; time_t starttime; DWORD bytesRead; starttime = time(NULL); prompt0 = 0; prompt1 = 0; /*Gets characters from buffer until command prompt ">>"appears */ for(;;) { if( time(NULL)-starttime > 3 ) { rs_close(); printf("DTLH3000 not ready!\n"); exit( 1); } if(_kbhit()) { if( _getch() == 27) { rs_close(); exit( 1); } } ReadFile(hFile, (LPVOID)&prompt1, 1, &bytesRead, NULL); if (bytesRead>0) { if( prompt1 == '>' && prompt0 == '>') break; prompt0 = prompt1; } } return OK; } /******************************************************************/ static FILE *hp; static char *histfile = NULL; main(int argc, char *argv[]) { char *autofile = NULL; int ver; char *cver = "1.53"; long baud = 9600; int oldcursor; while( *cver && *cver != '.' ) cver++; ver = (atoi(cver+1)%6)+31; printf(usage,ver,ver); getioaddr(argc,argv); baud = dmach; argc--, argv++; while( argc-- ) { if( strncmp("-B",argv[0],2) == 0 ) { sscanf( argv[0]+2, "%ld", &baud); } else if( strncmp("-p",argv[0],2) == 0 ) { /* skip this */ } else if( _access(argv[0],R_OK) == 0 ) { autofile = argv[0]; } argv++; } if( baud == 0 ) { fprintf(stdout, "BAUDRATE not define !\n"); fprintf(stdout, "abort !\n"); fprintf(stdout, "Please set DTLH3000 envelopment variable\n"); exit(1); } printf(" BAUDRATE = %ld\n", baud); if( getenv("SIOCONSHIS") != NULL ) { histfile = getenv("SIOCONSHIS"); } else { histfile = "siocons.his"; } if( _access(histfile, R_OK ) == 0 ) { hp = fopen(histfile,"r"); if( hp != NULL ) { set_keyin_history(hp); fclose(hp); } } if( cmdport_init(baud) == OK ) { prompttrap = add_new_trap(" \r>>", prompt_catch, NULL); add_new_trap("\r\nS-format data load start\r\n", ld2_trap, NULL); add_new_trap("\r\nS-format file load start\r\n", ld2_trap, (void *)1); if( autofile != NULL ) auto_auto(autofile); oldcursor = getcursor_type(); cmdloop(); setcursor_type(oldcursor); cmdport_term(); } hp = fopen(histfile,"w"); if( hp != NULL ) { dump_keyin_history(hp); fclose(hp); } return 0; } /* * forcefull stop */ void check_exit(int check) { if( check) { keyhit(); } if( ctrlcflag || breakflag ) { printf("\nTerminate by user!\n" ); cmdport_term(); hp = fopen(histfile,"w"); if( hp != NULL ) { dump_keyin_history(hp); fclose(hp); } exit( 1 ); } }