-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- TestChecksums.mesa, HGM, 9-Jan-83 21:53:25 DIRECTORY Checksum USING [ComputeChecksum, ComputeChecksumSoftware, ComputeChecksumProc], ESCAlpha USING [aROTATE], FormSW USING [ AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem], Heap USING [systemZone], Mopcodes USING [zACD, zADD, zDUP, zINC, zLI0, zLI1, zESC], MsgSW USING [Post], Process USING [Detach, Pause, Yield], Put USING [Line], Runtime USING [GetBcdTime], String USING [ AppendChar, AppendLongNumber, AppendNumber, AppendString, StringToNumber], System USING [GetClockPulses, Microseconds, Pulses, PulsesToMicroseconds], Time USING [Append, Unpack], Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFormSW, MakeFileSW], ToolWindow USING [TransitionProcType], Window USING [Handle]; TestChecksums: PROGRAM IMPORTS Checksum, FormSW, Heap, MsgSW, Process, Put, Runtime, String, System, Time, Tool SHARES Checksum = BEGIN z: UNCOUNTED ZONE = Heap.systemZone; dataSize: CARDINAL = 1000B; data: ARRAY [0..dataSize) OF CARDINAL; msg, form, log: Window.Handle ← NIL; valueString: LONG STRING ← z.NEW[StringBody[6]]; indexString: LONG STRING ← z.NEW[StringBody[6]]; stopIndexString: LONG STRING ← z.NEW[StringBody[6]]; running, pleaseStop: BOOLEAN ← FALSE; Init: PROCEDURE = BEGIN herald: STRING = [100]; String.AppendString[herald, "TestChecksums of "L]; Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]]; [] ← Tool.Create[ name: herald, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; SameProc: FormSW.ProcType = BEGIN stop, i: CARDINAL; error: BOOLEAN ← FALSE; stop ← String.StringToNumber[ stopIndexString, 8 ! ANY => BEGIN MsgSW.Post[msg, "The StopIndex is incorrectly specified; try again."L]; error ← TRUE; CONTINUE; END]; IF error THEN RETURN; FOR i IN [1..stop) DO data[i] ← data[0]; ENDLOOP; END; GeomProc: FormSW.ProcType = BEGIN power, stop, i: CARDINAL; error: BOOLEAN ← FALSE; stop ← String.StringToNumber[ stopIndexString, 8 ! ANY => BEGIN MsgSW.Post[msg, "The StopIndex is incorrectly specified; try again."L]; error ← TRUE; CONTINUE; END]; IF error THEN RETURN; power ← data[1]/data[0]; FOR i IN [2..stop) DO data[i] ← data[i - 1]*power; IF data[i] = 0 THEN data[i] ← data[0]; ENDLOOP; END; FibProc: FormSW.ProcType = BEGIN stop, i: CARDINAL; error: BOOLEAN ← FALSE; stop ← String.StringToNumber[ stopIndexString, 8 ! ANY => BEGIN MsgSW.Post[msg, "The StopIndex is incorrectly specified; try again."L]; error ← TRUE; CONTINUE; END]; IF error THEN RETURN; FOR i IN [2..stop) DO data[i] ← data[i - 1] + data[i - 2]; ENDLOOP; END; ReplaceProc: FormSW.ProcType = BEGIN val, i: CARDINAL; error: BOOLEAN ← FALSE; i ← String.StringToNumber[ indexString, 8 ! ANY => BEGIN MsgSW.Post[msg, "The Index is incorrectly specified; try again."L]; error ← TRUE; CONTINUE; END]; val ← String.StringToNumber[ valueString, 8 ! ANY => BEGIN MsgSW.Post[msg, "The Wordvalue is incorrectly specified; try again."L]; error ← TRUE; CONTINUE; END]; IF i >= dataSize THEN BEGIN MsgSW.Post[msg, "The Index is out of bounds; try again."L]; error ← TRUE; END; IF error THEN RETURN; data[i] ← val; END; StopProc: FormSW.ProcType = BEGIN pleaseStop ← TRUE; WHILE (running) DO Process.Pause[1]; ENDLOOP; END; StartProc: FormSW.ProcType = BEGIN stop: CARDINAL; error: BOOLEAN ← FALSE; stop ← String.StringToNumber[ stopIndexString, 8 ! ANY => BEGIN MsgSW.Post[msg, "The StopIndex is incorrectly specified; try again."L]; error ← TRUE; CONTINUE; END]; IF running THEN BEGIN MsgSW.Post[msg, "A test is already running!"L]; error ← TRUE; END; IF error THEN RETURN; running ← TRUE; pleaseStop ← FALSE; Put.Line[ log, " Ix Value SftChk SfTim emChk emTim % muChk muTim % exChk exTim %"L]; Process.Detach[FORK RunTest[stop]]; END; RunTest: PROCEDURE [stop: CARDINAL] = BEGIN msg: STRING = [128]; softCheckVal, trapCheckVal, microCheckVal, exCheckVal: CARDINAL; beginTime, stopTime: System.Pulses; softCheckTime, trapCheckTime, microCheckTime, exCheckTime: System.Microseconds; len: CARDINAL; where: LONG POINTER; FOR i: CARDINAL IN [0..stop) UNTIL pleaseStop DO len ← i + 1; where ← @data[0]; -- Simple Software beginTime ← System.GetClockPulses[]; softCheckVal ← Software[0, len, where]; stopTime ← System.GetClockPulses[]; softCheckTime ← System.PulsesToMicroseconds[[stopTime - beginTime]]; -- Pseudo Software Support for Microcode beginTime ← System.GetClockPulses[]; trapCheckVal ← Trap[0, len, where]; stopTime ← System.GetClockPulses[]; trapCheckTime ← System.PulsesToMicroseconds[[stopTime - beginTime]]; -- Microcode beginTime ← System.GetClockPulses[]; microCheckVal ← Checksum.ComputeChecksum[0, len, where]; stopTime ← System.GetClockPulses[]; microCheckTime ← System.PulsesToMicroseconds[[stopTime - beginTime]]; -- Additional one for experimenting beginTime ← System.GetClockPulses[]; exCheckVal ← ExComputeChecksum[0, len, where]; stopTime ← System.GetClockPulses[]; exCheckTime ← System.PulsesToMicroseconds[[stopTime - beginTime]]; msg.length ← 0; D4[msg, i]; O7[msg, data[i]]; O7[msg, softCheckVal]; LD6[msg, softCheckTime]; O7[msg, trapCheckVal]; LD6[msg, trapCheckTime]; IF softCheckVal # trapCheckVal THEN String.AppendChar[msg, '*] ELSE String.AppendChar[msg, ' ]; trapCheckTime ← (trapCheckTime*100)/softCheckTime; LD3[msg, trapCheckTime]; O7[msg, microCheckVal]; LD6[msg, microCheckTime]; IF softCheckVal # microCheckVal THEN String.AppendChar[msg, '*] ELSE String.AppendChar[msg, ' ]; microCheckTime ← (microCheckTime*100)/softCheckTime; LD2[msg, microCheckTime]; O7[msg, exCheckVal]; LD6[msg, exCheckTime]; IF softCheckVal # exCheckVal THEN String.AppendChar[msg, '*] ELSE String.AppendChar[msg, ' ]; exCheckTime ← (exCheckTime*100)/softCheckTime; LD3[msg, exCheckTime]; Put.Line[log, msg]; Process.Yield[]; ENDLOOP; running ← FALSE; END; D4: PROCEDURE [s: STRING, n: UNSPECIFIED] = BEGIN temp: STRING = [25]; String.AppendNumber[temp, n, 10]; THROUGH [temp.length..4) DO String.AppendChar[s, ' ]; ENDLOOP; String.AppendString[s, temp]; END; LD2: PROCEDURE [s: STRING, n: LONG UNSPECIFIED] = BEGIN temp: STRING = [25]; String.AppendLongNumber[temp, n, 10]; THROUGH [temp.length..2) DO String.AppendChar[s, ' ]; ENDLOOP; String.AppendString[s, temp]; END; LD3: PROCEDURE [s: STRING, n: LONG UNSPECIFIED] = BEGIN temp: STRING = [25]; String.AppendLongNumber[temp, n, 10]; THROUGH [temp.length..3) DO String.AppendChar[s, ' ]; ENDLOOP; String.AppendString[s, temp]; END; LD6: PROCEDURE [s: STRING, n: LONG UNSPECIFIED] = BEGIN temp: STRING = [25]; String.AppendLongNumber[temp, n, 10]; THROUGH [temp.length..6) DO String.AppendChar[s, ' ]; ENDLOOP; String.AppendString[s, temp]; END; O7: PROCEDURE [s: STRING, n: UNSPECIFIED] = BEGIN temp: STRING = [25]; String.AppendNumber[temp, n, 8]; THROUGH [temp.length..7) DO String.AppendChar[s, ' ]; ENDLOOP; String.AppendString[s, temp]; END; -- Put the INLINEs within a procedure to include the XFERs Software: PROCEDURE [cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER] RETURNS [checksum: CARDINAL] = BEGIN RETURN[Checksum.ComputeChecksumSoftware[cs, nWords, p]]; END; Trap: PROCEDURE [cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER] RETURNS [checksum: CARDINAL] = BEGIN RETURN[Checksum.ComputeChecksumProc[cs, nWords, p]]; END; ExComputeChecksum: PROCEDURE [cs: CARDINAL, nWords: CARDINAL, p: LONG POINTER] RETURNS [checksum: CARDINAL] = BEGIN Push: PROC [CARDINAL] = MACHINE CODE BEGIN END; Pop: PROC RETURNS [CARDINAL] = MACHINE CODE BEGIN END; TOS: PROC RETURNS [CARDINAL] = MACHINE CODE BEGIN Mopcodes.zDUP; END; IncTOS: PROC = MACHINE CODE BEGIN Mopcodes.zINC; END; OnesAddAndLeftRotate: PROC [ --cs: CARDINAL,-- wd: CARDINAL] --RETURNS [cs: CARDINAL]-- = MACHINE CODE BEGIN Mopcodes.zLI0; Mopcodes.zACD; Mopcodes.zADD; -- cs ← (cs ONESADD wd) Mopcodes.zLI1; Mopcodes.zESC, ESCAlpha.aROTATE; END; --TOS←-- Push[cs]; -- leave cs on the stack throughout the procedure THROUGH [0..nWords) DO --TOS←-- OnesAddAndLeftRotate[ --cs: TOS,-- wd: p↑]; p ← p + 1 ENDLOOP; IF TOS[] = 177777B THEN IncTOS[]; RETURN[Pop[ --TOS-- ]]; END; MakeSWs: Tool.MakeSWsProc = BEGIN msg ← Tool.MakeMsgSW[window: window, lines: 3]; form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; log ← Tool.MakeFileSW[window: window, name: "Checksum.log$"L]; END; MakeForm: FormSW.ClientItemsProcType = BEGIN i: CARDINAL; nParams: CARDINAL = 9; items ← FormSW.AllocateItemDescriptor[nParams]; items[i ← 0] ← FormSW.CommandItem[ tag: "Same"L, proc: SameProc, place: FormSW.newLine]; items[i ← i + 1] ← FormSW.CommandItem[tag: "Geom"L, proc: GeomProc]; items[i ← i + 1] ← FormSW.CommandItem[tag: "Fib"L, proc: FibProc]; items[i ← i + 1] ← FormSW.CommandItem[tag: "START"L, proc: StartProc]; items[i ← i + 1] ← FormSW.CommandItem[tag: "STOP"L, proc: StopProc]; String.AppendNumber[stopIndexString, dataSize, 8]; items[i ← i + 1] ← FormSW.StringItem[ tag: "StopIndex(octal)"L, string: @stopIndexString, inHeap: TRUE]; items[i ← i + 1] ← FormSW.CommandItem[ tag: "Replace"L, proc: ReplaceProc, place: FormSW.newLine]; String.AppendNumber[indexString, 0, 8]; items[i ← i + 1] ← FormSW.StringItem[ tag: "Index(octal)"L, string: @indexString, boxWidth: 100, inHeap: TRUE]; String.AppendNumber[valueString, 1, 8]; items[i ← i + 1] ← FormSW.StringItem[ tag: "with Value(octal)"L, string: @valueString, inHeap: TRUE]; data[0] ← 1; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN IF new = inactive THEN msg ← form ← NIL; END; -- Mainline code Init[]; -- this gets string out of global frame END...