-- Copyright (C) 1984 by Xerox Corporation. All rights reserved.
-- TestFlukeServer.mesa, HGM, 8-Jan-84 4:41:19
DIRECTORY
FormSW USING [
AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem],
Inline USING [BITAND, BytePair, HighByte, LowByte],
Put USING [Char, CR, Line, LongDecimal, LongNumber, Number, Text],
Runtime USING [GetBcdTime],
String USING [AppendString],
System USING [GetClockPulses, Microseconds, Pulses, PulsesToMicroseconds],
Time USING [Append, Unpack],
Tool USING [Create, MakeSWsProc, MakeFormSW, MakeFileSW, UnusedLogName],
ToolWindow USING [TransitionProcType],
UserInput USING [UserAbort],
Window USING [Handle],
MesaRPC USING [CallFailed, ImportFailed],
Multibus USING [IOAddress, Input, Output, RawRead],
MultibusRpcControl USING [ImportInterface, UnimportInterface],
MultibusAddresses USING [eprom, IOAddress, timeout];
TestFlukeServer: PROGRAM
IMPORTS
FormSW, Inline, Put, Runtime, String, System, Time, Tool, UserInput,
MesaRPC, Multibus, MultibusRpcControl =
BEGIN
target: LONG STRING ← NIL;
Echo: FormSW.ProcType =
BEGIN
start, end: System.Pulses;
cycles: LONG CARDINAL ← 0;
ms: LONG CARDINAL;
noBind: BOOLEAN ← FALSE;
harmless: Multibus.IOAddress ← LOOPHOLE[69000H]; -- DES Chip
start ← System.GetClockPulses[];
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
end ← System.GetClockPulses[];
ms ← System.PulsesToMicroseconds[[end-start]]/1000;
Put.Text[log, "It took "L];
Put.LongDecimal[log, ms];
Put.Line[log, " ms to Import Multibus."L];
start ← System.GetClockPulses[];
FOR i: CARDINAL IN [0..1000) DO
[] ← Multibus.Input[harmless];
Multibus.Output[0, harmless];
cycles ← cycles + 1;
ENDLOOP;
end ← System.GetClockPulses[];
ms ← System.PulsesToMicroseconds[[end-start]]/1000;
Put.Text[log, "It took "L];
Put.LongDecimal[log, ms];
Put.Text[log, " ms to read and write something "L];
Put.LongDecimal[log, cycles];
Put.Line[log, " times."L];
MultibusRpcControl.UnimportInterface[];
Put.CR[log];
END;
EERom: FormSW.ProcType =
BEGIN
base: POINTER = LOOPHOLE[writePulse];
noBind: BOOLEAN ← FALSE;
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
FOR i: CARDINAL IN [0..2048) DO
where: POINTER = base+i;
data: WORD ← ReadWord[where];
IF (i MOD 8H) = 0H THEN
BEGIN
IF UserInput.UserAbort[log] THEN EXIT;
Put.CR[log];
Put.Number[log, where, [16, FALSE, TRUE, 6]];
Put.Text[log, "/ "L];
END;
Put.Number[log, data, [16, FALSE, TRUE, 5]];
ENDLOOP;
Put.CR[log];
MultibusRpcControl.UnimportInterface[];
Put.CR[log];
END;
Jim: FormSW.ProcType =
BEGIN
base: POINTER = LOOPHOLE[writePulse];
noBind: BOOLEAN ← FALSE;
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
FOR i: CARDINAL IN [0..2048) DO
where: POINTER = base+i;
data: WORD ← ReadByte[where, 4];
IF (i MOD 10H) = 0H THEN
BEGIN
IF UserInput.UserAbort[log] THEN EXIT;
Put.CR[log];
Put.Number[log, where, [16, FALSE, TRUE, 6]];
Put.Text[log, "/ "L];
END;
Put.Number[log, data, [16, FALSE, TRUE, 3]];
ENDLOOP;
Put.CR[log];
MultibusRpcControl.UnimportInterface[];
Put.CR[log];
END;
EPROM0: FormSW.ProcType =
BEGIN
base: POINTER = LOOPHOLE[0C000H]; -- 2764 needs high bits on
noBind: BOOLEAN ← FALSE;
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
FOR i: CARDINAL IN [0..8192) DO
where: POINTER = base+i;
data: WORD ← ReadByte[where, 0];
IF (i MOD 10H) = 0H THEN
BEGIN
IF UserInput.UserAbort[log] THEN EXIT;
Put.CR[log];
Put.Number[log, where, [16, FALSE, TRUE, 6]];
Put.Text[log, "/ "L];
END;
Put.Number[log, data, [16, FALSE, TRUE, 3]];
ENDLOOP;
Put.CR[log];
MultibusRpcControl.UnimportInterface[];
Put.CR[log];
END;
eprom: Multibus.IOAddress = MultibusAddresses.eprom;
timeout: Multibus.IOAddress = MultibusAddresses.timeout;
writePulse: WORD = 0800H; -- NB: Low TRUE
ReadWord: PROCEDURE [loc: POINTER] RETURNS [data: WORD] =
BEGIN
temp: Inline.BytePair;
Multibus.Output[Inline.HighByte[loc], eprom + 00DH]; -- Port A Data
Multibus.Output[Inline.LowByte[loc], eprom + 00EH]; -- Port B Data
Multibus.Output[0FFH, timeout + 023H]; -- Port A Direction ← All in
Multibus.Output[000H, eprom + 00FH]; -- Port C Data ← Output Enable
Multibus.Output[005H, timeout + 00EH]; -- Port B Data ← High Byte
temp.high ← Multibus.Input[timeout + 00DH]; -- Port A Data
Multibus.Output[004H, timeout + 00EH]; -- Port B Data ← Low Byte
temp.low ← Multibus.Input[timeout + 00DH]; -- Port A Data
Multibus.Output[008H, eprom + 00FH]; -- Port C Data ← No Output Enable
Multibus.Output[00FH, timeout + 00EH]; -- Port B Data ← Idle
RETURN[LOOPHOLE[temp]];
END;
ReadByte: PROCEDURE [loc: POINTER, chip: CARDINAL] RETURNS [data: WORD] =
BEGIN
Multibus.Output[Inline.HighByte[loc], eprom + 00DH]; -- Port A Data
Multibus.Output[Inline.LowByte[loc], eprom + 00EH]; -- Port B Data
Multibus.Output[0FFH, timeout + 023H]; -- Port A Direction ← All in
Multibus.Output[000H, eprom + 00FH]; -- Port C Data ← Output Enable
Multibus.Output[chip, timeout + 00EH]; -- Port B Data ← High Byte
data ← Multibus.Input[timeout + 00DH]; -- Port A Data
Multibus.Output[008H, eprom + 00FH]; -- Port C Data ← No Output Enable
Multibus.Output[00FH, timeout + 00EH]; -- Port B Data ← Idle
END;
Map: FormSW.ProcType =
BEGIN
noBind: BOOLEAN ← FALSE;
map: LONG POINTER = LOOPHOLE[10000H];
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
FOR i: CARDINAL IN [0..20) DO
where: LONG POINTER = map + i;
data: WORD ← Multibus.RawRead[where];
Put.LongNumber[log, where, [16, FALSE, TRUE, 5]];
Put.Text[log, "/ "L];
Put.Number[log, data, [16, FALSE, TRUE, 5]];
Put.CR[log];
ENDLOOP;
MultibusRpcControl.UnimportInterface[];
Put.CR[log];
END;
Boot: FormSW.ProcType =
BEGIN
noBind: BOOLEAN ← FALSE;
map: LONG POINTER = LOOPHOLE[10000H];
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
FOR i: CARDINAL IN [0..100) DO
ENABLE MesaRPC.CallFailed => EXIT;
Multibus.Output[001H, timeout + 000H]; -- Master Interrupt Control ← Reset
Multibus.Output[000H, timeout + 000H]; -- Master Interrupt Control ← No Reset
Multibus.Output[00EH, timeout + 006H]; -- Port C Direction ← Bit 0 ← output
Multibus.Output[000H, timeout + 00FH]; -- Port C Data ← 0
Multibus.Output[010H, timeout + 001H]; -- Master Config Control ← Enable Port C
Put.Char[log, '!];
ENDLOOP;
MultibusRpcControl.UnimportInterface[];
Put.CR[log];
END;
Random: FormSW.ProcType =
BEGIN
noBind: BOOLEAN ← FALSE;
ones, zeros, up, down: LONG CARDINAL ← 0;
state: {idle, wasOne, wasZero} ← idle;
MultibusRpcControl.ImportInterface[[NIL, target] !
MesaRPC.ImportFailed =>
BEGIN
noBind ← TRUE;
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];
CONTINUE;
END];
IF noBind THEN RETURN;
FOR i: CARDINAL IN [0..5000) DO
where: LONG POINTER = timeout + 00FH; -- Port C Data
data: WORD ← Multibus.Input[where];
bit: WORD ← Inline.BITAND[data, 008H];
IF i < 500 THEN
BEGIN
Put.Number[log, bit, [16, FALSE, TRUE, 1]];
IF (i MOD 50) = 49 THEN Put.CR[log];
END;
IF bit = 0 THEN zeros ← zeros + 1
ELSE ones ← ones + 1;
SELECT state FROM
idle => IF bit = 0 THEN state ← wasZero ELSE state ← wasOne;
wasOne => BEGIN IF bit = 0 THEN down ← down + 1; state ← idle; END;
wasZero => BEGIN IF bit # 0 THEN up ← up + 1; state ← idle; END;
ENDCASE => ERROR;
IF UserInput.UserAbort[log] THEN EXIT;
ENDLOOP;
MultibusRpcControl.UnimportInterface[];
Put.Text[log, "Ones: "L];
Put.LongDecimal[log, ones];
Put.Text[log, " "L];
Put.LongDecimal[log, ones*100/(ones+zeros)];
Put.Text[log, "%, Zeros: "L];
Put.LongDecimal[log, zeros];
Put.Text[log, " "L];
Put.LongDecimal[log, zeros*100/(ones+zeros)];
Put.Text[log, "%."L];
Put.CR[log];
IF (up + down) > 0 THEN
BEGIN
Put.Text[log, "Up: "L];
Put.LongDecimal[log, up];
Put.Text[log, " "L];
Put.LongDecimal[log, up*100/(up+down)];
Put.Text[log, "%, Down: "L];
Put.LongDecimal[log, down];
Put.Text[log, " "L];
Put.LongDecimal[log, down*100/(up+down)];
Put.Text[log, "%."L];
Put.CR[log];
Put.Text[log, "Hit rate: "L];
Put.LongDecimal[log, (up+down)*100/(ones+zeros)];
Put.Text[log, "%."L];
Put.CR[log];
END;
END;
form, log: PUBLIC Window.Handle ← NIL;
Init: PROCEDURE =
BEGIN
herald: STRING = [100];
String.AppendString[herald, "TestFlukeServer of "L];
Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]];
[] ← Tool.Create[
name: herald, makeSWsProc: MakeSWs,
clientTransition: ClientTransition];
END;
MakeSWs: Tool.MakeSWsProc =
BEGIN
logFileName: STRING = [40];
Tool.UnusedLogName[logFileName, "TestFlukeServer.log$"L];
form ← Tool.MakeFormSW[window: window, formProc: MakeForm];
log ← Tool.MakeFileSW[window: window, name: logFileName];
END;
MakeForm: FormSW.ClientItemsProcType =
BEGIN
nParams: CARDINAL = 8;
items ← FormSW.AllocateItemDescriptor[nParams];
items[0] ← FormSW.CommandItem[tag: "Echo"L, proc: Echo, place: FormSW.newLine];
items[1] ← FormSW.CommandItem[tag: "EERom"L, proc: EERom];
items[2] ← FormSW.CommandItem[tag: "Jim"L, proc: Jim];
items[3] ← FormSW.CommandItem[tag: "EPROM0"L, proc: EPROM0];
items[4] ← FormSW.CommandItem[tag: "Map"L, proc: Map];
items[5] ← FormSW.CommandItem[tag: "Boot"L, proc: Boot];
items[6] ← FormSW.CommandItem[tag: "Random"L, proc: Random];
items[7] ← FormSW.StringItem[tag: "Target"L, string: @target, inHeap: TRUE];
RETURN[items, TRUE];
END;
ClientTransition: ToolWindow.TransitionProcType =
BEGIN IF new = inactive THEN form ← log ← NIL; END;
Init[];
END.