-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- TestMultibusPath.mesa, HGM, 7-May-83 18:41:16 DIRECTORY Environment USING [Block, Byte], FormSW USING [ AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem], Format USING [StringProc], Inline USING [BITSHIFT, BITXOR, HighByte, LowByte], Process USING [Yield], Put USING [CR, Line, LongDecimal, Octal, Text], Runtime USING [GetBcdTime], String USING [AppendString], System USING [GetClockPulses, Microseconds, Pulses, PulsesToMicroseconds], TextSW USING [ForceOutput], Time USING [Append, Unpack], Tool USING [Create, MakeFormSW, MakeFileSW, MakeSWsProc, UnusedLogName], ToolWindow USING [TransitionProcType], UserInput USING [ReturnToNotifier, UserAbort], Window USING [Handle], CP USING [RealCS, wordsPerBank], CPMI USING [AD, AF, AS, FS01, FS23, FX, FY, FZ, MI], MesaRPC USING [ImportFailed], Multibus USING [IOAddress, Input, Output], MultibusAddresses USING [IOAddress, controlStore], MultibusRpcControl USING [ImportInterface, UnimportInterface]; TestMultibusPath: PROGRAM IMPORTS FormSW, Inline, Process, Put, Runtime, String, System, TextSW, Time, Tool, UserInput, MesaRPC, Multibus, MultibusRpcControl = BEGIN form, log: Window.Handle; target: LONG STRING ← NIL; wordsToTest: CARDINAL = CP.wordsPerBank; -- Stomp on Kernel Error: SIGNAL [reason: LONG STRING] = CODE; Hickup: SIGNAL [reason: LONG STRING, cs: CP.RealCS, expected: CPMI.MI] = CODE; Three: TYPE = RECORD [a, b, c: WORD]; WriteInfo: PROCEDURE [reason: LONG STRING, cs: CP.RealCS, expected: CPMI.MI] = BEGIN foo: Three = LOOPHOLE[expected]; TailMessage[""L]; NewMessage[reason]; AppendMessage[": cs = "L]; Put.Octal[log, cs]; AppendMessage[", result = "L]; Put.Octal[log, foo.a]; AppendMessage[" "L]; Put.Octal[log, foo.b]; AppendMessage[" "L]; Put.Octal[log, foo.c]; TextSW.ForceOutput[log]; END; TestBank1: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; Hickup => BEGIN WriteInfo[reason, cs, expected]; IF UserInput.UserAbort[log] THEN CONTINUE; RESUME; END; END; PostMessage["Testing Bank 1 of control store (! = 64 wds)"L]; MakeContact[]; TailMessage[""L]; FOR cs: CP.RealCS IN [1*CP.wordsPerBank..1*wordsToTest+CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; address: CPMI.MI = LOOPHOLE[Three[cs, 0, cs]]; -- parity result: CPMI.MI; IF UserInput.UserAbort[log] THEN EXIT; SELECT TRUE FROM (cs = CP.wordsPerBank) => NULL; ((cs MOD 64) = 0) => AppendMessage["!"L]; ENDCASE => NULL; WriteCS[cs, zeros]; result ← ReadCS[cs]; IF result # zeros THEN SIGNAL Hickup["Didn't get zeros back"L, cs, result]; WriteCS[cs, ones]; result ← ReadCS[cs]; IF result # ones THEN SIGNAL Hickup["Didn't get ones back"L, cs, result]; WriteCS[cs, address]; result ← ReadCS[cs]; IF result # address THEN SIGNAL Hickup["Didn't get address back"L, cs, result]; Process.Yield[]; ENDLOOP; TailMessage[" ok"L]; IF UserInput.UserAbort[log] THEN RETURN; NewMessage["Check pass ... (! = 64 wds)"L]; TailMessage[""L]; FOR cs: CP.RealCS IN [1*CP.wordsPerBank..1*wordsToTest+CP.wordsPerBank) DO address: CPMI.MI = LOOPHOLE[Three[cs, 0, cs]]; result: CPMI.MI; IF UserInput.UserAbort[log] THEN EXIT; SELECT TRUE FROM (cs = CP.wordsPerBank) => NULL; ((cs MOD 64) = 0) => AppendMessage["!"L]; ENDCASE => NULL; result ← ReadCS[cs]; IF result # address THEN SIGNAL Hickup["Didn't get address back"L, cs, result]; ENDLOOP; TailMessage[" ok"L]; END; WriteBank1: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Writing Bank 1 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [1*CP.wordsPerBank..1*wordsToTest+CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; IF UserInput.UserAbort[log] THEN EXIT; WriteCS[cs, zeros]; WriteCS[cs, ones]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; ReadBank1: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Reading Bank 1 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [1*CP.wordsPerBank..1*wordsToTest+CP.wordsPerBank) DO IF UserInput.UserAbort[log] THEN EXIT; [] ← ReadCS[cs]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; WriteReadBank1: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Writing and Reading Bank 1 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [1*CP.wordsPerBank..wordsToTest+1*CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; IF UserInput.UserAbort[log] THEN EXIT; WriteCS[cs, zeros]; [] ← ReadCS[cs]; WriteCS[cs, ones]; [] ← ReadCS[cs]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; TestBank2: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; Hickup => BEGIN WriteInfo[reason, cs, expected]; IF UserInput.UserAbort[log] THEN CONTINUE; RESUME; END; END; PostMessage["Testing Bank 2 of control store (! = 64 wds)"L]; MakeContact[]; TailMessage[""L]; FOR cs: CP.RealCS IN [2*CP.wordsPerBank..2*wordsToTest+CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; address: CPMI.MI = LOOPHOLE[Three[cs, 0, cs]]; -- parity result: CPMI.MI; IF UserInput.UserAbort[log] THEN EXIT; SELECT TRUE FROM (cs = CP.wordsPerBank) => NULL; ((cs MOD 64) = 0) => AppendMessage["!"L]; ENDCASE => NULL; WriteCS[cs, zeros]; result ← ReadCS[cs]; IF result # zeros THEN SIGNAL Hickup["Didn't get zeros back"L, cs, result]; WriteCS[cs, ones]; result ← ReadCS[cs]; IF result # ones THEN SIGNAL Hickup["Didn't get ones back"L, cs, result]; WriteCS[cs, address]; result ← ReadCS[cs]; IF result # address THEN SIGNAL Hickup["Didn't get address back"L, cs, result]; Process.Yield[]; ENDLOOP; TailMessage[" ok"L]; IF UserInput.UserAbort[log] THEN RETURN; NewMessage["Check pass ... (! = 64 wds)"L]; TailMessage[""L]; FOR cs: CP.RealCS IN [2*CP.wordsPerBank..2*wordsToTest+CP.wordsPerBank) DO address: CPMI.MI = LOOPHOLE[Three[cs, 0, cs]]; result: CPMI.MI; IF UserInput.UserAbort[log] THEN EXIT; SELECT TRUE FROM (cs = CP.wordsPerBank) => NULL; ((cs MOD 64) = 0) => AppendMessage["!"L]; ENDCASE => NULL; result ← ReadCS[cs]; IF result # address THEN SIGNAL Hickup["Didn't get address back"L, cs, result]; ENDLOOP; TailMessage[" ok"L]; END; WriteBank2: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Writing Bank 2 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [2*CP.wordsPerBank..2*wordsToTest+CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; IF UserInput.UserAbort[log] THEN EXIT; WriteCS[cs, zeros]; WriteCS[cs, ones]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; ReadBank2: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Reading Bank 2 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [2*CP.wordsPerBank..2*wordsToTest+CP.wordsPerBank) DO IF UserInput.UserAbort[log] THEN EXIT; [] ← ReadCS[cs]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; WriteReadBank2: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Writing and Reading Bank 2 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [2*CP.wordsPerBank..wordsToTest+2*CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; IF UserInput.UserAbort[log] THEN EXIT; WriteCS[cs, zeros]; [] ← ReadCS[cs]; WriteCS[cs, ones]; [] ← ReadCS[cs]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; TestBank3: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; Hickup => BEGIN WriteInfo[reason, cs, expected]; IF UserInput.UserAbort[log] THEN CONTINUE; RESUME; END; END; PostMessage["Testing Bank 3 of control store (! = 64 wds)"L]; MakeContact[]; TailMessage[""L]; FOR cs: CP.RealCS IN [3*CP.wordsPerBank..3*wordsToTest+CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; address: CPMI.MI = LOOPHOLE[Three[cs, 0, cs]]; -- parity result: CPMI.MI; IF UserInput.UserAbort[log] THEN EXIT; SELECT TRUE FROM (cs = CP.wordsPerBank) => NULL; ((cs MOD 64) = 0) => AppendMessage["!"L]; ENDCASE => NULL; WriteCS[cs, zeros]; result ← ReadCS[cs]; IF result # zeros THEN SIGNAL Hickup["Didn't get zeros back"L, cs, result]; WriteCS[cs, ones]; result ← ReadCS[cs]; IF result # ones THEN SIGNAL Hickup["Didn't get ones back"L, cs, result]; WriteCS[cs, address]; result ← ReadCS[cs]; IF result # address THEN SIGNAL Hickup["Didn't get address back"L, cs, result]; Process.Yield[]; ENDLOOP; TailMessage[" ok"L]; IF UserInput.UserAbort[log] THEN RETURN; NewMessage["Check pass ... (! = 64 wds)"L]; TailMessage[""L]; FOR cs: CP.RealCS IN [3*CP.wordsPerBank..3*wordsToTest+CP.wordsPerBank) DO address: CPMI.MI = LOOPHOLE[Three[cs, 0, cs]]; result: CPMI.MI; IF UserInput.UserAbort[log] THEN EXIT; SELECT TRUE FROM (cs = CP.wordsPerBank) => NULL; ((cs MOD 64) = 0) => AppendMessage["!"L]; ENDCASE => NULL; result ← ReadCS[cs]; IF result # address THEN SIGNAL Hickup["Didn't get address back"L, cs, result]; ENDLOOP; TailMessage[" ok"L]; END; WriteBank3: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Writing Bank 3 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [3*CP.wordsPerBank..3*wordsToTest+CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; IF UserInput.UserAbort[log] THEN EXIT; WriteCS[cs, zeros]; WriteCS[cs, ones]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; ReadBank3: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Reading Bank 3 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [3*CP.wordsPerBank..3*wordsToTest+CP.wordsPerBank) DO IF UserInput.UserAbort[log] THEN EXIT; [] ← ReadCS[cs]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; WriteReadBank3: FormSW.ProcType = BEGIN ENABLE BEGIN Error => BEGIN TailMessage[reason]; CONTINUE; END; END; PostMessage["Writing and Reading Bank 3 of control store"L]; MakeContact[]; TailMessage[""L]; UNTIL UserInput.UserAbort[log] DO FOR cs: CP.RealCS IN [3*CP.wordsPerBank..wordsToTest+3*CP.wordsPerBank) DO zeros: CPMI.MI = LOOPHOLE[Three[0, 0, 0]]; ones: CPMI.MI = LOOPHOLE[Three[177777B, 177777B, 177777B]]; IF UserInput.UserAbort[log] THEN EXIT; WriteCS[cs, zeros]; [] ← ReadCS[cs]; WriteCS[cs, ones]; [] ← ReadCS[cs]; Process.Yield[]; ENDLOOP; AppendMessage["!"L]; ENDLOOP; TailMessage[" ok"L]; END; LogString: Format.StringProc = BEGIN Put.Text[clientData, s]; END; PostMessage: PROCEDURE [s: LONG STRING, clear: BOOLEAN ← TRUE] = BEGIN Put.CR[log]; Put.Text[log, s]; TextSW.ForceOutput[log] END; NewMessage: PROCEDURE [s: LONG STRING, clear: BOOLEAN ← TRUE] = BEGIN Put.Text[log, s]; TextSW.ForceOutput[log] END; AppendMessage: PROCEDURE [s: LONG STRING] = BEGIN Put.Text[log, s]; TextSW.ForceOutput[log] END; TailMessage: PROCEDURE [s: LONG STRING] = BEGIN Put.Text[log, s]; Put.Line[log, "."L]; TextSW.ForceOutput[log] END; Initialize: PROCEDURE = BEGIN herald: STRING = [100]; String.AppendString[herald, "TestMultibusPath of "L]; Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]]; [] ← Tool.Create[ name: herald, cmSection: "TestMultibusPath"L, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; MakeSWs: Tool.MakeSWsProc = BEGIN logFileName: STRING = [40]; form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; Tool.UnusedLogName[logFileName, "CSBankTester.log$"L]; log ← Tool.MakeFileSW[window: window, name: logFileName]; END; MakeForm: FormSW.ClientItemsProcType = BEGIN i: INTEGER ← -1; nParams: CARDINAL = 13; items ← FormSW.AllocateItemDescriptor[nParams]; items[i←i+1] ← FormSW.StringItem[tag: "Target"L, string: @target, inHeap: TRUE, place: FormSW.newLine]; items[i←i+1] ← FormSW.CommandItem[tag: "TestBank1"L, proc: TestBank1, place: FormSW.newLine]; items[i←i+1] ← FormSW.CommandItem[tag: "WriteBank1"L, proc: WriteBank1]; items[i←i+1] ← FormSW.CommandItem[tag: "ReadBank1"L, proc: ReadBank1]; items[i←i+1] ← FormSW.CommandItem[tag: "WriteReadBank1"L, proc: WriteReadBank1]; items[i←i+1] ← FormSW.CommandItem[tag: "TestBank2"L, proc: TestBank2, place: FormSW.newLine]; items[i←i+1] ← FormSW.CommandItem[tag: "WriteBank2"L, proc: WriteBank2]; items[i←i+1] ← FormSW.CommandItem[tag: "ReadBank2"L, proc: ReadBank2]; items[i←i+1] ← FormSW.CommandItem[tag: "WriteReadBank2"L, proc: WriteReadBank2]; items[i←i+1] ← FormSW.CommandItem[tag: "TestBank3"L, proc: TestBank3, place: FormSW.newLine]; items[i←i+1] ← FormSW.CommandItem[tag: "WriteBank3"L, proc: WriteBank3]; items[i←i+1] ← FormSW.CommandItem[tag: "ReadBank3"L, proc: ReadBank3]; items[i←i+1] ← FormSW.CommandItem[tag: "WriteReadBank3"L, proc: WriteReadBank3]; IF (i+1) # nParams THEN ERROR; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => BEGIN END; new = inactive => BEGIN END; ENDCASE; END; -- Adapted from CPKernelCSDicentra ReadCS: PROCEDURE [real: CP.RealCS] RETURNS [CPMI.MI] = BEGIN block: Environment.Block ← [LOOPHOLE[LONG[@data]], 0, 2*SIZE[MIReal]]; data: MIReal; WriteWord[csaMsb, real]; ReadBlock[csData0, block]; RETURN[RealToVirtural[data]]; END; WriteCS: PROCEDURE [real: CP.RealCS, mi: CPMI.MI] = BEGIN realMi: MIReal ← VirturalToReal[mi]; words: POINTER = @realMi; temp: PACKED ARRAY [0..8) OF Environment.Byte; block: Environment.Block ← [LOOPHOLE[LONG[@temp]], 0, 8]; FixParity[@realMi]; temp[0] ← Inline.HighByte[real]; temp[1] ← Inline.LowByte[real]; temp[2] ← Inline.HighByte[(words+0)↑]; temp[3] ← Inline.LowByte[(words+0)↑]; temp[4] ← Inline.HighByte[(words+1)↑]; temp[5] ← Inline.LowByte[(words+1)↑]; temp[6] ← Inline.HighByte[(words+2)↑]; temp[7] ← Inline.LowByte[(words+2)↑]; WriteBlock[csaMsb, block]; END; FixParity: PROCEDURE [data: LONG POINTER TO MIReal] = BEGIN words: LONG POINTER = data; parity: WORD ← 0; data.ep ← FALSE; FOR i: CARDINAL IN [0..SIZE[MIReal]) DO parity ← Inline.BITXOR[parity, (words+i)↑]; ENDLOOP; parity ← Inline.BITXOR[parity, Inline.BITSHIFT[parity, -8]]; parity ← Inline.BITXOR[parity, Inline.BITSHIFT[parity, -4]]; parity ← Inline.BITXOR[parity, Inline.BITSHIFT[parity, -2]]; parity ← Inline.BITXOR[parity, Inline.BITSHIFT[parity, -1]]; data.ep ← LOOPHOLE[parity]; END; MIReal: TYPE = MACHINE DEPENDENT RECORD [ rA, rB: [0..0FH], aS: CPMI.AS, aF: CPMI.AF, aD: CPMI.AD, --word 0 ep, cIn, enSU, mem: BOOLEAN, fS01: CPMI.FS01, fS23: CPMI.FS23, fX: CPMI.FX, fY: CPMI.FY, --word 1 fZ: CPMI.FZ, inia: [0..CP.wordsPerBank)]; --word 2 -- See also FixupMI in MakeControlStoreMB VirturalToReal: PROCEDURE [virtural: CPMI.MI] RETURNS [real: MIReal] = BEGIN mir: POINTER TO MIReal = @real; miv: POINTER TO CPMI.MI = @virtural; BEGIN OPEN miv; mir↑ ← [ rA, rB, aS, aF, aD, ep, cIn, enSU, mem, fS01, fS23, fX, fY, fZ, Inline.BITXOR[inia,17B]] END END; RealToVirtural: PROCEDURE [real: MIReal] RETURNS [virtural: CPMI.MI] = BEGIN mir: POINTER TO MIReal = @real; miv: POINTER TO CPMI.MI = @virtural; BEGIN OPEN mir; miv↑ ← [ rA, rB, aS, aF, aD, ep, cIn, enSU, mem, fS01, fS23, fX, fY, fZ, Inline.BITXOR[inia,17B]] END; END; -- Copied from Teather and/or TestDebuggerBoard baseAddress: MultibusAddresses.IOAddress = MultibusAddresses.controlStore; finger: MultibusAddresses.IOAddress = baseAddress + 0; contents: MultibusAddresses.IOAddress = baseAddress + 1; Register: TYPE = MACHINE DEPENDENT { -- Control Store section starts at 0 csaMsb(0B), csaLsb(1B), csData0(2B), csData1(3B), csData2(4B), csData3(5B), csData4(6B), csData5(7B), niaMsb(10B), niaLsb(11B), temp(12B), -- History Buffer section starts at 20B hbAddr(20B), hbPCMsb(21B), hbPCLsb(22B), hbPCExtra(23B), hbMatchMsb(24B), hbMatchLsb(25B), hbCount(26B), hbBits(27B), (377B) }; WriteWord: PROCEDURE [reg: Register, data: WORD] = BEGIN Multibus.Output[reg, finger]; Multibus.Output[Inline.HighByte[data], contents]; Multibus.Output[Inline.LowByte[data], contents]; END; ReadBlock: PROCEDURE [reg: Register, block: Environment.Block] = BEGIN Multibus.Output[reg, finger]; FOR i: CARDINAL IN [block.startIndex..block.stopIndexPlusOne) DO block.blockPointer[i] ← Multibus.Input[contents]; ENDLOOP; END; WriteBlock: PROCEDURE [reg: Register, block: Environment.Block] = BEGIN Multibus.Output[reg, finger]; FOR i: CARDINAL IN [block.startIndex..block.stopIndexPlusOne) DO Multibus.Output[block.blockPointer[i], contents]; ENDLOOP; END; -- From TestFlukeServer bound: BOOLEAN ← FALSE; MakeContact: PROCEDURE = BEGIN start, end: System.Pulses; ms: LONG CARDINAL; IF bound THEN MultibusRpcControl.UnimportInterface[]; bound ← FALSE; start ← System.GetClockPulses[]; MultibusRpcControl.ImportInterface[[NIL, target] ! MesaRPC.ImportFailed => BEGIN Put.Text[log, "Import from "L]; Put.Text[log, target]; Put.Text[log, " failed: "L]; SELECT why FROM communications => Put.Text[log, "communications"L]; badInstance => Put.Text[log, "badInstance"L]; badVersion => Put.Text[log, "badVersion"L]; wrongVersion => Put.Text[log, "wrongVersion"L]; unbound => Put.Text[log, "unbound"L]; stubProtocol => Put.Text[log, "stubProtocol"L]; ENDCASE => Put.Text[log, "??"L]; Put.Line[log, "."L]; UserInput.ReturnToNotifier["Import failed"L]; END]; bound ← TRUE; end ← System.GetClockPulses[]; ms ← System.PulsesToMicroseconds[[end-start]]/1000; Put.Line[log, "."L]; Put.Text[log, "It took "L]; Put.LongDecimal[log, ms]; Put.Text[log, " ms to Import Multibus"L]; END; Initialize[]; END.