DIRECTORY Basics, CommandTool, Convert, FS, GPIB, IMSTester, IO, MessageWindow, RefText, Rope, RopeList; IMSTesterImpl: CEDAR MONITOR IMPORTS Basics, Convert, CommandTool, FS, GPIB, IO, MessageWindow, RefText, Rope, RopeList EXPORTS IMSTester = BEGIN OPEN IMSTester; IMS: GPIB.DeviceAddr = 1; statusIMS: NAT; maxPktSize: NAT = 512; channelsPerGroup: NAT = 32; IMSError: PUBLIC SIGNAL [msg: ROPE] = CODE; checkSyntax: PUBLIC BOOL _ FALSE; stop: BOOL _ FALSE; logFile: ROPE _ "IMSTester.log"; synOut: IO.STREAM _ NIL; forceBd, acquireBd, progBd: PACKED ARRAY SlotNumber OF BOOLEAN; Initialize: PUBLIC ENTRY PROC [wDir: ROPE] RETURNS [forceBoard, acquireBoard, programable: PACKED ARRAY SlotNumber OF BOOLEAN] = { -- the tester ENABLE UNWIND => NULL; ReallyInitialize: INTERNAL PROC RETURNS [forceBoard, acquireBoard, programable: PACKED ARRAY SlotNumber OF BOOLEAN] ~ TRUSTED {{ rope: ROPE; stop _ FALSE; IF NOT checkSyntax THEN IF GPIB.InitializeController[] THEN { GPIB.InterfaceClear[]; GPIB.SelectedDeviceClear[IMS]} ELSE {IMSError["GPIB Controller Error!"]; RETURN; }; WriteDevice["INIT"]; --sets IMS modules to power-up condition FOR n: SlotNumber IN SlotNumber DO WriteDevice[IO.PutFR["CON? %g", IO.int[n]]]; rope _ ReadDevice[]; IF rope=NIL THEN { FOR slot: SlotNumber IN SlotNumber DO forceBoard[slot] _ (slot < 9) OR ((slot > 10) AND ((slot MOD 2)=1)); --reflects the current configuration acquireBoard[slot] _ (slot>11) AND ((slot MOD 2)=0); programable[slot] _ slot=21 OR slot=20; ENDLOOP; } ELSE { forceBoard[n] _ Rope.Find[rope, "STM", 0, FALSE]#-1; acquireBoard[n] _ Rope.Find[rope, "ACQ", 0, FALSE]#-1; programable[n] _ Rope.Find[rope, "PGM PGM", 0, FALSE]#-1 }; ENDLOOP; forceBd _ forceBoard; acquireBd _ acquireBoard; progBd _ programable; }}; logFile _ Rope.Concat[wDir, "IMSTester.log"]; [forceBoard, acquireBoard, programable] _ ReallyInitialize[]; }; RunDiagnostics: PUBLIC ENTRY PROC [extended: BOOL _ TRUE] = TRUSTED {{ ENABLE UNWIND => NULL; diagComplete: NAT = 196; IF extended THEN WriteDevice["DIAG ALL, EXT, ONCE"] -- wipes out pattern memory! ELSE WriteDevice["DIAG ALL, NORMAL, ONCE"]; IF NOT checkSyntax THEN UNTIL statusIMS = diagComplete DO statusIMS _ LOOPHOLE[GPIB.SelectedReadSerialPoll[IMS]]; ENDLOOP; WriteDevice["DIAG END"]; }}; DefineGroups: PUBLIC ENTRY PROC [forceGroups: ForceGroups, acquireGroups: AcquireGroups] = { ENABLE UNWIND => NULL; ReallyDefineGroups: INTERNAL PROC [forceGroups: ForceGroups, acquireGroups: AcquireGroups] ~ { podTiming: PodTiming; sentBanner: BOOL _ FALSE; timingChannel: BOOL _ FALSE; rootName, name: ROPE; length: NAT; FOR fg: ForceGroups _ forceGroups, fg.rest UNTIL fg=NIL DO length _ 0; sentBanner _ FALSE; FOR ptg: PodTimingGroups _ fg.first.podTimingGroups, ptg.rest UNTIL ptg=NIL DO podTiming _ ptg.first.podTiming; timingChannel _ podTiming=AT OR podTiming=BT; IF NOT sentBanner THEN { sentBanner _ TRUE; IF timingChannel THEN { WriteDevice[IO.PutFR["RES %g TIM #TXT", IO.rope[fg.first.name]]]; IF fg.first.format#RZ AND fg.first.format#R1 THEN IMSError["Illegal Format for Timing group"]; } ELSE WriteDevice[IO.PutFR["RES %g FOR #TXT", IO.rope[fg.first.name]]]; }; IF NOT forceBd[ptg.first.slot] THEN IMSError[IO.PutFR["No force board in slot %g for Force group %g", IO.int[ptg.first.slot], IO.rope[fg.first.name]]]; IF fg.first.programable AND NOT progBd[ptg.first.slot] THEN IMSError[IO.PutFR["Force board in slot %g for Force group %g is not programable", IO.int[ptg.first.slot], IO.rope[fg.first.name]]]; rootName _ SELECT podTiming FROM A=>"A", B=>"B", AT=>"AT", BT=>"BT", ENDCASE=>ERROR; FOR p: Pins _ ptg.first.pins, p.rest UNTIL p=NIL DO IF timingChannel AND p.first.channel#0 THEN IMSError["Can only assign channel 0 in A/B timing groups"]; IF (length _ length+1)>channelsPerGroup THEN IMSError[IO.PutFR["Force Group '%g' exceeded %g channels", IO.rope[fg.first.name], IO.int[channelsPerGroup]]]; name _ IF timingChannel THEN rootName ELSE IO.PutFR["%g%g", IO.rope[rootName], IO.int[p.first.channel]]; WriteDevice[IO.PutFR["%g %g %g %g", IO.card[ptg.first.slot], IO.rope[name], IO.rope[p.first.signalName], IO.card[p.first.packagePin]]]; ENDLOOP; ENDLOOP; WriteDevice["RES END"]; DefineParameters[fg: LIST[fg.first]]; ENDLOOP; FOR ag: AcquireGroups _ acquireGroups, ag.rest UNTIL ag=NIL DO length _ 0; WriteDevice[IO.PutFR["RES %g %g #TXT", IO.rope[ag.first.name], IO.rope[IF ag.first.compare THEN "COM" ELSE "ACQ"]]]; FOR ptg: PodTimingGroups _ ag.first.podTimingGroups, ptg.rest UNTIL ptg=NIL DO IF NOT acquireBd[ptg.first.slot] THEN IMSError[IO.PutFR["No acquire board in slot %g for Acquire group %g", IO.int[ptg.first.slot], IO.rope[ag.first.name]]]; IF ag.first.programable AND NOT progBd[ptg.first.slot] THEN IMSError[IO.PutFR["Force board in slot %g for Force group %g is not programable", IO.int[ptg.first.slot], IO.rope[ag.first.name]]]; IF ag.first.compare AND NOT forceBd[ptg.first.slot-1] THEN IMSError[IO.PutFR["No force board in slot %g for Compare group %g", IO.int[ptg.first.slot+1], IO.rope[ag.first.name]]]; IF ptg.first.podTiming=AT OR ptg.first.podTiming=BT THEN IMSError["Cannot assign AT or BT in an Acquire group"]; FOR p: Pins _ ptg.first.pins, p.rest UNTIL p=NIL DO IF (length _ length+1)>channelsPerGroup THEN IMSError[IO.PutFR["Acquire Group '%g' exceeded %g channels", IO.rope[ag.first.name], IO.int[channelsPerGroup]]]; WriteDevice[IO.PutFR["%g %g%g %g %g", IO.card[ptg.first.slot], IO.rope[SELECT ptg.first.podTiming FROM A=>"A", B=>"B", ENDCASE=> ERROR], IO.card[p.first.channel], IO.rope[p.first.signalName], IO.card[p.first.packagePin]]]; ENDLOOP; ENDLOOP; WriteDevice["RES END"]; DefineParameters[ag: LIST[ag.first]]; ENDLOOP; }; ReallyDefineGroups[forceGroups, acquireGroups]; }; RedefineGroups: PUBLIC ENTRY PROC [forceGroups: ForceGroups _ NIL, acquireGroups: AcquireGroups _ NIL] = { ENABLE UNWIND => NULL; DefineParameters[fg: forceGroups, ag: acquireGroups]; }; DefineParameters: PRIVATE INTERNAL PROC [fg: ForceGroups _ NIL, ag: AcquireGroups _ NIL] = { FOR fgl: ForceGroups _ fg, fgl.rest WHILE fgl#NIL DO f: ForceGroup _ fgl.first; WriteDevice[IO.PutFR["FOR %g %g %gns %gns", IO.rope[f.name], IO.rope[SELECT f.format FROM NRZ=>"NRZ", DNRZ=>"DNRZ", RZ=>"RZ", R1=>"R1", RC=>"RC", ENDCASE=>"RI"], IO.int[f.delay], IO.int[f.width]]]; IF f.programable THEN { WriteDevice[IO.PutFR["HID %g %g", IO.rope[f.name], IO.real[f.hiDrive]]]; WriteDevice[IO.PutFR["LOD %g %g", IO.rope[f.name], IO.real[f.loDrive]]]; }; ENDLOOP; FOR agl: AcquireGroups _ ag, agl.rest WHILE agl#NIL DO a: AcquireGroup _ agl.first; WriteDevice[IO.PutFR["SAM %g %gns", IO.rope[a.name], IO.int[a.sample]]]; IF a.programable THEN WriteDevice[IO.PutFR["THR %g %g", IO.rope[a.name], IO.real[a.threshold]]]; ENDLOOP; }; SetCyclePeriod: PUBLIC ENTRY PROC [period: Period] = { ENABLE UNWIND => NULL; WriteDevice[IO.PutFR["CLK INT %gNS", IO.int[period]]]; }; SetIMSMemory: PUBLIC ENTRY PROC [forceGroups: ForceGroups, acquireGroups: AcquireGroups, buffer: Buffer, cycles: Cycle, start: Cycle, halt: Cycle, jumps: Jumps _ NIL] = { ENABLE UNWIND => NULL; ReallySetIMSMemory: INTERNAL PROC [forceGroups: ForceGroups, acquireGroups: AcquireGroups, buffer: Buffer, cycles: Cycle, start: Cycle, halt: Cycle, jumps: Jumps _ NIL] ~ { firstPTG: PodTimingGroup; firstControlBit: BOOL; vector: REF TEXT; bits: LONG CARDINAL; data: Data; cycAdd: Cycle _ start; vector _ RefText.ObtainScratch[maxPktSize]; vector.length _ 0; FOR bufAdd: Cycle IN [0..cycles) DO --build vector for this cycle IF stop THEN {stop _ FALSE; EXIT}; vector _ RefText.AppendRope[vector, "MEM "]; vector _ RefText.AppendRope[vector, Convert.RopeFromCard[cycAdd]]; vector _ RefText.AppendRope[vector, " \""]; FOR fg: ForceGroups _ forceGroups, fg.rest UNTIL fg=NIL DO bits _ 0; firstPTG _ fg.first.podTimingGroups.first; firstControlBit _ buffer[bufAdd][firstPTG.board][(SELECT firstPTG.podTiming FROM A=>0, B=>8, AT=>16, BT=>17 ENDCASE=>ERROR)+firstPTG.pins.first.channel].inhibit; IF ~firstPTG.podTiming=AT AND ~firstPTG.podTiming=BT THEN { vector _ RefText.AppendChar[vector, IF firstControlBit THEN 'i ELSE 'f]; vector _ RefText.AppendChar[vector, ' ]; }; FOR ptg: PodTimingGroups _ fg.first.podTimingGroups, ptg.rest UNTIL ptg=NIL DO FOR p: Pins _ ptg.first.pins, p.rest UNTIL p=NIL DO bits _ bits*2; data _ buffer[bufAdd][ptg.first.board][(SELECT ptg.first.podTiming FROM A=>0, B=>8, AT=>16, BT=>17 ENDCASE=>ERROR)+p.first.channel]; IF firstControlBit#data.inhibit THEN IMSError[Rope.Cat[ IO.PutFR["Force group %g is not strictly Force or Inhibit. Cycle: %g, force board: %g, byte: ", IO.rope[fg.first.name], IO.int[bufAdd], IO.int[ptg.first.board]], SELECT ptg.first.podTiming FROM A=>"A", B=>"B", AT=>"AT", BT=>"BT" ENDCASE=>ERROR, IO.PutFR[", channel: %g is %g.", IO.int[p.first.channel], IO.rope[IF data.inhibit THEN "inhibit" ELSE "force"]]]]; IF data.forceData THEN bits _ bits+1; ENDLOOP; ENDLOOP; vector _ Convert.AppendCard[to: vector, from: bits, base: 16, showRadix: FALSE]; vector _ RefText.AppendChar[vector, ' ]; ENDLOOP; FOR ag: AcquireGroups _ acquireGroups, ag.rest UNTIL ag=NIL DO IF ag.first.compare THEN { bits _ 0; firstPTG _ ag.first.podTimingGroups.first; firstControlBit _ buffer[bufAdd][firstPTG.board][(SELECT firstPTG.podTiming FROM A=>0, B=>8, AT=>16, BT=>17 ENDCASE=>ERROR)+firstPTG.pins.first.channel].mask; vector _ RefText.AppendChar[vector, IF firstControlBit THEN 'm ELSE 'c]; vector _ RefText.AppendChar[vector, ' ]; FOR ptg: PodTimingGroups _ ag.first.podTimingGroups, ptg.rest UNTIL ptg=NIL DO FOR p: Pins _ ptg.first.pins, p.rest UNTIL p=NIL DO bits _ bits*2; data _ buffer[bufAdd][ptg.first.board][(SELECT ptg.first.podTiming FROM A=>0, B=>8, AT=>16, BT=>17 ENDCASE=>ERROR)+p.first.channel]; IF firstControlBit#data.mask THEN IMSError[Rope.Cat[ IO.PutFR["Acquire group %g is not strictly Mask or Compare. Cycle: %g, acquire board: %g, byte: ", IO.rope[ag.first.name], IO.int[bufAdd], IO.int[ptg.first.board]], SELECT ptg.first.podTiming FROM A=>"A", B=>"B", AT=>"AT", BT=>"BT" ENDCASE=>ERROR, IO.PutFR[", channel: %g is %g.", IO.int[p.first.channel], IO.rope[IF data.mask THEN "mask" ELSE "compare"]]]]; IF data.compareData THEN bits _ bits+1; ENDLOOP; ENDLOOP; vector _ Convert.AppendCard[to: vector, from: bits, base: 16, showRadix: FALSE]; vector _ RefText.AppendChar[vector, ' ]; }; ENDLOOP; FOR l: Jumps _ jumps, l.rest WHILE l#NIL DO IF jumps.first.source=cycAdd THEN { IF halt=cycAdd THEN IMSError["Cannot Halt and Jump in same cycle!"]; vector _ RefText.AppendTextRope[vector, ": Goto "]; vector _ RefText.AppendRope[vector, IO.PutR1[IO.card[jumps.first.destination]]]; jumps _ jumps.rest; }; ENDLOOP; IF halt=cycAdd THEN vector _ RefText.AppendTextRope[vector, ": Halt"]; vector _ RefText.AppendRope[vector, IF checkSyntax THEN "\"\n" ELSE "\"\l"]; IF vector.length>(maxPktSize-100) THEN { --try not to go over maxPktSize WriteDevice[Rope.FromRefText[vector], cycAdd=cycles-1]; vector.length _ 0; }; cycAdd _ cycAdd+1; REPEAT FINISHED => IF vector.length#0 THEN WriteDevice[Rope.FromRefText[vector], TRUE]; ENDLOOP; RefText.ReleaseScratch[vector]; }; ReallySetIMSMemory [forceGroups, acquireGroups, buffer, cycles, start, halt, jumps]; }; ErrorCount: PUBLIC ENTRY PROC RETURNS [count: LONG CARDINAL] = { ENABLE UNWIND => NULL; s: IO.STREAM; WriteDevice["FAIL?"]; IF checkSyntax THEN RETURN[0] ELSE { s _ IO.RIS[ReadDevice[]]; IF NOT Rope.Equal[IO.GetTokenRope[s ! IO.EndOfStream => ERROR].token, "FAIL", FALSE] THEN ERROR; RETURN[IO.GetCard[s ! IO.EndOfStream => ERROR]]; }; }; GetErrors: PUBLIC ENTRY PROC [acquireGroups: AcquireGroups, buffer: Buffer, testStart, testEnd, startCycle, cyclesJumped: Cycle] RETURNS [errors: Errors] = { ENABLE UNWIND => NULL; ReallyGetErrors: INTERNAL PROC [acquireGroups: AcquireGroups, buffer: Buffer, testStart, testEnd, startCycle, cyclesJumped: Cycle] RETURNS [errors: Errors] ~ { s: IO.STREAM; pinCount: NAT; mask, acquireData: LONG CARDINAL; expectData: Data; err: Errors _ NIL; errorCycle: Cycle; IF checkSyntax THEN RETURN [NIL]; errorCycle _ FindNextError[startCycle]; IF errorCycle>testEnd THEN RETURN [NIL]; WriteDevice[IO.PutFR["MEM? %g COM", IO.card[errorCycle-cyclesJumped]]]; s _ IO.RIS[ReadDevice[! IO.EndOfStream => ERROR]]; WHILE ([]_s.GetChar[]) # '" DO ENDLOOP; --skip to opening quote FOR ag: AcquireGroups _ acquireGroups, ag.rest UNTIL ag=NIL DO --skip compare data [] _ IO.GetTokenRope[s ! IO.EndOfStream => ERROR]; --skips 'C or 'M designator [] _ IO.GetTokenRope[s ! IO.EndOfStream => ERROR]; --skips data ENDLOOP; FOR ag: AcquireGroups _ acquireGroups, ag.rest UNTIL ag=NIL DO pinCount _ 0; FOR ptg: PodTimingGroups _ ag.first.podTimingGroups, ptg.rest UNTIL ptg=NIL DO FOR p: Pins _ ptg.first.pins, p.rest UNTIL p=NIL DO pinCount _ pinCount+1; ENDLOOP; ENDLOOP; acquireData _ Convert.CardFromRope[IO.GetTokenRope[s ! IO.EndOfStream => ERROR].token, 16]; mask _ Basics.DoubleShift[[lc[1]], pinCount-1].lc; FOR ptg: PodTimingGroups _ ag.first.podTimingGroups, ptg.rest UNTIL ptg=NIL DO FOR p: Pins _ ptg.first.pins, p.rest UNTIL p=NIL DO expectData _ buffer[errorCycle-testStart][ptg.first.board][(SELECT ptg.first.podTiming FROM A=>0, B=>8, AT=>16, BT=>17 ENDCASE=>ERROR)+p.first.channel]; IF NOT expectData.mask AND (Basics.DoubleAnd[[lc[acquireData]], [lc[mask]]].lc#0) # expectData.compareData THEN { err _ CONS[[errorCycle, ag.first, ptg.first, p.first, expectData.compareData, NOT expectData.compareData], err]; }; mask _ Basics.DoubleShift[[lc[mask]], -1].lc; ENDLOOP; ENDLOOP; ENDLOOP; FOR l: Errors _ err, l.rest WHILE l#NIL DO --put list in increasing order errors _ CONS[l.first, errors]; ENDLOOP; }; RETURN[ReallyGetErrors[acquireGroups, buffer, testStart, testEnd, startCycle, cyclesJumped]]; }; GetRawErrors: PUBLIC ENTRY PROC [out: IO.STREAM, forceGroups: ForceGroups, acquireGroups: AcquireGroups, testEnd, startCycle, cyclesJumped: Cycle] RETURNS [valid: BOOL, errorCycle: Cycle _ 0] = { ENABLE UNWIND => NULL; IF checkSyntax THEN RETURN [FALSE]; errorCycle _ FindNextError[startCycle]; IF errorCycle>testEnd THEN RETURN [FALSE]; ReallyGetMemory[out, errorCycle, forceGroups, acquireGroups, cyclesJumped]; RETURN[TRUE, errorCycle]; }; GetMemory: PUBLIC ENTRY PROC [out: IO.STREAM, cycle: Cycle, forceGroups: ForceGroups, acquireGroups: AcquireGroups, cyclesJumped: Cycle] = { ENABLE UNWIND => NULL; ReallyGetMemory[out, cycle, forceGroups, acquireGroups, cyclesJumped]; }; ReallyGetMemory: PRIVATE INTERNAL PROC [out: IO.STREAM, cycle: Cycle, forceGroups: ForceGroups, acquireGroups: AcquireGroups, cyclesJumped: Cycle] = { s: IO.STREAM; dataTokens, compTokens: LIST OF ROPE _ NIL; WriteDevice[IO.PutFR["MEM? %g", IO.int[cycle]]]; IF checkSyntax THEN RETURN; s _ IO.RIS[ReadDevice[! IO.EndOfStream => ERROR]]; WHILE ([]_s.GetChar[]) # '" DO ENDLOOP; --skip to opening quote IO.PutF[out, "Mem %g, ", IO.int[cycle]]; FOR fg: ForceGroups _ forceGroups, fg.rest UNTIL fg=NIL DO pt: PodTiming _ fg.first.podTimingGroups.first.podTiming; IO.PutRope[out, IF pt=A OR pt=B THEN IO.GetTokenRope[s ! IO.EndOfStream => ERROR].token ELSE ""]; --gets 'F or 'I designator if there is one IO.PutChar[out, ' ]; IO.PutRope[out, IO.GetTokenRope[s ! IO.EndOfStream => ERROR].token]; --gets force data IO.PutChar[out, ' ]; ENDLOOP; IO.PutChar[out, '\n ]; FOR ag: AcquireGroups _ acquireGroups, ag.rest UNTIL ag=NIL DO compTokens _ CONS[IO.GetTokenRope[s].token, compTokens]; dataTokens _ CONS[IO.GetTokenRope[s].token, dataTokens]; out.PutF["%g %g ", IO.rope[compTokens.first], IO.rope[dataTokens.first]] ENDLOOP; IO.PutChar[out, '\n ]; compTokens _ RopeList.Reverse[compTokens]; dataTokens _ RopeList.Reverse[dataTokens]; WriteDevice[IO.PutFR["MEM? %g COM", IO.int[cycle-cyclesJumped]]]; s _ IO.RIS[ReadDevice[! IO.EndOfStream => ERROR]]; WHILE ([]_s.GetChar[]) # '" DO ENDLOOP; --skip to opening quote FOR ag: AcquireGroups _ acquireGroups, ag.rest UNTIL ag=NIL DO [] _ IO.GetTokenRope[s]; [] _ IO.GetTokenRope[s] ENDLOOP; FOR rl: LIST OF ROPE _ compTokens, rl.rest UNTIL rl=NIL DO tRope: ROPE _ IO.GetTokenRope[s].token; rRope: ROPE _ dataTokens.first; dataTokens _ dataTokens.rest; IO.PutRope[out, " "]; IF Rope.Equal[rRope, tRope] OR Rope.Equal[rl.first, "M"] THEN IO.PutRope[out, tRope] ELSE FOR i: INT IN [0..Rope.Length[tRope]) DO rc: CHAR _ Rope.Fetch[rRope, i]; tc: CHAR _ Rope.Fetch[tRope, i]; IF rc # tc AND IO.GetInfo[out].class=$ViewersOutput THEN IO.PutF[out, "%l%g%l", IO.char['b], IO.char[tc], IO.char['B]] ELSE IO.PutF[out, "%g", IO.char[tc]] ENDLOOP; out.PutChar[' ]; ENDLOOP; WHILE ~s.EndOf[] DO token: ROPE; IO.PutChar[out, ' ]; token _ IO.GetTokenRope[s ! IO.EndOfStream => EXIT].token; SELECT TRUE FROM Rope.Equal[token, """"] => token _ ""; Rope.Equal[token, "e"] => token _ ""; ENDCASE => NULL; IO.PutRope[out, token]; ENDLOOP; IO.PutChar[out, '\n ]; }; Upload: PUBLIC ENTRY PROC [fName: ROPE] ~ { s: IO.STREAM; s _ FS.StreamOpen[fileName: fName, accessOptions: $create, wDir: CommandTool.CurrentWorkingDirectory[] ! FS.Error => {Message[IO.PutFR["Trouble opening: %g", IO.rope[fName]]]; CONTINUE}]; IF s=NIL THEN RETURN; WriteDevice["SET?"]; IO.Put[s, IO.rope[ReadDevice[]]]; WriteDevice["BSET?"]; IO.Put[s, IO.rope[ReadDevice[]]]; IO.Close[s]; }; Download: PUBLIC ENTRY PROC [fName: ROPE] ~ { s: IO.STREAM; done: BOOL _ FALSE; nBytesRead: NAT _ 0; rt: REF TEXT _ RefText.ObtainScratch[maxPktSize]; s _ FS.StreamOpen[fileName: fName, wDir: CommandTool.CurrentWorkingDirectory[] ! FS.Error => {Message[IO.PutFR["File: %g not found", IO.rope[fName]]]; CONTINUE}]; IF s=NIL THEN RETURN; DO nBytesRead _ IO.GetBlock[s, rt ! IO.EndOfStream => {done _ TRUE; CONTINUE}]; IF nBytesRead=0 THEN EXIT; WriteDevice[Rope.FromRefText[rt], done, ""]; IF done THEN EXIT; ENDLOOP; RefText.ReleaseScratch[rt]; IO.Close[s]; }; Start: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; WriteDevice["START ALL"] }; Stop: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; WriteDevice["STOP ALL"]; --current test operations IF checkSyntax AND synOut#NIL THEN IO.Close[synOut]; }; Wait: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; WriteDevice["WAIT ALL, 10s"]; }; Abort: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; stop _ TRUE; }; FindNextError: PRIVATE INTERNAL PROC [startCycle: Cycle] RETURNS [errorCycle: Cycle] = { s: IO.STREAM; WriteDevice[IO.PutFR["FIND? SEQ %g", IO.card[startCycle]]]; s _ IO.RIS[ReadDevice[]]; IF NOT Rope.Equal[IO.GetTokenRope[s ! IO.EndOfStream => ERROR].token, "FIND", FALSE] THEN ERROR; IF NOT Rope.Equal[IO.GetTokenRope[s ! IO.EndOfStream => GOTO finished].token, "SEQ", FALSE] THEN ERROR; errorCycle _ IO.GetCard[s ! IO.EndOfStream => ERROR]; EXITS finished => errorCycle _ LAST[Cycle]; }; Message: PRIVATE INTERNAL PROC [rope: ROPE] = { MessageWindow.Append[rope, TRUE]; MessageWindow.Blink[]; MessageWindow.Append[rope, TRUE]; }; GetIMSStatusMsg: PRIVATE INTERNAL PROC RETURNS [msg: ROPE] = TRUSTED {{ errBuf: ROPE; end: BOOL; IF checkSyntax THEN RETURN["GetIMSStatusMsg: No Status Message in Simulation."]; statusIMS _ LOOPHOLE[GPIB.SelectedReadSerialPoll[IMS]]; GPIB.WriteDevice[IMS, "Err?\l"]; [errBuf, end] _ GPIB.ReadDevice[IMS]; IF NOT end THEN ERROR; --shouldn't get long ropes here errBuf _ Rope.Substr[errBuf, Rope.Length["error \""], Rope.Length[errBuf]-3]; msg _ IO.PutFR["SRQ: %g; Error: %g", IO.card[statusIMS], IO.rope[errBuf]]; }}; WriteDevice: PRIVATE INTERNAL PROC [msg: ROPE, hold: BOOL _ TRUE, term: ROPE _ "\l"] = TRUSTED {{ IF checkSyntax THEN { IF synOut=NIL THEN synOut _ FS.StreamOpen[logFile, $create]; --check for NIL synOut.PutF["%g\n", IO.rope[msg] ! IO.Error => {synOut _ FS.StreamOpen[logFile, $create]; RETRY}] --file could be closed } ELSE GPIB.WriteDeviceBuffered[IMS, Rope.Concat[msg, term], hold]; }}; ReadDevice: PRIVATE INTERNAL PROC RETURNS [msg: ROPE] = TRUSTED {{ r: ROPE; end: BOOL _ FALSE; msg _ NIL; IF checkSyntax THEN RETURN[NIL] ELSE WHILE NOT end DO [r, end] _ GPIB.ReadDevice[IMS]; msg _ Rope.Concat[msg, r]; ENDLOOP; }}; END. nIMSTesterImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Gasbarro December 9, 1985 12:46:42 pm PST Last Edited by: Neil Gunther December 18, 1985 3:00:10 pm PST Last Edited by: Gasbarro February 13, 1987 6:20:01 pm PST Don Curry February 17, 1987 10:35:00 am PST -- Globals -- validCycles: Cycle _ 0; --number of valid cycles in IMS memory -- What about looping? Use IMSCommander for serious interrogation. --store diag results, someday(sigh!) WriteDevice[IO.PutFR["RAD %g BIN", IO.rope[f.name]]]; WriteDevice[IO.PutFR["RAD %g BIN", IO.rope[a.name]]]; validCycles _ cycles; IM$: mem? 2 COM mem 2,Compare,"C 0000 M 00 C 00 C 00000002 FFFF 00 00 FFFFFFFF"," e" ***This is a work around for an IMS firmware bug in V1.1A. When a test is run by jumping to a start address from location zero the acquired data is read in cycle-cyclesJumped.*** IM$: mem? 2 COM mem 2,Compare,"C 0000 M 00 C 00 C 00000002 FFFF 00 00 FFFFFFFF"," e" IM$: mem? 1 mem 1,"I 0 I 0 I 00000000 I 0 M 0 M 000 M 00000000 M 00 1 3FF FFFFFFFF 7F" -- for HALT to be executed or timeout IM$: find? seq 0 "" "???e" find (Seq 2,...) Κ"– "cedar" style˜codešœ™Kšœ Οmœ1™šœž œ žœžœ˜?K˜—šΟn œžœžœžœžœžœ)žœžœ žœžœ  ˜Kšžœ˜š‘œžœžœžœ)žœžœ žœžœžœ˜€Kšœžœ˜ Kšœžœ˜ šžœžœ žœ˜šœžœžœžœ˜'Jšžœ˜Jšžœ˜Jšžœ%˜)Jšž˜Jšœ˜——Jšœ (˜=šžœžœ ž˜"Kšœ žœžœ ˜,Kšœ˜šžœžœžœ˜šžœžœ ž˜%Kšœžœžœžœ  $˜jKšœžœžœ˜4Kšœžœ ˜'—Kšžœ˜Kšœžœ˜Kšœ*žœ˜4Kšœ,žœ˜6Kšœ0žœ˜9K˜—Kšžœ˜—JšœE˜EK˜Kšœ˜K˜—K˜-Kšœ=˜=Kšœ˜K˜—š ‘œžœ žœžœžœ˜FKšœB™BKšžœ˜Kšœžœ˜šžœ ž˜Kšœ# ˜?—Kšžœ(˜,šžœžœ žœ˜šžœž˜!Kšœ žœžœžœ˜7Kšœ$™$Kšžœ˜——Kšœ˜K˜K˜—š‘ œžœ=˜\Kšžœ˜š‘œž œ=˜^Kšœ˜Kšœ žœžœ˜Kšœžœžœ˜Kšœžœ˜Kšœžœ˜ šžœ(žœžœž˜:Kšœžœ˜šžœ;žœžœžœ˜OKšœ ˜ Kšœžœžœ žœ˜-šžœžœ žœ˜Kšœ žœ˜šžœžœ˜Kšœ žœžœ˜AKšžœžœžœžœ-˜^Kšœžœ žœžœ˜H—K˜—Kš žœžœžœ žœ7žœžœ˜—Kšžœžœžœžœ žœGžœžœ˜ΏKš œ žœ žœžœžœžœžœ˜Tšžœ"žœžœž˜3Kšžœžœžœ=˜hKšžœ&žœ žœ0žœ1˜›Kš œžœžœ žœžœžœžœ˜hKš œ žœžœžœ žœžœ˜‡Kšžœ˜—Kšžœ˜—Kšœ˜Kšœžœ ˜%Kšžœ˜ K˜—šžœ,žœžœž˜>Kšœ ˜ Kš œ žœžœžœžœžœžœ ˜tšžœ;žœžœžœ˜OKšžœžœžœx˜Kšžœžœžœžœ„˜ΏKšžœžœžœžœ žœ9žœžœ˜²Kš žœžœžœžœžœ8˜pšžœ"žœžœž˜3Kšžœ&žœ žœ2žœ1˜Kšœ žœžœžœžœžœžœžœžœžœžœ˜ήKšžœ˜—Kšžœ˜—Kšœ˜Kšœžœ ˜%Kšžœ˜ —K˜K˜—Kšœ/˜/K˜K˜—š ‘œžœžœžœžœ!žœ˜jKšžœ˜Kšœ5˜5K˜K˜—š ‘œžœžœžœžœžœ˜\šžœ!žœžœž˜4Kšœ˜Kšœ žœžœžœžœ žœžœ žœ žœžœžœ žœžœ˜ΕKšœ žœžœ™5šžœžœ˜Kšœ žœžœžœ˜HKšœ žœžœžœ˜HK˜—Kšžœ˜—šžœ#žœžœž˜6Kšœ˜Kšœ žœžœžœ˜HKšœ žœžœ™5Kš žœžœ žœžœžœ˜`Kšžœ˜—K˜K˜—š‘œžœ˜7Kšžœ˜Kšœ žœžœ˜6K˜K˜—š‘ œžœƒžœ˜ͺKšžœ˜š‘œž œƒžœ˜¬Kšœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœ˜Kšœ ˜ Kšœ˜K™Kšœ+˜+Kšœ˜šžœžœ žœ ˜AKšžœžœ žœžœ˜"Kšœ,˜,KšœB˜BKšœ+˜+šžœ(žœžœž˜:Kšœ ˜ Kšœ*˜*Kš œ2žœžœ žœžœžœžœ'˜‘š žœžœžœžœžœ˜;Kšœ$žœžœžœ˜HKšœ(˜(K˜—šžœ;žœžœžœ˜Ošžœ"žœžœž˜3Kšœ˜Kš œ(žœžœ žœžœžœžœ˜„šžœžœ˜7Kšžœ_žœžœžœ˜£Kš žœžœžœžœžœžœ˜RKš žœžœžœžœžœ žœ ˜r—Kšžœžœ˜%Kšžœ˜—Kšžœ˜—KšœIžœ˜PKšœ(˜(Kšžœ˜—šžœ,žœžœž˜>šžœžœ˜Kšœ ˜ Kšœ*˜*Kš œ2žœžœ žœžœžœžœ$˜žKšœ$žœžœžœ˜HKšœ(˜(šžœ;žœžœžœ˜Ošžœ"žœžœž˜3Kšœ˜Kš œ(žœžœ žœžœžœžœ˜„šžœžœ˜4Kšžœbžœžœžœ˜¦Kš žœžœžœžœžœžœ˜RKš žœžœžœžœ žœžœ˜n—Kšžœžœ˜'Kšžœ˜—Kšžœ˜—KšœIžœ˜PKšœ(˜(K˜—Kšžœ˜—šžœžœžœž˜+šžœžœ˜#Kšžœ žœΟzœ˜DKšœ3˜3Kšœ$žœžœ!˜PKšœ˜Kšœ˜—Kšžœ˜—Kšžœ žœ3˜FKšœ$žœ žœžœ ˜Lšžœ žœ ˜HKšœ7˜7K˜Kšœ˜—Kšœ˜šž˜Kšžœžœžœ'žœ˜P—Kšžœ˜—Kšœ˜K˜K˜—KšœT˜TKšœ˜K˜—š ‘ œžœžœžœžœ ž œ˜@Kšžœ˜Kšœžœžœ˜ Kšœ˜šžœ žœžœžœ˜$Kšœžœžœ˜Kšžœžœ žœžœžœžœžœžœ˜`Kšžœžœ žœžœ˜0Kšœ˜—K˜K˜—š‘ œžœežœ˜Kšžœ˜š‘œž œežœ˜ŸKšœžœžœ˜ Kšœ žœ˜Kšœžœžœ˜!K˜Kšœžœ˜K˜K˜Kšžœ žœžœžœ˜!Kšœ'˜'Kšžœžœžœžœ˜(KšΠbfΟf ™Kš€G™GKšœ žœžœ!˜HKš œžœžœžœžœ˜2Kšžœžœžœ ˜?š žœ,žœžœžœ ˜RKšœžœžœžœ ˜NKšœžœžœžœ  ˜?Kšžœ˜—šžœ,žœžœž˜>Kšœ ˜ šžœ;žœžœžœ˜Ošžœ"žœžœž˜3K˜Kšžœ˜—Kšžœ˜—Kšœ#žœžœžœ ˜[Kšœ2˜2šžœ;žœžœžœ˜Ošžœ"žœžœž˜3Kš œ<žœžœ žœžœžœžœ˜˜Kšžœžœžœ˜KšœP˜Pšžœ˜KšœžœEžœ˜qKšœ˜—Kšœ-˜-Kšžœ˜—Kšžœ˜—Kšžœ˜—š žœžœžœžœ ˜IKšœ žœ˜Kšžœ˜—˜K˜——KšžœW˜]K˜K˜—š‘ œžœžœžœžœžœdžœ žœ˜ΓKšœ³™³Kšžœ˜Kšžœ žœžœžœ˜#Kšœ'˜'Kšžœžœžœžœ˜*KšœK˜KKšžœžœ˜Kšœ˜K˜—š‘ œžœžœžœ`˜ŒKšžœ˜KšœF˜FK˜K˜—š ‘œžœžœžœžœžœ`˜–Kšœžœžœ˜ Kšœžœžœž œ˜+K™Kš£€ ™Kš€G™GKš£€™ Kš€L™LK˜Kšœ žœžœ˜0Kšžœ žœžœ˜Kš œžœžœžœžœ˜2Kšžœžœžœ ˜?Kšžœžœ ˜(šžœ(žœžœž˜:Kšœ9˜9Kšžœžœžœžœžœžœžœžœ *˜ŒKšžœ˜Kš žœžœžœžœ  ˜VKšžœ˜Kšžœ˜—Kšžœ˜šžœ,žœžœž˜>Kšœ žœžœ$˜8Kšœ žœžœ$˜8Kšœžœžœžœ˜Q—Kšžœ˜Kšœ*˜*Kšœ*˜*Kšœ žœžœ˜AKš œžœžœžœžœ˜2Kšžœžœžœ ˜?šžœ,žœžœž˜>Kšœžœžœžœ˜9—šžœžœžœžœžœžœžœ˜;Kšœžœžœ˜'Kšœžœ2˜=Kšžœ˜šžœžœ˜8Kšžœžœ˜š žœžœžœžœž˜-Kšœžœ˜ Kšœžœ˜ šžœ žœžœ"˜3Kš žœžœžœ žœ žœ ˜DKšžœžœžœ žœ˜/———Kšœžœ˜—šžœ ž˜Kšœžœ˜ Kšžœ˜Kšœžœžœžœ˜:šžœžœž˜Kšœ&˜&Kšœ,˜,Kšžœžœ˜—Kšžœ˜Kšžœ˜—Kšžœ˜Kšœ˜K˜—š‘œžœž œ žœ˜+Kšœžœžœ˜ KšžœcžœEžœ˜»Kšžœžœžœžœ˜Kšœ˜Kšžœ˜!Kšœ˜Kšžœ˜!Kšžœ ˜ K˜K˜—š‘œžœ žœ˜-Kšœžœžœ˜ Kšœžœžœ˜Kšœ žœ˜Kšœžœžœ%˜1KšœQžœDžœ˜’Kšžœžœžœžœ˜šž˜Kš œ žœžœžœžœ˜LKšžœžœžœ˜Kšœ,˜,Kšžœžœžœ˜Kšžœ˜—Kšœ˜Kšžœ ˜ Kšœ˜K˜—š‘œžœ˜Kšžœ˜Kšœ˜Kšœ˜K˜—š‘œžœ˜Kšžœ˜Kšœ ˜2Kš žœ žœžœžœžœ˜4Kšœ˜K˜—š‘œžœ˜Kš œ ™%Kšžœ˜Kšœ˜Kšœ˜K˜—š‘œžœ˜Kšžœ˜Jšœžœ˜ Kšœ˜K˜—š ‘ œžœžœžœžœ˜XKšΡbfk£€™Kš€™Kšœžœžœ˜ Kšœ žœžœ˜