/*----------------------------------------------------------------*/ /* filetest.c tty/filetesting 10 Nov 2011 Keven Miller */ #ifdef __mpexl #pragma list off #endif /*---------------------------------------------------------------- This initial designed was for testing terminal responce with the various FSETMODE, FCONTROL, XCONTRAP settings. Since then, other file types were added, and now it can be a general "File IO" tester. ---FO File Open typ# aop# File type 9, when opening, allows file equations. File names used are as follows: type name foptions Designator 1 TTYLST 00214 $STDLIST 2 TTYNEW 00024 $NEWPASS 3 TTYOLD 00034 $OLDPASS 4 TTYIN 00244 $STDIN 5 TTYINX 00254 $STDINX 6 TTYNUL 00064 $NULL 7 TTYMSG 030104 MsgFile 8 TTYOSP 024204 OUTSP 9 TTYSTD 00004 StandardFile The 2nd number aop# usually is 0=read, 1=write, or 4=both. ---Build setvar CCOPTS "-Aa +e +w1" ccxllk fileutil.c,fileutil.pub ------------------------------------------------------------------*/ #include #include #include #include #include #ifdef __mpexl #pragma intrinsic CCODE #pragma intrinsic ACTIVATE #pragma intrinsic COMMAND #pragma intrinsic CAUSEBREAK #pragma intrinsic FOPEN #pragma intrinsic FCLOSE #pragma intrinsic FCHECK #pragma intrinsic FERRMSG #pragma intrinsic FREAD #pragma intrinsic FCONTROL #pragma intrinsic FSETMODE #pragma intrinsic FPOINT #pragma intrinsic FSPACE #pragma intrinsic FLOCK #pragma intrinsic FUNLOCK #pragma intrinsic FWRITE #pragma intrinsic PRINT #pragma intrinsic READ #pragma intrinsic READX #pragma intrinsic RESETCONTROL #pragma intrinsic XCONTRAP #pragma intrinsic XSYSTRAP #pragma intrinsic IOWAIT #pragma intrinsic IODONTWAIT #pragma intrinsic PAUSE #pragma intrinsic FRELATE #pragma intrinsic FFILEINFO #pragma intrinsic TIMER #pragma intrinsic FDEVICECONTROL extern void PAUSEX ( float* ); #define M(n) n /* Used with Transport */ #define C , /* Used with Transport */ #define MPE_INIT() /* Used with Transport */ #define MPE_FINISH() /* Used with Transport */ typedef unsigned short u16; typedef signed short s16; typedef int s32; typedef unsigned int u32; typedef float f32; #else /* NOT __mpexl */ # include "transport.h" /* Used with Transport */ #define M(n) &mask, n /* Used with Transport */ #define C /* Used with Transport */ #endif #define proc #define MPE_CCE 2 #define MAX_FILES 8 #define VERSION "E.02.00" #define TIMER_WRAP 2073600000 int noph; /* Used in SYSTRAP for ACTIVATE */ int yt; /* Used in cytrap */ int mt; /* Used in msgtrap */ s32 timelast; /* Used with Timing */ f32 pv; /* Used in cytrap and PAUSE,PAUSEX */ int pclear; /* Used in cytrap to clear pv */ int yreset; /* Used in cytrap to reset ^Y */ unsigned int mask; /* Used with Transport */ /*----------------------------------------------------------------*/ proc void msgtrap (int fn) /* show user msg interrupt */ { int f2, cc; s16 slen; u16 cs; char buf2 [300]; ++mt; printf ("\n!! Msg Interrupt %d fn %d\n", mt, fn ); f2 = IODONTWAIT ( fn, buf2, &slen, &cs ); cc = CCODE (); buf2 [slen] = 0; printf ( "cc %d f %d %d[%s]\n", cc, f2, slen, buf2 ); } /*----------------------------------------------------------------*/ proc void cytrap (void) /* show user interrupt */ { ++yt; printf ( "\n!! Control-Y %d PAUSE value %f\n", yt, pv ); if (pclear) pv = 0.0; if (yreset) RESETCONTROL (); } /*----------------------------------------------------------------*/ proc int fschk ( int fn ) /* Get and return FSERR */ { s16 fserr; mask = 3; FCHECK ( M(fn), &fserr ); if ( CCODE () != MPE_CCE ) fserr = 72; /* Invalid file number */ return fserr; } /*----------------------------------------------------------------*/ proc int fserr ( int fn ) /* Get and print FSERR msg */ { s16 fserr, slen; char msg [80]; fserr = fschk ( fn ); FERRMSG ( &fserr, msg, &slen ); if ( CCODE () != MPE_CCE ) slen = sprintf ( msg, "Unknown FSERR %d", fserr ); else msg [slen] = 0; printf ( "fn %d %s\n", fn, msg ); return fserr; } /*----------------------------------------------------------------*/ proc void systrap ( s32 code, s32 intr, s32 err, s32 parm ) { if ( code == 1003 && /* */ intr == 104 && /* ACTIVATE CATALOG.PUB.SYS set 5 */ err == 2 ) /* Illegal Cap CATALOG.PUB.SYS set 6 */ { noph = 1; } else { printf ( "** Systrap code %d intr %d err %d parm %d\n", code, intr, err, parm ); } } /*----------------------------------------------------------------*/ proc int main ( int ac, char *av[] ) { int cc, f, done, len, code, idx, fn [MAX_FILES]; s16 val, parm, fop, aop, rs, tt, nr, nw, r, w; s32 timenow, eof, lim, cur; char *np, *cp, pmt [12], cmd [300], buf [300]; MPE_INIT (); /* Remove leading path (if non-MPE) and trailing group.acct (if MPE) */ np = av [0]; while ((cp = strchr (np, '/'))) np = &cp [1]; cp = strchr ( np, '.' ); if (cp) *cp = 0; XSYSTRAP ( (int) &systrap, &code ); printf ( "%s TTY Tester %s\n", np, VERSION ); /* Initialize startup values */ timelast = TIMER (); f = 0; idx = 0; memset ( buf, 0, sizeof (buf)); memset ( fn, 0, sizeof (fn)); for ( done = 0; !done; ) { /* Get command */ len = sprintf ( pmt, "File %d>", idx ); PRINT ( pmt, -len, 0320 ); len = READX ( cmd, -( sizeof(cmd) -1) ); cmd [len] = 0; if ( len == 0 ) continue; for ( cp = cmd; *cp; ++cp ) *cp = toupper ( *cp ); /* Parse command */ cp = cmd; while ( isspace(*cp)) ++cp; switch (*cp++) { case 'F': /* Get 2nd letter */ code = ( isalpha (*cp) ? *cp++ : ' ' ); /* Get 3rd letter */ fop = ( isalpha (*cp) ? *cp++ : ' ' ); while ( *cp && !isdigit (*cp) && *cp != '+' && *cp != '-') ++cp; /* Get optional +- sign (for FSPACE) positioning */ len = ( *cp == '+' ? +1 : ( *cp == '-' ? -1 : 0 )); /* Get optional 1st value */ val = atoi(cp); if (len) ++cp; while ( isdigit (*cp)) ++cp; /* Get optional 2nd value */ while ( *cp && !isdigit (*cp)) ++cp; parm = atoi(cp); while ( isdigit (*cp)) ++cp; while ( *cp == ' ' ) ++cp; /* Switch on 2nd letter */ switch (code) { case 'H': /* File Help */ printf ("\n"); printf ("FS FSETMODE values\n"); printf (" 4 Disable echo of NL on read complete\n"); printf ("FT FCONTROL codes\n" ); printf (" 0 general parm passing\n" ); printf (" 1 pass in cctl\n" ); printf (" 2 complete IO\n"); printf (" 4 FREAD timeout in seconds\n" ); printf (" 12,13 Echo enabled,disable; rtn 0=was on,1=off\n"); printf (" 14,15 Break disable,enable\n"); printf (" 16,17 Subsys break (Control-Y) disable,enable\n"); printf (" 18,19 Tape mode disable,enable\n"); printf (" 20,21 read input time disable,enable " "(appears always on)\n"); printf (" 22 read input timer value " "(in hundreth seconds; only serial conn)\n"); printf (" 23,24 Parity disable,enable\n"); printf (" 25 AEOR alternate read terminator\n" ); printf (" 26,27 Binary mode disable,enable\n" ); printf (" 28,29 User Block mode disable,enable\n"); printf (" 34,35 Line Delete echo !!! enable,disable\n"); printf (" 38 Set term type\n"); printf (" 39 Get term type\n"); printf (" 41 Transparent/Unedited mode " "(Interrupt key only serial conn)\n"); printf (" 43 Abort NOWAIT IO\n"); printf (" 45 Extended wait val=1 enable 0 disable\n"); printf (" 46 Writer ID val=1 enable 0 disable\n"); printf (" 47 Nondestructive read val=1 ena 0 dis\n"); printf (" 48 Msg FREAD Interrupt\n"); printf ("FD FDEVICECONTROL p2=1 read 2 write 3 r/w\n"); break; case 'D': /* FDEVICECONTROL */ strcpy ( cmd, cp ); len = 1; FDEVICECONTROL ( f, cmd, len, 192, val, parm, (u16*)&tt ); cc = CCODE (); memcpy ( &parm, cmd, sizeof(parm)); printf ( "FDEVICECONTROL cc %d fserr %d buf %d %X\n", cc, tt, parm, parm ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'S': /* FSETMODE */ FSETMODE ( f, val ); cc = CCODE (); printf ( "FSETMODE mode %d cc %d\n", val, cc ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'T': /* FCONTROL */ code = val; val = parm; /* save old */ if ( code == 48 ) { lim = ( val ? (int) &msgtrap : 0 ); FCONTROL ( f, code, &lim ); } else FCONTROL ( f, code, &parm ); cc = CCODE (); printf ( "FCONTROL code %d parm %d rtn %d cc %d\n", code, val, parm, cc ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'C': /* FCLOSE */ switch (fop) { case 'T': len = 2; break; /* save temp */ case 'P': len = 1; break; /* save perm */ case 'D': len = 4; break; /* delete */ default: len = 0; } FCLOSE ( f, len, 0 ); cc = CCODE (); printf ( "FCLOSE cc %d\n", cc ); if ( cc != MPE_CCE ) fserr ( f ); else { if ( 0 < idx && idx <= MAX_FILES ) { if ( f == fn [idx-1] ) fn [idx-1] = 0; else printf ("** File %d not matched to fn %d\n", idx, f ); } f = 0; } break; case 'P': /* FPOINT FSPACE */ if (len) FSPACE ( f, val ); else FPOINT ( f, val ); cc = CCODE (); if (len) printf ("FSPACE %d cc %d\n", val, cc ); else printf ("FPOINT rec %d cc %d\n", val, cc ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'L': /* FLOCK */ len = ( fop == 'W' ? 1 : 0 ); FLOCK ( f, len ); cc = CCODE (); printf ("FLOCK cc %d\n", cc ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'U': /* FUNLOCK */ FUNLOCK ( f ); cc = CCODE (); printf ("FUNLOCK cc %d\n", cc ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'W': /* FWRITE */ len = strlen (buf); FWRITE ( f, (unsigned char*)buf, -len, val ); cc = CCODE (); printf ( "FWRITE len %d cctl %d cc %d\n", len, val, cc ); if ( cc != MPE_CCE ) fserr ( f ); break; case 'R': /* FREAD */ len = val; if ( !len || len >= sizeof(buf)) len = sizeof (buf) -1; len = FREAD ( f, buf, -len ); cc = CCODE (); if ( cc == MPE_CCE ) buf [len] = 0; printf ( "FREAD len %d cc %d [%s]\n", len, cc, buf ); val = ( cc != MPE_CCE ? fserr ( f ) : 0 ); break; case 'I': /* FRELATE FFILEINFO */ parm = f; /* save current file */ for ( len = 0; len <= MAX_FILES; ++len ) { /* If 1st value specified, only show that file */ if ( val ) { if ( 0 < val && val <= MAX_FILES ) len = val -1; else val = 0; } f = ( len < MAX_FILES ? fn [len] : 0 ); if ( ! f && len < MAX_FILES ) printf ("(%d) %2d Not Opened\n", len+1, f ); else { fop = aop = rs = tt = 0; eof = lim = 0; nw = nr = w = r = 0; mask = 0x3FF; FFILEINFO (M(f),1,cmd,2,&fop,3,&aop,4,&rs,60,&tt); cp = strchr ( cmd, ' ' ); if (cp) *cp = 0; mask = 0x3FF; FFILEINFO (M(f),10,&eof,11,&lim,34,&nw,35,&nr,58,&w); mask = 0x1F; FFILEINFO (M(f),59,&r,9,&cur); printf ("(%d) %2d %-.28s F0%o A0%o rs %3d tt %d", ( len < MAX_FILES ? len+1 : 0 ), f, cmd, fop, aop, rs, tt ); printf (" Cur %d Eof %d Lim %d\n", cur, eof, lim ); printf (" R %d(%d) W %d(%d)\n", nr, r, nw, w ); for ( code = 0; code <= MAX_FILES; ++code ) { fop = ( code < MAX_FILES ? fn [code] : 0 ); if ( code < MAX_FILES && !fop ) continue; aop = FRELATE ( f, fop ); if ( aop ) { nr = ( code < MAX_FILES ? code+1 : 0 ); printf (" Relate 0%o File %d\n", (u16) aop, nr ); } } } if ( val ) break; } f = parm; break; case 'O': /* FOPEN */ /* Find open fn slot */ for ( len = 0; len < MAX_FILES; ++len ) if ( fn [len] == 0 ) break; if ( len >= MAX_FILES ) { printf ("** Too many open files %d\n", MAX_FILES ); break; } switch (fop) { case 'B': fop = 3; break; /* Old Perm or Temp */ case 'T': fop = 2; break; /* Old Temp */ case 'P': fop = 1; break; /* Old Perm */ default: fop = 0; /* New */ } /* Switch on File type 0-9 */ mask = 7; switch (val) { case 1: /* STDLIST */ fop |= 0214; strcpy ( cmd, "TTLST" ); strcpy ( &cmd [10], "$STDLIST" ); break; case 2: /* $NEWPASS */ fop |= 024; strcpy ( cmd, "TTNEW" ); strcpy ( &cmd [10], "$NEWPASS" ); break; case 3: /* $OLDPASS */ fop |= 034; strcpy ( cmd, "TTOLD" ); strcpy ( &cmd [10], "$OLDPASS" ); break; case 4: /* $STDIN */ fop |= 0244; strcpy ( cmd, "TTIN" ); strcpy ( &cmd [10], "$STDIN" ); break; case 5: /* $STDINX */ fop |= 0254; strcpy ( cmd, "TTINX" ); strcpy ( &cmd [10], "$STDINX" ); break; case 6: /* $NULL */ fop |= 064; strcpy ( cmd, "TTNUL" ); strcpy ( &cmd [10], "$NULL" ); break; case 7: /* MSG */ fop |= 030104; strcpy ( cmd, "TTMSG" ); strcpy ( &cmd [10], "Msg" ); break; case 8: /* OUTSP */ fop |= 024204; strcpy ( cmd, "TTOSP" ); strcpy ( &cmd [10], "Outsp" ); break; case 9: /* DISK & FEQ */ fop |= 04; strcpy ( cmd, "TTSTD" ); strcpy ( &cmd [10], "STD" ); break; default: printf ("** Unknown file type: %d\n", val ); mask = 0; } if (mask) { f = FOPEN ( cmd, fop, parm ); cc = CCODE (); printf ( "Fopen %s %d cc %d\n", &cmd [10], f, cc ); if ( cc != MPE_CCE ) fserr ( f ); idx = len+1; fn [len] = f; } break; default: /* Select another file */ if ( code == ' ' ) { f = 0; if ( 0 <= val && val <= MAX_FILES ) { idx = val; if ( idx ) f = fn [idx-1]; } } else printf ("** Unknown File Command: %c\n", code ); } break; case 'A': ACTIVATE ( 0, 0 ); cc = CCODE (); printf ("ACTIVATE parent cc %d\n", cc ); if ( noph ) printf ("** Need PH cap **\n"); else ACTIVATE ( 0, 3 ); break; case 'R': code = ( isalpha (*cp) ? *cp++ : ' ' ); while ( *cp && !isdigit(*cp)) ++cp; len = atoi (cp); if ( !len || len >= sizeof(buf)) len = sizeof (buf) -1; if ( code == 'X' ) len = READX ( buf, -len ); else len = READ ( buf, -len ); cc = CCODE (); if ( cc == MPE_CCE ) buf [len] = 0; if ( code == 'X' ) printf ( "READX len %d cc %d [%s]\n", len, cc, buf ); else printf ( "READ len %d cc %d [%s]\n", len, cc, buf ); val = ( cc != MPE_CCE ? fserr ( 0 ) : 0 ); break; case 'P': code = ( *cp == 'A' || *cp == 'X' ? *cp++ : ' ' ); while ( *cp && !isdigit (*cp)) ++cp; val = atoi (cp); switch (code) { case 'A': pv = val; PAUSE (&pv); break; case 'X': pv = val; PAUSEX (&pv); break; default: len = strlen (buf); PRINT ( buf, -len, val ); } cc = CCODE (); switch (code) { case 'A': printf ("PAUSE cc %d\n", cc ); break; case 'X': printf ("PAUSEX cc %d\n", cc ); break; default: printf ("PRINT len %d cctl %d cc %d\n", len, val, cc); } break; case 'I': code = ( *cp == 'D' ? *cp++ : ' ' ); len = ( *cp == 'A' ? 0 : f); val = parm = 0; mask = 15; if ( code == 'D' ) len = IODONTWAIT ( M(len), buf, &val, (u16*)&parm ); else len = IOWAIT ( M(len), buf, &val, (u16*)&parm ); cc = CCODE (); printf ( "IOWAIT-%c rtn %d len %d cs %d cc %d\n", code, len, val, parm, cc ); if ( cc != MPE_CCE ) fserr ( len ); break; case 'Y': code = ( *cp == 'R' || *cp == 'C' ? *cp++ : ' ' ); switch (code) { case 'R': RESETCONTROL (); break; case 'C': XCONTRAP ( 0, &len ); break; default: XCONTRAP ( (int)&cytrap, &len ); } cc = CCODE (); if ( code == 'R' ) printf ( "RESETCONTROL cc %d\n", cc ); else printf ( "XCONTRAP old %p cc %d\n", (void*)len, cc ); break; case 'T': timenow = TIMER (); len = timenow - timelast; if ( len < 0 ) len += TIMER_WRAP; printf ( "TIMER %d (%d)\n", timenow, len ); timelast = timenow; break; case 'B': CAUSEBREAK (); cc = CCODE (); printf ( "CAUSEBREAK cc %d\n", cc ); break; case 'Q': done = 1; break; case 'E': code = ( *cp == 'X' ? *cp++ : ' ' ); switch (code) { case 'X': done = 1; break; default: fserr ( f ); } break; case ':': np = strchr (cp, 0); *np = '\r'; COMMAND ( cp, &val, &parm ); cc = CCODE (); printf ( "COMMAND err %d parm %d cc %d\n", val, parm, cc ); break; case 'S': code = ( isalpha (*cp) ? *cp++ : ' ' ); parm = ( isalpha (*cp) ? *cp++ : ' ' ); switch (code) { case 'P': pclear = ( parm == 'Z' ? 1 : 0 ); break; case 'Y': yreset = ( parm == 'R' ? 1 : 0 ); break; } printf ( " Zero PAUSE inside Interrupt: %d\n", pclear ); printf ( " RESETCONTROL inside Interrupt: %d\n", yreset ); break; default: printf ( "Unknown command: %c\n", cp[-1] ); case 'H': case '?': printf ( "---------- ----------------------- "); printf ( "--------------- -----------------------\n"); printf ( "Help this list " ); printf ( "B CAUSEBREAK \n" ); printf ( "E FERRMSG " ); printf ( "T Time since last time \n" ); printf ( "EXit exit program " ); printf ( "Quit exit program \n" ); printf ( "Y XCONTRAP set trap " ); printf ( "YC XCONTRAP clear trap \n" ); printf ( "P [cctl#] PRINT with cctl " ); printf ( "YR RESETCONTROL \n" ); printf ( "PA [sec#] PAUSE seconds " ); printf ( "PX [sec#] PAUSEX seconds \n" ); printf ( "RX [len#] READX " ); printf ( "R [len#] READ (buf size %d)\n", sizeof(buf)-1); printf ( "I[A] IOWAIT [All files] " ); printf ( "ID[A] IODONTWAIT [All files] \n" ); printf ( "FR [len#] FREAD " ); printf ( "FW [cctl#] FWRITE with cctl \n" ); printf ( "FS [opt#] FSETMODE " ); printf ( "FT [opt#][val#] FCONTROL \n" ); printf ( "FL[W] FLOCK [wait] " ); printf ( "FU FUNLOCK \n" ); printf ( "FC[TPD] FCLOSE [Tmp Prm Del] " ); printf ( "FP [+-][rec#] FPOINT or +- FSPACE\n" ); printf ( "FI [file#] FFILEINFO FRELATE " ); printf ( "FH File Help for options \n"); printf ( "F [file#] Select file (0-%d)\n", MAX_FILES); printf ( "FD [opt#] [val#] [data] FDEVICECONTROL 192\n"); printf ( "FO[TP] [type#] [aop] FOPEN [Tmp Prm] "); printf ( " aop= 0 read 1 write 4 R/W\n"); printf ( " type= 1 stdlist \"TTLST\" 2 newpass \"TTNEW\"" " 3 oldpass \"TTOLD\"\n"); printf ( " 4 stdin \"TTIN\" 5 stdinx \"TTINX\" " " 6 null \"TTNUL\"\n"); printf ( " 7 msg \"TTMSG\" 8 outsp \"TTOSP\" " " 9 std \"TTSTD\"\n"); printf ( "SPZ Set PAUSE to zero in interrupt\n"); printf ( "SP Do not set PAUSE to zero\n"); printf ( "SYR Do RESETCONTROL in interrupt\n"); printf ( "SY Do not RESETCONTROL\n" ); printf ( "A Activate parent\n" ); printf ( ": [cmd] MPE command (cmd size %d)\n", sizeof(cmd)-1); } } /* FDEVICECONTROL(fn,buf,1,192,15,1,&fserr) buf[0]=DC2,RS, EOR 1 TT or ENV file 3 line speed 5 Break 8 time of read 2 set timeout 4 ECHO 6 subbreak 9 parchk (11) 10(12) set parity 14 line delete 15 unedit 26 XON/XOFF on/off 27 XOFF timer 28 6=DTC blk 7=line/dtc block 15=PAD blk 29 blk char 30 read trigger(dc1) 32 blk trigger(dc1) 36 BS char 37 cancel ^X 39 TYpe 1 EOR std 40 type 2 EOR (AEOR) 41 subbreak char 66 multiAEOR 67 DEL for BS 68 Esc seq EOR 60 echo of read terminator */ /* Close all files */ for ( len = 0; len < MAX_FILES; ++len ) { f = fn [len]; if ( f ) { FCLOSE ( f,0,0 ); cc = CCODE (); if ( cc != MPE_CCE ) fserr ( f ); } } MPE_FINISH (); return 0; } /*----------------------------------------------------------------*/