-- DiagnosticsImplA.mesa - edited by: -- Poskanzer 9-May-83 21:57:46 -- JFung.pasa 17-Nov-83 14:07:43 stopped bouncing -- JFung.pasa 24-Feb-84 16:44:13 accept typein mode -- domain name xsis north caused address fault (915) DIRECTORY Ascii USING [CR, SP], Authenticator USING [firstVerifier, nullCredentials], ByeOps USING [ResumeBouncing, StopBouncing], CH USING [Element, Enumerate, NamePattern, wildCard, zeroMaxLengthNames], CHLookup USING [ Error, FileserverPt, LookupFileserver, LookupMailserver, LookupPrintserver], CHPIDs USING [ch3fileserver, ch3mailserver, ch3printserver], CHStubInternal USING [FindDomainAddr], DiagnosticsOps USING [ EchoUserTest, FloppyCleanReadWriteHeads, FloppyCommandFileTest, FloppyDisplayErrorLog, FloppyExerciser, FloppyFormatDiskette, FloppyStandardTest, Help, KeyboardAndMouseTest, LFDisplayTest, PutMessage, Tests], ExtendedString USING [AppendNumber], Format USING [HostNumber, NetworkNumber, StringProc], FormSW USING [ AllocateItemDescriptor, BooleanItem, ClientItemsProcType, CommandItem, Destroy, Display, DisplayItem, Enumerated, EnumeratedItem, EnumeratedNotifyProcType, FindItem, ItemHandle, newLine, nullIndex, NumberItem, ProcType, StringItem], Heap USING [systemZone], NetworkStream USING [AssignNetworkAddress], NSString USING [AppendToMesaString, StringFromMesaString], OnlineDiagnostics USING [ ErrorHandling, FloppyWhatToDoNext, GetConfirmationProc, GetFloppyChoiceProc, GetYesOrNoProc, SectorLength, YesOrNo], Process USING [Detach], Profile USING [GetDefaultDomain, GetDefaultOrganization, String], Put USING [Char, CR, Line, Text], String USING [ AppendChar, AppendCharAndGrow, AppendLongNumber, AppendNumber, AppendString, AppendStringAndGrow, Copy, CopyToNewString], System USING [NetworkAddress], Tool USING [Create, MakeFileSW, MakeFormSW, MakeSWsProc, UnusedLogName], ToolWindow USING [Activate, Deactivate, TransitionProcType], UserInput USING [CreatePeriodicNotify, PeriodicProcType, UserAbort], UserTerminal USING [BlinkDisplay], Window USING [GetChild, GetParent, Handle, rootWindow, Stack, ValidateTree], WindowFont USING [FontHeight]; DiagnosticsImplA: MONITOR IMPORTS ByeOps, CH, CHLookup, CHStubInternal, DiagnosticsOps, ExtendedString, Format, FormSW, Heap, NetworkStream, NSString, Process, Profile, Put, String, Tool, ToolWindow, UserInput, UserTerminal, Window, WindowFont EXPORTS DiagnosticsOps = BEGIN -- TYPEs ConfirmIndex: TYPE = {confirm, yes, no, continue, loop, display, exit}; FormIndex: TYPE = { help, start, cancel, addCommand, deleteCommand, test, floppyTest, currOrganization, currDomain, thisEthernetID, thisProcessorID, listFS, listPS, listMS, testEthernetID, testProcessorID, doubleDensity, doubleSided, sectorsPerTrack, sectorLength, errorHandling, operation, cmdFile, trackNumber, startingSector, sectorCount, increment, dataWord, loopCount, dataDisplayed}; StringIndex: TYPE = { currOrganization, currDomain, thisEthernetID, thisProcessorID, listFS, listPS, listMS, testEthernetID, testProcessorID, cmdFile}; DataHandle: TYPE = LONG POINTER TO Data; Data: TYPE = MACHINE DEPENDENT RECORD [ -- File subwindow stuff fileSW(0): Window.Handle ← NIL, -- Form subwindow stuff -- Note: enumerateds and booleans must be word boundary -- aligned as addresses for them must be generated confirmSW(2): Window.Handle ← NIL, latestConfirm(4): ConfirmIndex ← confirm, formSW(5): Window.Handle ← NIL, test(7): DiagnosticsOps.Tests ← none, floppyTest(8): FloppyTest ← clean, doubleDensity(9): BOOLEAN ← TRUE, doubleSided(10): BOOLEAN ← FALSE, sectorsPerTrack(11): CARDINAL [8..26] ← 15, sectorLength(12): OnlineDiagnostics.SectorLength ← five12, errorHandling(13): OnlineDiagnostics.ErrorHandling ← stopOnError, operation(14): Operation ← initialize, trackNumber(15): CARDINAL ← 1, startingSector(16): CARDINAL ← 1, sectorCount(17): CARDINAL ← 1, increment(18): INTEGER ← 0, dataWord(19): CARDINAL ← 177777B, loopCount(20): CARDINAL ← 65535, dataDisplayed(21): DataDisplayed ← status, confirming(22): BOOLEAN ← FALSE, -- mode switch - only one formSW active at a time reDisplay(23): BOOLEAN ← FALSE, -- used by the enumerated notify procs inALoop(24): BOOLEAN ← FALSE, -- for the floppy command file test cmdCount(25): [0..cmdMax] ← 0, cmdIndexes(26): ARRAY [0..cmdMax] OF CARDINAL ← ALL[0], -- note unusual indexing strings(127): ARRAY StringIndex OF LONG STRING ← ALL[NIL]]; FloppyTest: TYPE = {clean, standard, summary, format, exercise, cmdFile}; Operation: TYPE = { initialize, recalibrate, readStatus, readHeader, readSectors, writeSectors, writeDeletedSectors, verify, loop, displayData, clearLog, log}; DataDisplayed: TYPE = {status, header, sector, summary}; -- Variable declarations. wh: Window.Handle ← NIL; -- Tool's window toolData: DataHandle ← NIL; -- Tool's data z: UNCOUNTED ZONE = Heap.systemZone; -- Some of the following should probably be in toolData. confirmation: CONDITION; -- to let the GetXXXProc's know when ConfirmCommand has been bugged cmdMax: CARDINAL = 100; running: PUBLIC BOOLEAN ← FALSE; -- whether there is a detached process running calledByBye: PUBLIC BOOLEAN ← FALSE; -- whether we were activated by Bye active: BOOLEAN ← FALSE; -- whether the tool is currently active -- Routines to allow the diagnostics to talk to the window. PutChar: PUBLIC PROCEDURE [ch: CHARACTER, minWidth: CARDINAL ← 0] = BEGIN Put.Char[toolData.fileSW, ch]; THROUGH [1..minWidth) DO Put.Char[toolData.fileSW, Ascii.SP]; ENDLOOP; END; PutCR: PUBLIC PROCEDURE = BEGIN Put.CR[toolData.fileSW]; END; PutText: PUBLIC PROCEDURE [text: LONG STRING, minWidth: CARDINAL ← 0] = BEGIN Put.Text[toolData.fileSW, text]; THROUGH [text.length..minWidth) DO Put.Char[toolData.fileSW, Ascii.SP]; ENDLOOP; END; PutLine: PUBLIC PROCEDURE [text: LONG STRING] = BEGIN Put.Line[toolData.fileSW, text]; END; PutNumber: PUBLIC PROCEDURE [ number: UNSPECIFIED, radix: CARDINAL, minWidth: CARDINAL ← 0] = BEGIN text: STRING = [40]; String.AppendNumber[text, number, radix]; THROUGH [text.length..minWidth) DO PutChar[Ascii.SP]; ENDLOOP; PutText[text]; END; PutLongNumber: PUBLIC PROCEDURE [ number: LONG UNSPECIFIED, radix: CARDINAL, minWidth: CARDINAL ← 0] = BEGIN text: STRING = [40]; String.AppendLongNumber[text, number, radix]; THROUGH [text.length..minWidth) DO PutChar[Ascii.SP]; ENDLOOP; PutText[text]; END; PutTextCentered: PUBLIC PROCEDURE [text: LONG STRING, width: CARDINAL ← 0] = BEGIN leftBlanks: CARDINAL = (width - text.length)/2; rightBlanks: CARDINAL = width - text.length - leftBlanks; THROUGH [0..leftBlanks) DO PutChar[Ascii.SP]; ENDLOOP; PutText[text]; THROUGH [0..rightBlanks) DO PutChar[Ascii.SP]; ENDLOOP; END; GetConfirmation: PUBLIC ENTRY OnlineDiagnostics.GetConfirmationProc = BEGIN ENABLE UNWIND => NULL; MakeConfirmsVisible[confirm, confirm]; DiagnosticsOps.PutMessage[msg]; PutLine["Please select Confirm! when this is done."L]; WAIT confirmation; MakeConfirmsInvisible[]; END; GetYesOrNo: PUBLIC ENTRY OnlineDiagnostics.GetYesOrNoProc = BEGIN ENABLE UNWIND => NULL; MakeConfirmsVisible[yes, no]; DiagnosticsOps.PutMessage[msg]; PutLine["Please select either Yes! or No! as appropriate."L]; WAIT confirmation; MakeConfirmsInvisible[]; RETURN[ SELECT toolData.latestConfirm FROM yes => OnlineDiagnostics.YesOrNo[yes], ENDCASE => OnlineDiagnostics.YesOrNo[no]]; END; GetFloppyChoice: PUBLIC ENTRY OnlineDiagnostics.GetFloppyChoiceProc = BEGIN ENABLE UNWIND => NULL; MakeConfirmsVisible[continue, exit]; PutLine["What do you want to do now?"L]; WAIT confirmation; MakeConfirmsInvisible[]; RETURN[ SELECT toolData.latestConfirm FROM continue => OnlineDiagnostics.FloppyWhatToDoNext[continueToNextError], loop => OnlineDiagnostics.FloppyWhatToDoNext[loopOnThisError], display => OnlineDiagnostics.FloppyWhatToDoNext[displayStuff], ENDCASE => OnlineDiagnostics.FloppyWhatToDoNext[exit]]; END; MakeConfirmsVisible: PROCEDURE [low, high: ConfirmIndex] = BEGIN toolData.confirming ← TRUE; FOR i: ConfirmIndex IN [low..high] DO FormSW.FindItem[toolData.confirmSW, ORD[ConfirmIndex[i]]].flags.invisible ← FALSE; ENDLOOP; FormSW.Display[toolData.confirmSW]; END; MakeConfirmsInvisible: PROCEDURE = BEGIN toolData.confirming ← FALSE; FOR i: ConfirmIndex IN ConfirmIndex DO FormSW.FindItem[toolData.confirmSW, ORD[ConfirmIndex[i]]].flags.invisible ← TRUE; ENDLOOP; FormSW.Display[toolData.confirmSW]; END; CheckForAbort: PUBLIC PROCEDURE = BEGIN IF UserInput.UserAbort[wh] THEN ERROR ABORTED; END; -- FormSW support routines. ConfirmCommand: ENTRY FormSW.ProcType = BEGIN ENABLE UNWIND => NULL; IF NOT toolData.confirming THEN UserTerminal.BlinkDisplay[] ELSE BEGIN toolData.latestConfirm ← LOOPHOLE[index, ConfirmIndex]; NOTIFY confirmation; END; END; ActionCommand: FormSW.ProcType = BEGIN IF toolData.confirming OR running THEN UserTerminal.BlinkDisplay[] ELSE BEGIN SELECT LOOPHOLE[index, FormIndex] FROM help => DiagnosticsOps.Help[toolData.test]; start => BEGIN --start-- SELECT toolData.test FROM display => BEGIN --display-- IF calledByBye THEN ByeOps.StopBouncing[]; DiagnosticsOps.LFDisplayTest[]; UglyHackToGetAroundBugInFormSW[]; IF calledByBye THEN ByeOps.ResumeBouncing[]; END --display-- ; keyboard => BEGIN --keyboard-- IF calledByBye THEN ByeOps.StopBouncing[]; DiagnosticsOps.KeyboardAndMouseTest[]; UglyHackToGetAroundBugInFormSW[]; IF calledByBye THEN ByeOps.ResumeBouncing[]; END --keyboard-- ; ethernet => DiagnosticsOps.EchoUserTest[ toolData.strings[testEthernetID], toolData.strings[ testProcessorID]]; floppy => BEGIN --floppy-- running ← TRUE; SELECT toolData.floppyTest FROM clean => Process.Detach[ FORK DiagnosticsOps.FloppyCleanReadWriteHeads[]]; standard => Process.Detach[FORK DiagnosticsOps.FloppyStandardTest[]]; summary => Process.Detach[FORK DiagnosticsOps.FloppyDisplayErrorLog[]]; format => Process.Detach[FORK DiagnosticsOps.FloppyFormatDiskette[]]; exercise => Process.Detach[FORK DiagnosticsOps.FloppyExerciser[]]; cmdFile => BEGIN --cmdFile-- IF toolData.inALoop THEN BEGIN CmdAppend["E,"L]; FormSW.DisplayItem[ toolData.formSW, ORD[FormIndex[cmdFile]]]; END; Process.Detach[ FORK DiagnosticsOps.FloppyCommandFileTest[ toolData.doubleDensity, toolData.doubleSided, toolData.sectorsPerTrack, toolData.sectorLength, toolData.errorHandling, toolData.strings[cmdFile]]]; END --cmdFile-- ; ENDCASE; END --floppy-- ; none => NULL; ENDCASE; END --start-- ; cancel => [] ← ToolWindow.Deactivate[wh]; addCommand => BEGIN --addCommand-- temp: LONG STRING = [100]; SELECT toolData.operation FROM initialize => CmdAppend["I,"L]; recalibrate => CmdAppend["RC,"L]; readStatus => CmdAppend["RAST,"L]; readHeader => BEGIN --readHeader-- String.Copy[temp, "RAH,"L]; IF AppendTrackNumber[temp] THEN IF toolData.inALoop THEN BEGIN IF AppendIncrement[temp] THEN CmdAppend[temp]; END ELSE CmdAppend[temp]; END --readHeader-- ; readSectors => BEGIN --readSectors-- String.Copy[temp, "RASE,"L]; IF AppendTrackNumber[temp] THEN IF AppendStartingSector[temp] THEN IF toolData.inALoop THEN BEGIN IF AppendIncrement[temp] THEN CmdAppend[temp]; END ELSE BEGIN IF AppendSectorCount[temp] THEN CmdAppend[temp]; END; END --readSectors-- ; writeSectors, writeDeletedSectors => BEGIN --write-- IF toolData.operation = writeSectors THEN String.Copy[temp, "WS,"L] ELSE String.Copy[temp, "WD,"L]; IF AppendTrackNumber[temp] THEN IF AppendStartingSector[temp] THEN IF toolData.inALoop THEN BEGIN IF AppendIncrement[temp] THEN IF AppendDataWord[temp] THEN CmdAppend[temp]; END ELSE BEGIN IF AppendSectorCount[temp] THEN IF AppendDataWord[temp] THEN CmdAppend[temp]; END; END --write-- ; verify => CmdAppend["V,"L]; loop => BEGIN --loop-- IF toolData.inALoop THEN CmdAppend["E,"L] ELSE BEGIN String.Copy[temp, "S,"L]; String.AppendNumber[temp, toolData.loopCount, 10]; String.AppendString[temp, ","L]; --!! Diag2Pack.mesa uses "'", but this works. CmdAppend[temp]; END; ToggleInALoop[]; END --loop-- ; displayData => CmdAppend[ SELECT toolData.dataDisplayed FROM status => "DST,"L, header => "DH,"L, sector => "DSE,"L, summary => "DL,"L, ENDCASE => "DST,"L]; clearLog => CmdAppend["C,"L]; log => CmdAppend["L,"L]; ENDCASE; END --addCommand-- ; deleteCommand => CmdDelete[]; ENDCASE => PutLine["Unknown command - should never happen!?!?"L]; END; END; KamikazeProc: UserInput.PeriodicProcType = BEGIN FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[start]]]; END; UglyHackToGetAroundBugInFormSW: PROCEDURE = BEGIN [] ← UserInput.CreatePeriodicNotify[ proc: KamikazeProc, window: Window.rootWindow, rate: 0]; END; CmdAppend: PROCEDURE [string: LONG STRING] = BEGIN IF toolData.cmdCount < cmdMax THEN BEGIN String.AppendStringAndGrow[@toolData.strings[cmdFile], string, z]; toolData.cmdCount ← toolData.cmdCount + 1; toolData.cmdIndexes[toolData.cmdCount] ← toolData.strings[cmdFile].length; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[cmdFile]]]; END; END; CmdDelete: PROCEDURE = BEGIN IF toolData.cmdCount > 0 THEN BEGIN ch: CHARACTER ← toolData.strings[cmdFile][ toolData.cmdIndexes[toolData.cmdCount - 1]]; IF ch = 'E OR ch = 'S THEN ToggleInALoop[]; toolData.cmdCount ← toolData.cmdCount - 1; toolData.strings[cmdFile].length ← toolData.cmdIndexes[toolData.cmdCount]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[cmdFile]]]; END; END; AppendTrackNumber: PROCEDURE [cmd: LONG STRING] RETURNS [ok: BOOLEAN] = BEGIN IF toolData.trackNumber > 76 THEN BEGIN PutLine["Track number invalid - must be between 0 and 76."L]; ok ← FALSE; END ELSE BEGIN String.AppendNumber[cmd, toolData.trackNumber, 10]; String.AppendString[cmd, ",0,"L]; --!! what is the 0? "keyHead", 0 or 1 ok ← TRUE; END; END; AppendStartingSector: PROCEDURE [cmd: LONG STRING] RETURNS [ok: BOOLEAN] = BEGIN IF toolData.startingSector < 1 OR toolData.startingSector > toolData.sectorsPerTrack THEN BEGIN PutLine[ "Starting sector invalid - must be between 1 and # of sectors per track."L]; ok ← FALSE; END ELSE BEGIN String.AppendNumber[cmd, toolData.startingSector, 10]; String.AppendString[cmd, ","L]; ok ← TRUE; END; END; AppendIncrement: PROCEDURE [cmd: LONG STRING] RETURNS [ok: BOOLEAN] = BEGIN IF toolData.increment < -2000 OR toolData.increment > 2000 THEN BEGIN PutLine["Increment invalid - must be between -2000 and 2000."L]; ok ← FALSE; END ELSE BEGIN IF toolData.increment < 0 THEN String.AppendString[cmd, "-"L] ELSE String.AppendString[cmd, "+"L]; String.AppendNumber[cmd, ABS[toolData.increment], 10]; String.AppendString[cmd, ","L]; ok ← TRUE; END; END; AppendSectorCount: PROCEDURE [cmd: LONG STRING] RETURNS [ok: BOOLEAN] = BEGIN IF toolData.sectorCount < 1 OR toolData.sectorCount > toolData.sectorsPerTrack THEN BEGIN PutLine[ "Sector count invalid - must be between 1 and # of sectors per track."L]; ok ← FALSE; END ELSE BEGIN String.AppendNumber[cmd, toolData.sectorCount, 10]; String.AppendString[cmd, ","L]; ok ← TRUE; END; END; AppendDataWord: PROCEDURE [cmd: LONG STRING] RETURNS [ok: BOOLEAN] = BEGIN String.AppendNumber[cmd, toolData.dataWord, 16]; String.AppendString[cmd, ","L]; ok ← TRUE; END; ToggleInALoop: PROCEDURE = BEGIN toolData.inALoop ← NOT toolData.inALoop; IF toolData.test = floppy AND toolData.floppyTest = cmdFile THEN OperationNotify[ toolData.formSW, FormSW.FindItem[ toolData.formSW, ORD[FormIndex[operation]]], ORD[FormIndex[operation]], toolData.operation]; END; TestNotify: FormSW.EnumeratedNotifyProcType = BEGIN SELECT LOOPHOLE[oldValue, DiagnosticsOps.Tests] FROM ethernet => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[currOrganization]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[currDomain]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[thisEthernetID]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[thisProcessorID]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[thisProcessorID]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[listFS]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[listPS]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[listMS]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[testEthernetID]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[testProcessorID]]].flags.invisible ← TRUE; END; floppy => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[floppyTest]]].flags.invisible ← TRUE; END; none => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[start]]].flags.invisible ← FALSE; END; ENDCASE; SELECT toolData.test FROM ethernet => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[currOrganization]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[currDomain]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[thisEthernetID]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[thisProcessorID]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[listFS]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[listPS]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[listMS]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[testEthernetID]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[testProcessorID]]].flags.invisible ← FALSE; END; floppy => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[floppyTest]]].flags.invisible ← FALSE; END; none => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[start]]].flags.invisible ← TRUE; END; ENDCASE; IF LOOPHOLE[oldValue, DiagnosticsOps.Tests] = floppy AND toolData.floppyTest = cmdFile THEN BEGIN toolData.floppyTest ← clean; FloppyTestNotify[ sw, FormSW.FindItem[sw, ORD[FormIndex[floppyTest]]], ORD[ FormIndex[floppyTest]], FloppyTest[cmdFile]]; END; IF toolData.reDisplay THEN BEGIN FormSW.Display[sw]; toolData.reDisplay ← FALSE; END; END; FloppyTestNotify: FormSW.EnumeratedNotifyProcType = BEGIN SELECT LOOPHOLE[oldValue, FloppyTest] FROM cmdFile => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[addCommand]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[deleteCommand]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[doubleDensity]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[doubleSided]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[sectorsPerTrack]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[sectorLength]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[errorHandling]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[operation]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[cmdFile]]].flags.invisible ← TRUE; --SetCurrent[sw, nullIndex]; END; ENDCASE; SELECT toolData.floppyTest FROM cmdFile => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[addCommand]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[deleteCommand]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[doubleDensity]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[doubleSided]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[sectorsPerTrack]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[sectorLength]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[errorHandling]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[operation]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[cmdFile]]].flags.invisible ← FALSE; END; ENDCASE; IF LOOPHOLE[oldValue, FloppyTest] = cmdFile THEN BEGIN oldOperation: Operation ← toolData.operation; toolData.operation ← initialize; OperationNotify[ sw, FormSW.FindItem[sw, ORD[FormIndex[operation]]], ORD[ FormIndex[operation]], oldOperation]; END; IF toolData.reDisplay THEN BEGIN FormSW.Display[sw]; toolData.reDisplay ← FALSE; END; END; OperationNotify: FormSW.EnumeratedNotifyProcType = BEGIN SELECT LOOPHOLE[oldValue, Operation] FROM readHeader => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[trackNumber]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[increment]]].flags.invisible ← TRUE; --SetCurrent[sw, nullIndex]; END; readSectors => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[trackNumber]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[startingSector]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[sectorCount]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[increment]]].flags.invisible ← TRUE; --SetCurrent[sw, nullIndex]; END; writeSectors, writeDeletedSectors => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[trackNumber]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[startingSector]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[sectorCount]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[dataWord]]].flags.invisible ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[increment]]].flags.invisible ← TRUE; --SetCurrent[sw, nullIndex]; END; loop => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[loopCount]]].flags.invisible ← TRUE; --SetCurrent[sw, nullIndex]; END; displayData => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[dataDisplayed]]].flags.invisible ← TRUE; END; ENDCASE; SELECT toolData.operation FROM readHeader => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[trackNumber]]].flags.invisible ← FALSE; IF toolData.inALoop THEN FormSW.FindItem[sw, ORD[FormIndex[increment]]].flags.invisible ← FALSE; END; readSectors => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[trackNumber]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[startingSector]]].flags.invisible ← FALSE; IF toolData.inALoop THEN FormSW.FindItem[sw, ORD[FormIndex[increment]]].flags.invisible ← FALSE ELSE FormSW.FindItem[sw, ORD[FormIndex[sectorCount]]].flags.invisible ← FALSE; END; writeSectors, writeDeletedSectors => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[trackNumber]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[startingSector]]].flags.invisible ← FALSE; IF toolData.inALoop THEN FormSW.FindItem[sw, ORD[FormIndex[increment]]].flags.invisible ← FALSE ELSE FormSW.FindItem[sw, ORD[FormIndex[sectorCount]]].flags.invisible ← FALSE; FormSW.FindItem[sw, ORD[FormIndex[dataWord]]].flags.invisible ← FALSE; END; loop => IF NOT toolData.inALoop THEN BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[loopCount]]].flags.invisible ← FALSE; END; displayData => BEGIN toolData.reDisplay ← TRUE; FormSW.FindItem[sw, ORD[FormIndex[dataDisplayed]]].flags.invisible ← FALSE; END; ENDCASE; IF toolData.reDisplay THEN BEGIN FormSW.Display[sw]; toolData.reDisplay ← FALSE; END; END; -- Setup and support routines. ClientTransition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => BEGIN IF toolData = NIL THEN toolData ← z.NEW[Data ← []]; active ← TRUE; END; new = inactive => BEGIN IF toolData # NIL THEN BEGIN FormSW.Destroy[toolData.formSW]; z.FREE[@toolData.strings[cmdFile]]; z.FREE[@toolData]; END; IF calledByBye THEN BEGIN calledByBye ← FALSE; ByeOps.ResumeBouncing[]; END; active ← FALSE; END; ENDCASE END; DiagnosticsActivate: PUBLIC PROCEDURE = BEGIN --calledByBye ← TRUE; IF wh = NIL THEN Init[]; ToolWindow.Activate[wh]; Window.Stack[wh, Window.GetChild[Window.GetParent[wh]]]; -- top me Window.ValidateTree[]; END; Init: PROCEDURE = BEGIN -- Make the tool window and its subwindows. wh ← Tool.Create[ makeSWsProc: MakeSWs, initialState: inactive, clientTransition: ClientTransition, name: "Diagnostics"L, initialBox: [[512, 0], [512, 808]], tinyName1: "Diag"L, tinyName2: "nostics"L] END; MakeSWs: Tool.MakeSWsProc = BEGIN logName: STRING ← [40]; Tool.UnusedLogName[unused: logName, root: "Diagnostics.log"L]; toolData.confirmSW ← Tool.MakeFormSW[ window: window, formProc: MakeConfirm, zone: z, h: 2*WindowFont.FontHeight[]]; -- should be 1 toolData.formSW ← Tool.MakeFormSW[ window: window, formProc: MakeForm, zone: z, h: 45*WindowFont.FontHeight[]]; running ← TRUE; Process.Detach[FORK SetupEthernetItems[]]; <<toolData.fileSW ← Tool.MakeFileSW[ window: window, name: logName, allowTypeIn: FALSE];>> --changed typein mode to True. JFung.pasa -- 24-Feb-84 16:44:13 toolData.fileSW ← Tool.MakeFileSW[ window: window, name: logName, allowTypeIn: TRUE]; END; MakeConfirm: FormSW.ClientItemsProcType = BEGIN OPEN FormSW; -- This procedure creates the confirmation FormSW. formItems: LONG POINTER TO ARRAY ConfirmIndex OF FormSW.ItemHandle ← NIL; items ← AllocateItemDescriptor[nItems: ConfirmIndex.LAST.ORD + 1, z: z]; formItems ← LOOPHOLE[BASE[items]]; formItems↑ ← [ confirm: CommandItem[ tag: "Confirm"L, place: newLine, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand], yes: CommandItem[ tag: "Yes"L, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand], no: CommandItem[ tag: "No"L, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand], continue: CommandItem[ tag: "Continue"L, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand], loop: CommandItem[ tag: "Loop"L, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand], display: CommandItem[ tag: "Display"L, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand], exit: CommandItem[ tag: "Exit"L, drawBox: TRUE, invisible: TRUE, proc: ConfirmCommand]]; RETURN[items: items, freeDesc: TRUE] END; MakeForm: FormSW.ClientItemsProcType = BEGIN OPEN FormSW; -- This procedure creates the main FormSW. formItems: LONG POINTER TO ARRAY FormIndex OF FormSW.ItemHandle ← NIL; EnumSeq: TYPE = RECORD [seq: SEQUENCE n: CARDINAL OF FormSW.Enumerated]; testSeq: LONG POINTER TO EnumSeq ← z.NEW[EnumSeq [5]]; floppyTestSeq: LONG POINTER TO EnumSeq ← z.NEW[EnumSeq [6]]; sectorLengthSeq: LONG POINTER TO EnumSeq ← z.NEW[EnumSeq [4]]; errorHandlingSeq: LONG POINTER TO EnumSeq ← z.NEW[EnumSeq [3]]; operationSeq: LONG POINTER TO EnumSeq ← z.NEW[EnumSeq [12]]; dataDisplayedSeq: LONG POINTER TO EnumSeq ← z.NEW[EnumSeq [4]]; testSeq[0] ← ["Display"L, DiagnosticsOps.Tests[display]]; testSeq[1] ← ["Keyboard"L, DiagnosticsOps.Tests[keyboard]]; testSeq[2] ← ["Echo Test"L, DiagnosticsOps.Tests[ethernet]]; testSeq[3] ← ["Floppy Disk Drive"L, DiagnosticsOps.Tests[floppy]]; testSeq[4] ← ["None"L, DiagnosticsOps.Tests[none]]; floppyTestSeq[0] ← ["Clean Heads"L, FloppyTest[clean]]; floppyTestSeq[1] ← ["Standard"L, FloppyTest[standard]]; floppyTestSeq[2] ← ["Summary"L, FloppyTest[summary]]; floppyTestSeq[3] ← ["Format"L, FloppyTest[format]]; floppyTestSeq[4] ← ["Exerciser"L, FloppyTest[exercise]]; floppyTestSeq[5] ← ["Command File"L, FloppyTest[cmdFile]]; sectorLengthSeq[0] ← ["128 bytes"L, OnlineDiagnostics.SectorLength[one28]]; sectorLengthSeq[1] ← ["256 bytes"L, OnlineDiagnostics.SectorLength[two56]]; sectorLengthSeq[2] ← ["512 bytes"L, OnlineDiagnostics.SectorLength[five12]]; sectorLengthSeq[3] ← [ "1024 bytes"L, OnlineDiagnostics.SectorLength[one024]]; errorHandlingSeq[0] ← [ "No Error Checking"L, OnlineDiagnostics.ErrorHandling[noChecking]]; errorHandlingSeq[1] ← [ "Stop on Errors"L, OnlineDiagnostics.ErrorHandling[stopOnError]]; errorHandlingSeq[2] ← [ "Loop on Errors"L, OnlineDiagnostics.ErrorHandling[loopOnError]]; operationSeq[0] ← ["Initialize floppy drive"L, Operation[initialize]]; operationSeq[1] ← ["Recalibrate"L, Operation[recalibrate]]; operationSeq[2] ← ["Read Status"L, Operation[readStatus]]; operationSeq[3] ← ["Read Header"L, Operation[readHeader]]; operationSeq[4] ← ["Read Sectors"L, Operation[readSectors]]; operationSeq[5] ← ["Write Sectors"L, Operation[writeSectors]]; operationSeq[6] ← [ "Write Deleted Sectors"L, Operation[writeDeletedSectors]]; operationSeq[7] ← ["Verify"L, Operation[verify]]; operationSeq[8] ← ["Start/Stop Loop"L, Operation[loop]]; operationSeq[9] ← ["Display Data"L, Operation[displayData]]; operationSeq[10] ← ["Clear Status Log"L, Operation[clearLog]]; operationSeq[11] ← ["Log Status"L, Operation[log]]; toolData.cmdCount ← 0; toolData.cmdIndexes[toolData.cmdCount] ← 0; toolData.inALoop ← FALSE; dataDisplayedSeq[0] ← ["Status"L, DataDisplayed[status]]; dataDisplayedSeq[1] ← ["Header"L, DataDisplayed[header]]; dataDisplayedSeq[2] ← ["Sector"L, DataDisplayed[sector]]; dataDisplayedSeq[3] ← ["Summary Log"L, DataDisplayed[summary]]; items ← AllocateItemDescriptor[nItems: FormIndex.LAST.ORD + 1, z: z]; formItems ← LOOPHOLE[BASE[items]]; formItems↑ ← [ help: CommandItem[ tag: "Help"L, place: newLine, drawBox: TRUE, invisible: FALSE, proc: ActionCommand], start: CommandItem[ tag: "Start"L, drawBox: TRUE, invisible: TRUE, proc: ActionCommand], cancel: CommandItem[ tag: "Cancel"L, drawBox: TRUE, invisible: FALSE, proc: ActionCommand], addCommand: CommandItem[ tag: "Add Command to file"L, drawBox: TRUE, invisible: TRUE, proc: ActionCommand], deleteCommand: CommandItem[ tag: "Delete Previous Command"L, drawBox: TRUE, invisible: TRUE, proc: ActionCommand], test: EnumeratedItem[ tag: "Test to be executed"L, place: newLine, invisible: FALSE, feedback: all, value: @toolData.test, copyChoices: TRUE, choices: DESCRIPTOR[testSeq↑], proc: TestNotify], floppyTest: EnumeratedItem[ tag: "Type of test"L, place: newLine, invisible: TRUE, feedback: all, value: @toolData.floppyTest, copyChoices: TRUE, choices: DESCRIPTOR[floppyTestSeq↑], proc: FloppyTestNotify], currOrganization: StringItem[ tag: "Current Organization"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[currOrganization]], currDomain: StringItem[ tag: "Current Domain"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[currDomain]], thisEthernetID: StringItem[ tag: "Ethernet ID number of this machine"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[thisEthernetID]], thisProcessorID: StringItem[ tag: "Processor ID number of this machine"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[thisProcessorID]], listFS: StringItem[ tag: "FS"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[listFS]], listPS: StringItem[ tag: "PS"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[listPS]], listMS: StringItem[ tag: "MS"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[listMS]], testEthernetID: StringItem[ tag: "Ethernet ID number of the test partner's machine"L, place: newLine, invisible: TRUE, inHeap: TRUE, string: @toolData.strings[testEthernetID]], testProcessorID: StringItem[ tag: "Processor ID number of the test partner's machine"L, place: newLine, invisible: TRUE, inHeap: TRUE, string: @toolData.strings[testProcessorID]], doubleDensity: BooleanItem[ tag: "Double Density"L, place: newLine, invisible: TRUE, switch: @toolData.doubleDensity], doubleSided: BooleanItem[ tag: "Double Sided"L, invisible: TRUE, switch: @toolData.doubleSided], sectorsPerTrack: NumberItem[ tag: "Sectors per Track"L, invisible: TRUE, value: @toolData.sectorsPerTrack, notNegative: TRUE, signed: FALSE], sectorLength: EnumeratedItem[ tag: "Sector Length"L, place: newLine, invisible: TRUE, feedback: all, value: @toolData.sectorLength, copyChoices: TRUE, choices: DESCRIPTOR[sectorLengthSeq↑]], errorHandling: EnumeratedItem[ tag: "Error Handling"L, place: newLine, invisible: TRUE, feedback: all, value: @toolData.errorHandling, copyChoices: TRUE, choices: DESCRIPTOR[errorHandlingSeq↑]], operation: EnumeratedItem[ tag: "Command File Operation"L, place: newLine, invisible: TRUE, feedback: one, value: @toolData.operation, copyChoices: TRUE, choices: DESCRIPTOR[operationSeq↑], proc: OperationNotify], cmdFile: StringItem[ tag: "Commands"L, place: newLine, invisible: TRUE, readOnly: TRUE, inHeap: TRUE, string: @toolData.strings[cmdFile]], trackNumber: NumberItem[ tag: "Track number"L, place: newLine, invisible: TRUE, value: @toolData.trackNumber, notNegative: TRUE, signed: FALSE], startingSector: NumberItem[ tag: "Starting Sector"L, place: newLine, invisible: TRUE, value: @toolData.startingSector, notNegative: TRUE, signed: FALSE], sectorCount: NumberItem[ tag: "Sector Count"L, place: newLine, invisible: TRUE, value: @toolData.sectorCount, notNegative: TRUE, signed: FALSE], increment: NumberItem[ tag: "Increment (+ or -) by"L, place: newLine, invisible: TRUE, value: @toolData.increment, notNegative: FALSE, signed: TRUE], dataWord: NumberItem[ tag: "Data Word"L, place: newLine, invisible: TRUE, value: @toolData.dataWord, radix: octal, notNegative: TRUE, signed: FALSE], loopCount: NumberItem[ tag: "Loop Count"L, place: newLine, invisible: TRUE, value: @toolData.loopCount, notNegative: TRUE, signed: FALSE], dataDisplayed: EnumeratedItem[ tag: "Data to Be Displayed"L, place: newLine, invisible: TRUE, feedback: all, value: @toolData.dataDisplayed, copyChoices: TRUE, choices: DESCRIPTOR[dataDisplayedSeq↑]]]; z.FREE[@testSeq]; z.FREE[@floppyTestSeq]; z.FREE[@sectorLengthSeq]; z.FREE[@errorHandlingSeq]; z.FREE[@operationSeq]; z.FREE[@dataDisplayedSeq]; RETURN[items: items, freeDesc: TRUE] END; SetupEthernetItems: PROCEDURE = BEGIN --SetupEthernetItems-- thisNetworkAddress: System.NetworkAddress; -- Get the current domain and organization. Profile.GetDefaultOrganization[GetCurrOrganization]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[currOrganization]]]; Profile.GetDefaultDomain[GetCurrDomain]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[currDomain]]]; -- Get the current network and host number. thisNetworkAddress ← NetworkStream.AssignNetworkAddress[]; Format.NetworkNumber[ GetThisEthernetID, thisNetworkAddress.net, productSoftware]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[thisEthernetID]]]; Format.HostNumber[ GetThisProcessorID, thisNetworkAddress.host, productSoftware]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[thisProcessorID]]]; AppendServers[]; -- List all the file servers, print servers, and mail servers. FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[listFS]]]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[listPS]]]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[listMS]]]; GetClearingHouse[]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[testEthernetID]]]; FormSW.DisplayItem[toolData.formSW, ORD[FormIndex[testProcessorID]]]; running ← FALSE; END --SetupEthernetItems-- ; GetCurrOrganization: PROCEDURE [s: Profile.String] = BEGIN toolData.strings[currOrganization] ← String.CopyToNewString[s, z]; END; GetCurrDomain: PROCEDURE [s: Profile.String] = BEGIN toolData.strings[currDomain] ← String.CopyToNewString[s, z]; END; GetThisEthernetID: Format.StringProc = BEGIN toolData.strings[thisEthernetID] ← String.CopyToNewString[s, z]; END; GetThisProcessorID: Format.StringProc = BEGIN toolData.strings[thisProcessorID] ← String.CopyToNewString[s, z]; END; GetTestEthernetID: Format.StringProc = BEGIN toolData.strings[testEthernetID] ← String.CopyToNewString[s, z]; END; GetTestProcessorID: Format.StringProc = BEGIN toolData.strings[testProcessorID] ← String.CopyToNewString[s, z]; END; -- Append server trash, stolen from Diag1Pack.mesa AppendServers: PROCEDURE = BEGIN --AppendServers-- found: BOOLEAN ← FALSE; foundThatID: BOOLEAN ← FALSE; pattern: CH.NamePattern; index: StringIndex; string: LONG POINTER TO LONG STRING; wildString: LONG STRING ← [5]; GetAndAppendID: PROC [name: CH.Element] = BEGIN --GetAndAppendID-- AppendID: PROC [fullName: CH.Element, info: CHLookup.FileserverPt] = BEGIN --AppendID-- temp: LONG STRING ← [100]; -- Append the decimal representation of info.address -- AppendDashedNumberAndGrow[string, @info.address.host, 3, 10, z]; -- Append a blank -- String.AppendStringAndGrow[string, " "L, z]; -- ****************************************************************** -- -- NOTE!!!! - The octal & hex representations of the proc IDs are not printed at this time. May be re-inserted at a future time. -- Append the octal representation of info.address -- AppendNumberAndGrow[string, @info.address.host, 3, 8, z]; -- Append the string "B " -- String.AppendStringAndGrow[string, "B "L, z]; -- Append the hexadecimal representation of info.address -- AppendNumberAndGrow[string, @info.address.host, 3, 16, z]; -- Append the string "X " -- String.AppendStringAndGrow[string, "X "L, z]; -- ****************************************************************** -- -- Append the string " NET # " String.AppendStringAndGrow[string, " NET # "L, z]; -- Append the net # -- AppendDashedNumberAndGrow[string, @info.address.net, 2, 10, z]; -- Append a blank -- String.AppendStringAndGrow[string, " "L, z]; -- Append the name of the server NSString.AppendToMesaString[temp, name.local]; String.AppendStringAndGrow[string, temp, z]; -- Append a CR -- String.AppendStringAndGrow[string, " "L, z]; found ← TRUE; END --AppendID-- ; SELECT index FROM listFS => CHLookup.LookupFileserver[ name, AppendID ! CHLookup.Error => BEGIN found ← FALSE; CONTINUE; END; ]; listPS => CHLookup.LookupPrintserver[ name, LOOPHOLE[AppendID] ! CHLookup.Error => BEGIN found ← FALSE; CONTINUE; END; ]; listMS => CHLookup.LookupMailserver[ name, LOOPHOLE[AppendID] ! CHLookup.Error => BEGIN found ← FALSE; CONTINUE; END; ]; ENDCASE => NULL; END --GetAndAppendID-- ; -- Set up the pattern to be used in the enumerations. -- String.AppendChar[wildString, CH.wildCard]; pattern ← [ org: NSString.StringFromMesaString[toolData.strings[currOrganization]], domain: NSString.StringFromMesaString[toolData.strings[currDomain]], local: NSString.StringFromMesaString[wildString]]; --The following code enumerates the servers found in the Clearinghouse, -- and appends their IDs to the appropriate strings. FOR index IN [listFS..listMS] DO string ← @toolData.strings[index]; found ← CH.Enumerate[ Authenticator.nullCredentials, Authenticator.firstVerifier, @pattern, (SELECT index FROM listFS => CHPIDs.ch3fileserver, listPS => CHPIDs.ch3printserver, ENDCASE => CHPIDs.ch3mailserver), GetAndAppendID].code = done; IF found THEN WHILE string[string↑.length - 1] = Ascii.SP OR string[string↑.length - 1] = Ascii.CR DO string↑.length ← string↑.length - 1; ENDLOOP -- get rid of final CR ELSE String.AppendStringAndGrow[string, "none"L, z]; ENDLOOP; END --AppendServers-- ; GetClearingHouse: PROCEDURE = BEGIN --GetClearingHouse-- CHAddr: System.NetworkAddress ← CHStubInternal.FindDomainAddr[ CH.zeroMaxLengthNames]; Format.NetworkNumber[GetTestEthernetID, CHAddr.net, productSoftware]; Format.HostNumber[GetTestProcessorID, CHAddr.host, productSoftware]; END --GetClearingHouse-- ; AppendNumberAndGrow: PROCEDURE [ string: LONG POINTER TO LONG STRING, field: LONG POINTER, size: CARDINAL, radix: CARDINAL, z: UNCOUNTED ZONE] = BEGIN --AppendNumberAndGrow-- temp: LONG STRING ← [100]; temp.length ← 0; ExtendedString.AppendNumber[field, size, radix, temp]; String.AppendStringAndGrow[string, temp, z]; END --AppendNumberAndGrow-- ; AppendDashedNumberAndGrow: PROCEDURE [ string: LONG POINTER TO LONG STRING, field: LONG POINTER, size: CARDINAL, radix: CARDINAL, z: UNCOUNTED ZONE] = BEGIN --AppendDashedNumberAndGrow-- temp: LONG STRING ← [100]; temp.length ← 0; ExtendedString.AppendNumber[field, size, radix, temp]; FOR i: CARDINAL IN [0..temp.length) DO String.AppendCharAndGrow[string, temp[i], z]; IF (temp.length - 1 - i) MOD 3 = 0 AND i # temp.length - 1 THEN String.AppendCharAndGrow[string, '-, z]; ENDLOOP; END --AppendDashedNumberAndGrow-- ; -- Mainline code. Init[]; END...