-- File: [Thyme]System>CSIM01>spOutput.mesa -- Last editted: -- Wilhelm April 6, 1982 11:36 AM, reformated by Barth and stored under -- [Cherry]Thyme>1.97> . DIRECTORY spGlobals, AltoDefs, CWF, Real, RealFns, plotDefs, DisplayDefs, StreamDefs, TimeDefs, StringDefs, AbsAllocDefs; spOutput: PROGRAM IMPORTS spGlobals, CWF, P: plotDefs, DisplayDefs, Str: StreamDefs, TD: TimeDefs, StringDefs, AbsAllocDefs EXPORTS spGlobals = BEGIN OPEN spGlobals; t0: REAL; argumentPtr: TYPE = LONG POINTER TO argument; argument: TYPE = RECORD[node: nodePtr, branch: branchPtr, getComVal: BOOLEAN, dvdt: BOOLEAN, current: BOOLEAN]; printBlkPtr: TYPE = LONG POINTER TO printBlk; printBlk: TYPE = RECORD[nextBlk: printBlkPtr, relativeTo: REAL, arg: argument]; plotBlkPtr: TYPE = LONG POINTER TO plotBlk; plotBlk: TYPE = RECORD[nextBlk: plotBlkPtr, graph: P.GraphHandle, relativeTo: REAL, arg: argument]; maxPrints: CARDINAL = 10; numPrints: CARDINAL _ 0; prints: ARRAY [0..maxPrints) OF RECORD[printList: printBlkPtr, printTimeRelTo: REAL, printStream: Str.StreamHandle]; maxPlots: CARDINAL = 10; numPlots: CARDINAL _ 0; plots: ARRAY [0..maxPlots) OF RECORD[plotList: plotBlkPtr, title: LONG STRING, plotTimeRelTo: REAL, yMin, yMax: REAL, plotCount: CARDINAL]; displayBlanked: BOOLEAN; systemWindow: P.TWHandle _ NIL; thymeLog: Str.StreamHandle _ NIL; time: STRING = [40]; bwDisplay: BOOLEAN _ FALSE; makePrintBlk: PROCEDURE RETURNS[pb: printBlkPtr] = BEGIN pb _ AbsAllocDefs.Allocate[SIZE[printBlk]]; pb^ _ [NIL, 1.0, [NIL, NIL, FALSE, FALSE, FALSE]] END; makePlotBlk: PROCEDURE RETURNS[pb: plotBlkPtr] = BEGIN pb _ AbsAllocDefs.Allocate[SIZE[plotBlk]]; pb^ _ [NIL, NIL, 1.0, [NIL, NIL, FALSE, FALSE, FALSE]] END; restoreDisplay: PUBLIC PROCEDURE = BEGIN IF displayBlanked THEN DisplayDefs.DisplayOn[] END; killPlot: PUBLIC PROCEDURE = BEGIN i: CARDINAL; time: STRING = [40]; time.length _ 0; TD.AppendDayTime[time, TD.UnpackDT[TD.CurrentDayTime[]]]; CWF.FWF1[thymeLog, "*n*n%s", time]; CWF.WF1["*n*n%s", time]; IF thymeLog # NIL THEN thymeLog.destroy[thymeLog]; FOR i IN [0..numPrints) DO prints[i].printStream.destroy[prints[i].printStream] ENDLOOP; P.CloseWindow[] END; openSysWindow: PUBLIC PROCEDURE[herald: STRING] = BEGIN logName: STRING = [40]; CWF.SWF1[logName, "%s.log", inputFileName]; thymeLog _ Str.NewByteStream[logName, Str.WriteAppend]; thymeLog.reset[thymeLog]; time.length _ 0; TD.AppendDayTime[time, TD.UnpackDT[TD.CurrentDayTime[]]]; CWF.FWF2[thymeLog, "%s*n*n%s*n*n", herald, time]; CWF.WF2["%s*n*n%s*n*n", herald, time] END; printSysWindow: PUBLIC PROCEDURE[s: STRING] = BEGIN IF systemWindow # NIL THEN P.WriteLine[s, systemWindow]; CWF.FWF1[thymeLog, "%s*n", s] END; initPlot: PUBLIC PROCEDURE[tMin, tMax: REAL, blank: BOOLEAN] = BEGIN window: P.WindowHandle; plotWindow: P.PWHandle; plotColor: P.ColorHandle; i, color: CARDINAL; pl: plotBlkPtr; cy, cyTitle, h, w: INTEGER; w2, wTitle: P.TWHandle; s: STRING = [20]; displayBlanked _ blank AND ~bwDisplay; IF displayBlanked THEN DisplayDefs.DisplayOff[white]; t0 _ tMin; P.SetTempFileName[inputFileName]; FOR i IN [0..numPlots) DO window _ P.OpenWindow[NIL, TRUE, ~bwDisplay, FALSE]; [w, h] _ P.GetWindowSize[window]; cy _ P.HeightOfLines[MAX[plots[i].plotCount, 6]]; cyTitle _ P.HeightOfLines[3]; w2 _ P.GetTextWindow[1500, h - cy, w/2, h - 15,,,window]; wTitle _ P.GetTextWindow[w/2, h - cyTitle, w, h - 15,,,window]; P.WriteString[inputFileName, wTitle]; P.WriteString[" ", wTitle]; P.WriteLine[time, wTitle]; IF plots[i].title # NIL THEN P.WriteLine[plots[i].title, wTitle]; plotWindow _ P.GetPlotWindow[0, 0, w, h - cy - 50, tMin/plots[i].plotTimeRelTo, tMax/plots[i].plotTimeRelTo, plots[i].yMin, plots[i].yMax, , window]; IF i = 0 THEN systemWindow _ P.GetTextWindow[w/2, h - cy, w, h - cyTitle,, FALSE]; color _ 0; pl _ plots[i].plotList; UNTIL pl = NIL DO plotColor _ P.GetStandardColor[color]; P.SetWindowColor[plotColor, w2]; pl^.graph _ SELECT color/8 FROM 0 => P.GetGraphHandle[plotWindow, plotColor], 1 => P.GetGraphHandle[plotWindow, plotColor,,, dashed], ENDCASE => P.GetGraphHandle[plotWindow, plotColor,,, dotted]; color _ color + 1; IF pl^.arg.getComVal THEN P.WriteString["Value of ", w2] ELSE IF pl^.arg.current THEN P.WriteString["Current through ", w2] ELSE IF pl^.arg.dvdt THEN P.WriteString["Derivative at ", w2] ELSE P.WriteString["Voltage at ", w2]; P.WriteString[makeStringNB[pl^.arg.node, pl^.arg.branch], w2]; IF pl^.relativeTo # 1.0 THEN BEGIN CWF.SWF1[s, "/%-9.2f", @pl^.relativeTo]; P.WriteString[s, w2] END; P.WriteLine["", w2]; pl _ pl^.nextBlk ENDLOOP ENDLOOP END; evaluateArgument: PROCEDURE[a: argumentPtr] RETURNS[iv: REAL] = BEGIN b: branchPtr; IF a^.getComVal THEN RETURN[a^.branch^.comVal]; IF a^.node # NIL THEN IF a^.dvdt THEN iv _ a^.node^.nHist.f0 ELSE iv _ a^.node^.nHist.y ELSE BEGIN b _ a.branch; IF a^.current THEN WITH b^ SELECT FROM resistor => iv _ (posNode^.nHist.y - negNode^.nHist.y)/comVal; capacitor => iv _ (posNode^.nHist.f0 - negNode^.nHist.f0)*comVal; inductor => iv _ iHist.y/comVal; vSource => iv _ vsCurrent; iSource => iv _ comVal ENDCASE ELSE iv _ b^.posNode^.nHist.y - b^.negNode^.nHist.y END END; plotFromList: PUBLIC PROCEDURE[t: REAL] = BEGIN i: CARDINAL; p: plotBlkPtr; r: REAL; FOR i IN [0..numPlots) DO p _ plots[i].plotList; UNTIL p = NIL DO r _ evaluateArgument[@p^.arg]/p^.relativeTo; IF t > t0 THEN P.DrawGraph[p^.graph, t/plots[i].plotTimeRelTo, r] ELSE P.PositionPen[p^.graph, t0/plots[i].plotTimeRelTo, r]; p _ p^.nextBlk ENDLOOP ENDLOOP END; printFromList: PUBLIC PROCEDURE[ni: CARDINAL, t: REAL, printStep: BOOLEAN] = BEGIN i: CARDINAL; p: printBlkPtr; r, trel: REAL; FOR i IN [0..numPrints) DO p _ prints[i].printList; trel _ t/prints[i].printTimeRelTo; CWF.FWF1[prints[i].printStream, "%9.3f", @trel]; IF printStep THEN CWF.FWF1[prints[i].printStream, "(%2d)", @ni]; UNTIL p = NIL DO r _ evaluateArgument[@p^.arg]/p^.relativeTo; CWF.FWF1[prints[i].printStream, " %9.3f", @r]; p _ p^.nextBlk ENDLOOP; CWF.FWFCR[prints[i].printStream] ENDLOOP END; scale: PROCEDURE RETURNS[s: REAL _ 1.0] = BEGIN IF item = colon THEN BEGIN next[]; s _ getSignedNumber[] END END; makePrintList: PUBLIC PROCEDURE = BEGIN I, D, cv: BOOLEAN; pb, pb2, pb3: printBlkPtr; n: nodePtr; b: branchPtr; name: STRING = [40]; IF numPrints >= maxPrints THEN BEGIN error[631]; numPrints _ numPrints - 1 END; IF item = leftB THEN next[] ELSE error[600]; IF item = colon THEN BEGIN prints[numPrints].printTimeRelTo _ scale[]; IF item = comma THEN next[] ELSE error[603,, FALSE] END ELSE prints[numPrints].printTimeRelTo _ 1.0; prints[numPrints].printList _ NIL; UNTIL item # name DO [n, b] _ findNodeOrBranch[]; IF n = NIL AND b = NIL THEN error[620] ELSE BEGIN I _ b # NIL AND item = upArrow; D _ n # NIL AND item = quote; cv _ b # NIL AND item = atSign; IF I OR D OR cv THEN next[]; pb _ makePrintBlk[]; pb^ _ [prints[numPrints].printList, scale[], [n, b, cv, D, I]]; prints[numPrints].printList _ pb END; IF item = comma THEN next[] ELSE EXIT ENDLOOP; pb _ NIL; pb3 _ prints[numPrints].printList; UNTIL pb3 = NIL DO pb2 _ pb3; pb3 _ pb3^.nextBlk; pb2^.nextBlk _ pb; pb _ pb2 ENDLOOP; prints[numPrints].printList _ pb; CWF.SWF2[name, "%s.out%d", inputFileName, @numPrints]; prints[numPrints].printStream _ Str.NewByteStream[name, Str.WriteAppend]; prints[numPrints].printStream.reset[prints[numPrints].printStream]; numPrints _ numPrints + 1; IF item = rightB THEN next[] ELSE error[601, TRUE] END; getPlotNum: PROCEDURE RETURNS[r: REAL _ 1.0] = BEGIN r _ getSignedNumber[]; IF item = comma THEN next[] ELSE error[603,, FALSE] END; makePlotList: PUBLIC PROCEDURE[bw: BOOLEAN] = BEGIN I, D, cv: BOOLEAN; pb: plotBlkPtr; n: nodePtr; b: branchPtr; bwDisplay _ bw; IF numPlots >= maxPlots THEN BEGIN error[632, FALSE]; numPlots _ numPlots - 1 END; IF item = leftB THEN next[] ELSE error[600]; IF item = string THEN BEGIN plots[numPlots].title _ newString; next[]; IF item = comma THEN next[] ELSE error[603,, FALSE] END ELSE plots[numPlots].title _ NIL; IF item = colon THEN BEGIN plots[numPlots].plotTimeRelTo _ scale[]; IF item = comma THEN next[] ELSE error[603,, FALSE] END ELSE plots[numPlots].plotTimeRelTo _ 1.0; plots[numPlots].yMin _ getPlotNum[]; plots[numPlots].yMax _ getPlotNum[]; IF plots[numPlots].yMin >= plots[numPlots].yMax THEN error[630, FALSE]; plots[numPlots].plotList _ NIL; plots[numPlots].plotCount _ 0; UNTIL item # name DO plots[numPlots].plotCount _ plots[numPlots].plotCount + 1; [n, b] _ findNodeOrBranch[]; IF n = NIL AND b = NIL THEN error[620] ELSE BEGIN I _ b # NIL AND item = upArrow; D _ n # NIL AND item = quote; cv _ b # NIL AND item = atSign; IF I OR D OR cv THEN next[]; pb _ makePlotBlk[]; pb^ _ [plots[numPlots].plotList, NIL, scale[], [n, b, cv, D, I]]; plots[numPlots].plotList _ pb END; IF item = comma THEN next[] ELSE EXIT ENDLOOP; IF item = rightB THEN next[] ELSE error[601, TRUE]; numPlots _ numPlots + 1 END; dumpAll: PUBLIC PROCEDURE[t: REAL] = BEGIN dump: Str.StreamHandle; dname: STRING = [40]; nodes: nodePtr _ nodeList; inds: inductorPtr _ inductorList; dname.length _ 0; StringDefs.AppendString[dname, "Dumped "]; TD.AppendDayTime[dname, TD.UnpackDT[TD.CurrentDayTime[]]]; printSysWindow[dname]; CWF.SWF1[dname, "%s.dump", inputFileName]; dump _ Str.NewByteStream[dname, Str.WriteAppend]; dump.reset[dump]; CWF.FWF1[dump, "ic[%f,*n", @t]; UNTIL nodes = NIL DO CWF.FWF2[dump, "%s_%f", makeStringNB[nodes, NIL, FALSE], @nodes^.nHist.y]; nodes _ nodes^.nextNode; IF nodes # NIL THEN CWF.FWF[dump, ",*n"] ELSE CWF.FWFCR[dump] ENDLOOP; UNTIL inds = NIL DO CWF.FWF2[dump, "%s_%f", makeStringNB[NIL, inds, FALSE], @inds^.iHist.y]; inds _ inds^.nextInductor; IF inds # NIL THEN CWF.FWF[dump, ",*n"] ELSE CWF.FWFCR[dump] ENDLOOP; CWF.FWF[dump, "];*n"]; dump.destroy[dump] END; END.