!! POSTPRO 08/10/79 %BEGIN %EXTERNAL %STRING(63) %FN %SPEC ITOS(%INTEGER N ,P) %EXTERNALSTRING(127)%FNSPEC CLIPARAM %EXTERNALINTEGERFNSPEC DEF STREAMS(%STRING(127) STREAMS,DEFAULTS) %INTEGER RETURN CODE %OWNSTRING(15) DEFAULTS=".TRC/%I1.WVM" %CONSTINTEGER MAXTRACES=200 %RECORDFORMAT TRACEF(%STRING(15) NAME, %INTEGER VALUE) %RECORD(TRACEF)%ARRAY TRACES(1:MAXTRACES) %RECORD(TRACEF)%NAME TRACE %CONSTINTEGER MAXSIGNALS=80 %RECORD(TRACEF)%NAME %ARRAY SIGNALS(1:MAXSIGNALS) %CONSTINTEGER NULL=0; !! null address %CONSTINTEGER LINELENGTH=60; !! length of console line %CONSTINTEGER PAGELEN=66, BOTTOM=2, TOP=1 %STRING(63) TRACENAME, NAME %STRING(15)%NAME T %INTEGER TIME, VALUE, NTRACES, NSIGNALS %INTEGER WIDTH, POSN, COMPRESSION, I, CH %INTEGER COLS PER TRACE, LINE %ROUTINE SKIP BLANKS SKIPSYMBOL %WHILE NEXTSYMBOL=' ' %OR NEXTSYMBOL=NL %END %ROUTINE SKIP LINE SKIPSYMBOL %WHILE NEXTSYMBOL#NL SKIPSYMBOL %END %ROUTINE TRUNCATE(%STRING(*)%NAME S) !! truncate the string S to 15 characters !! the first 5 and the last 9 characters are left %INTEGER I, L L=LENGTH(S)-10 %IF L>5 %START !! length > 15 %FOR I=2,1,10 %CYCLE !! for last 10 characters CHARNO(S,I+5)=CHARNO(S,I+L) %REPEAT CHARNO(S,6)='?' CHARNO(S,0)=15 %FINISH %END %ROUTINE GET STRING(%STRING(*)%NAME S) !! read in a string (from the terminal or from a file) !! certain characters are taken to terminate the string !! namely blank, newline, comma %INTEGER L, CH SKIP BLANKS L=0 %CYCLE CH=NEXTSYMBOL %EXIT %IF CH=' ' %OR CH=',' %OR CH=NL SKIPSYMBOL L=L+1 CH=CH-'a'+'A' %IF 'a'<=CH<='z' CHARNO(S,L)=CH %REPEAT CHARNO(S,0)=L %END %RECORD(TRACEF)%MAP FIND TRACE(%STRING(15) NAME) %RECORD(TRACEF)%NAME TRACE %INTEGER I %FOR I=1,1,NTRACES %CYCLE TRACE==TRACES(I) %RESULT==TRACE %IF TRACE_NAME=NAME %REPEAT %RESULT==RECORD(NULL) %END %RECORD(TRACEF)%MAP FIND SIGNAL(%STRING(15) NAME) %INTEGER I %RECORD(TRACEF)%NAME TRACE %FOR I=1,1,NSIGNALS %CYCLE TRACE==SIGNALS(I) %RESULT==TRACE %IF TRACE_NAME=NAME %REPEAT %RESULT==RECORD(NULL) %END %ROUTINE NULINE NEWLINE LINE=LINE+1 %END %ROUTINE NEWPAGE NEWLINES(PAGELEN+TOP-LINE) LINE=TOP %END %ROUTINE HEADING !! output a simulation trace heading %INTEGERARRAY DONE(1:NSIGNALS) %INTEGER I, NSPACES, NDONE %STRING(15)%NAME NAME PRINTSTRING(" Time") DONE(I)=0 %FOR I=1,1,NSIGNALS; NDONE=0 %CYCLE !! until all signal names have been output NSPACES=0 %FOR I=1,1,NSIGNALS %CYCLE NSPACES=NSPACES+COLS PER TRACE %CONTINUE %IF NSPACES<1 SPACES(NSPACES) %IF DONE(I)=1 %START !! already output this name PRINTSYMBOL('|'); NSPACES=-1 %FINISH %ELSE %START NAME==SIGNALS(I)_NAME PRINTSTRING(NAME) NSPACES=0-LENGTH(NAME) DONE(I)=1 NDONE=NDONE+1 %FINISH %REPEAT NULINE %EXIT %IF NDONE>=NSIGNALS SPACES(5) %REPEAT NULINE %END %ROUTINE PRINT LINE !! print a line of the simulation trace %INTEGER I, VALUE, NSPACES, F, TRACEWIDTH, CH TRACEWIDTH=COLS PER TRACE-1 TRACEWIDTH=4 %IF TRACEWIDTH>4 NSPACES=0 %FOR I=1,1,NSIGNALS %CYCLE NSPACES=NSPACES+COLS PER TRACE SPACES(NSPACES) VALUE=SIGNALS(I)_VALUE %IF VALUE=0 %START PRINTSYMBOL('0') NSPACES=-1 %FINISH %ELSE %START %IF VALUE=1 %THEN CH='X' %ELSE CH=' ' PRINTSYMBOL(CH) %FOR F=1,1,TRACEWIDTH-1 %IF VALUE=1 %THEN PRINTSYMBOL('X') %ELSE PRINTSYMBOL('1') NSPACES=0-TRACEWIDTH %FINISH %REPEAT NULINE %END %ROUTINE PRINT TO(%INTEGER WHEN) !! print the simulation trace up to just before the time WHEN %OWNINTEGER TIME=0 %INTEGER T %ROUTINE PRINT TIME(%INTEGER T) !! print out the time %IF (COMPRESSION=0 %AND REM(T,5)=0) %OR %C (COMPRESSION#0 %AND T=TIME) %START WRITE(T,4) %FINISH %ELSE SPACES(5) %END %RETURN %IF WHEN<=TIME NEWPAGE %AND HEADING %UNLESS LINE0 %START !! could be the compressed form %IF WHEN-TIME>COMPRESSION %START NEWPAGE %AND HEADING %UNLESS LINE<=PAGELEN-BOTTOM-2 PRINTSTRING(" ++++"); PRINT LINE ->OUT %FINISH %FINISH %FOR T=TIME+1,1,WHEN-1 %CYCLE NEWPAGE %AND HEADING %UNLESS LINEDONE %UNLESS RETURN CODE=1 !! first copy any 'comments' to the heading page SELECTINPUT(1); SELECTOUTPUT(1) %IF NEXTSYMBOL='$' %START SKIPSYMBOL %CYCLE READSYMBOL(CH) %EXIT %IF CH='$' %AND NEXTSYMBOL=NL PRINTSYMBOL(CH) %REPEAT SKIPSYMBOL %FINISH !!...first read the list of signal names at time 0... SELECTOUTPUT(0) NTRACES=0 %CYCLE SKIP BLANKS SKIP LINE %WHILE NEXTSYMBOL='$' GET STRING(TRACENAME) TRUNCATE(TRACENAME) %IF TRACENAME="*" %START !! premature end of trace PRINTSTRING("*Trace is empty - processing abandonned") NEWLINE %STOP %FINISH READ(VALUE); READ(TIME) %EXIT %IF TIME>0 %IF NTRACES>=MAXTRACES %START PRINTSTRING("*Too many signal names (re-compile program)") NEWLINE %STOP %FINISH NTRACES=NTRACES+1 TRACE==TRACES(NTRACES) TRACE_NAME=TRACENAME; TRACE_VALUE=VALUE %REPEAT !!...prompt for output control parameters............. SELECTINPUT(0) %CYCLE PROMPT("Width of page= ") SKIP BLANKS %UNLESS '0'<=NEXTSYMBOL<='9' %START !! help information PRINTSTRING("* Give the width of the page (in character columns) * on which the signal traces are to appear. ") %FINISH %ELSE %START READ(WIDTH) %EXIT %IF 10<=WIDTH<=132 %FINISH PRINTSTRING("* Width must be in range 10 to 132. ") SKIP LINE %REPEAT SKIP LINE !!...prompt for signal names to be traced........ NSIGNALS=0 %CYCLE PROMPT("Signal names ") GET STRING(NAME) TRUNCATE(NAME) NAME="?" %IF NAME="" %IF NAME="?" %START POSN=0 %FOR I=1,1,NTRACES %CYCLE T==TRACES(I)_NAME NEWLINE %AND POSN=0 %IF POSN+LENGTH(T)>LINELENGTH SPACE; PRINTSTRING(T) POSN=POSN+LENGTH(T)+1 %REPEAT PRINTSTRING(" * Use an asterisk (*) to terminate the list of names. ") %FINISH %ELSE %IF NAME="*" %START %EXIT %FINISH %ELSE %START TRACE==FIND TRACE(NAME) %IF TRACE==RECORD(NULL) %START !! NAME not found PRINTSTRING("* ".NAME." is not a signal name") NEWLINE %FINISH %ELSE %START %IF NSIGNALS>=MAXSIGNALS %START PRINTSTRING("* Only ".ITOS(MAXSIGNALS,0)." signals can be traced") NEWLINE %FINISH %ELSE %START NSIGNALS=NSIGNALS+1 SIGNALS(NSIGNALS)==TRACE %FINISH %FINISH %FINISH SKIPSYMBOL %REPEAT !!...work out whether trace will fit or not... COLS PER TRACE=(WIDTH-6)//(NSIGNALS+1) %IF COLS PER TRACE<2 %START PRINTSTRING("*Width of page is too small for no. of signals") NEWLINE NSIGNALS=(WIDTH-6)//2 %IF NSIGNALS<2 %START PRINTSTRING("*Trace abandonned"); NEWLINE %STOP %FINISH %ELSE %START PRINTSTRING("*Only the first ".ITOS(NSIGNALS,0)." signals will be traced") NEWLINE %FINISH %FINISH !!...prompt for compression factor......... %CYCLE SKIP LINE PROMPT("Compr'n factor=") SKIP BLANKS READ(COMPRESSION) %AND %EXIT %IF '0'<=NEXTSYMBOL<='9' PRINTSTRING("* If a compression factor of 'n' > 0 is specified, * then all time periods of length 'n' or more in which * no events occur are removed from the signal trace. * A value of 0 specifies no compression. ") %REPEAT SKIP LINE !!...and finally generate the signal traces......... SELECTINPUT(1); SELECTOUTPUT(1) LINE=PAGELEN %CYCLE TRACE==FIND SIGNAL(TRACENAME) %IF %NOT TRACE==RECORD(NULL) %START PRINT TO (TIME) TRACE_VALUE=VALUE %FINISH !! output any 'comments' (identified by '$') %CYCLE SKIP BLANKS; !! get rid of NL etc %EXIT %UNLESS NEXTSYMBOL='$' SKIPSYMBOL; !! skip the marker !! and copy the comment to the output stream %CYCLE CH=NEXTSYMBOL %EXIT %IF CH=NL PRINTSYMBOL(CH) SKIPSYMBOL %REPEAT NULINE %REPEAT GET STRING(TRACENAME) TRUNCATE(TRACENAME) %EXIT %IF TRACENAME="*"; !! end of trace READ(VALUE); READ(TIME) %REPEAT PRINT TO(TIME+1) DONE: %ENDOFPROGRAM