-- File: GateParameterAlto.mesa, Last Edit: March 6, 1981 3:01 PM DIRECTORY MiscOps USING [ReleaseDebuggerBitmap], SegmentDefs USING [FileHandle, MemoryConfig, GetMemoryConfig], StreamDefs USING [GetDiskStreamList, StreamHandle], CmFile USING [OpenSection, NextItem, GetNextToken, Close], FormSW USING [ AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem], Put USING [Char, Decimal, Line, Number, Text], Runtime USING [IsBound], String USING [ AppendChar, AppendDecimal, AppendNumber, AppendString, EquivalentString, InvalidNumber, StringToDecimal, StringToOctal, SubString, SubStringDescriptor], Process USING [Priority], Storage USING [FreeString, Expand, String], TajoMisc USING [SetState], TajoOps USING [UserCmFile], Tool USING [Create, MakeSWsProc, MakeFormSW], ToolWindow USING [TransitionProcType], UserTerminal USING [SetBackground], Clock USING [DisplayGoingOn, DisplayGoingOff], Indirect USING [GetParmFileName], Password USING [Check, Encrypt, Encrypted], Trouble USING [Bug, SetDisplayOnOffProcs, WrapTypescriptFile], AltoRam USING [CantFindFile, FileLooksCrufty, LoadRamAndBoot], AltoPRDefs USING [PRDriverVars, PRRouteIndex, GetPRDriverVars], AltoSlaDefs USING [ LineNeedsPassword, RememberDialoutPassword, RememberDialinPassword], CommUtilDefs USING [GetEthernetHostNumber, LockCode], DriverDefs USING [ CreateEthernetDriver, CreateChainedEthernetDriver, CreateEIADriver, CreateCommProcDriver, CreatePacketRadioDriver], GateDefs USING [typescript], PupDefs USING [ AdjustBufferParms, UseAltoChecksumMicrocode, UsePrincOpsChecksumMicrocode]; GateParameterAlto: PROGRAM IMPORTS MiscOps, SegmentDefs, StreamDefs, CmFile, FormSW, Put, Runtime, String, Storage, TajoMisc, TajoOps, Tool, UserTerminal, AltoRam, AltoPRDefs, AltoSlaDefs, Clock, Indirect, Password, Trouble, CommUtilDefs, DriverDefs, GateDefs, PupDefs EXPORTS GateDefs = BEGIN LoadRam: PROCEDURE [fileName: STRING] = BEGIN SELECT TRUE FROM fileName.length = 0 => Trouble.Bug["Please specify a Microcode file name."L]; fileName.length # 0 => BEGIN Put.Text[NIL, "Loading "L]; Put.Text[NIL, fileName]; Put.Text[NIL, "..."L]; AltoRam.LoadRamAndBoot[ fileName ! AltoRam.CantFindFile => Trouble.Bug["Can't find microcode file."L]; AltoRam.FileLooksCrufty => Trouble.Bug["Microcode file looks crufty."L]]; END; ENDCASE; Put.Line[NIL, "ok."L]; END; GetDecimal: PROCEDURE [ss: String.SubString] RETURNS [CARDINAL] = BEGIN ENABLE String.InvalidNumber => Trouble.Bug["Decimal number expected."L]; token: STRING = [100]; IF ~CmFile.GetNextToken[ss, token] THEN SIGNAL String.InvalidNumber; RETURN[String.StringToDecimal[token]]; END; GetOctal: PROCEDURE [ss: String.SubString] RETURNS [CARDINAL] = BEGIN ENABLE String.InvalidNumber => Trouble.Bug["Octal number expected."L]; token: STRING = [100]; IF ~CmFile.GetNextToken[ss, token] THEN SIGNAL String.InvalidNumber; RETURN[String.StringToOctal[token]]; END; noLines, noBoard: WORD = 177765B; PrintHost: PROCEDURE [name: STRING, net, host, lines, board: CARDINAL] = BEGIN Put.Number[NIL, net, [8, FALSE, TRUE, 0]]; Put.Char[NIL, '#]; Put.Number[NIL, host, [8, FALSE, TRUE, 0]]; Put.Char[NIL, '#]; Put.Text[NIL, name]; IF lines # noLines THEN BEGIN Put.Text[NIL, " with "L]; Put.Decimal[NIL, lines]; Put.Text[NIL, " lines"L]; END; IF board # noBoard THEN BEGIN Put.Text[NIL, " on board "L]; Put.Decimal[NIL, board]; END; Put.Line[NIL, "."L]; END; CheckHost: PROCEDURE [host: CARDINAL] = BEGIN IF host # CommUtilDefs.GetEthernetHostNumber[] THEN Trouble.Bug["Wrong Ethernet Host number"L]; END; ScanParameterFile: PUBLIC PROCEDURE RETURNS [priority: Process.Priority, noOiscp: BOOLEAN] = BEGIN ramNeeded, ramLoaded: BOOLEAN ← FALSE; parmFileName: STRING ← NIL; sectionName: STRING = "Gateway"L; name, arg: STRING ← NIL; ss: String.SubStringDescriptor; priority ← 2; noOiscp ← TRUE; IF Runtime.IsBound[Indirect.GetParmFileName] THEN parmFileName ← Indirect.GetParmFileName[]; IF parmFileName = NIL THEN parmFileName ← "GateParameter.txt"L; IF ~CmFile.OpenSection[parmFileName, sectionName] THEN BEGIN Message["Can't find [Gateway] section in "L, parmFileName]; Message["I guess we are simply a BootServer"L]; RETURN; END; DO [name, arg] ← CmFile.NextItem[]; IF arg # NIL THEN ss ← [base: arg, offset: 0, length: arg.length]; SELECT TRUE FROM name = NIL => EXIT; name[0] = '; => NULL; String.EquivalentString[name, "BUFFERS"L] => -- <number> (decimal) BEGIN buffers: CARDINAL ← GetDecimal[@ss]; PupDefs.AdjustBufferParms[buffers, 0]; MessageDecimal["Set number of buffers to "L, buffers]; END; String.EquivalentString[name, "EXPANDHEAP"L] => -- <pages> (decimal) BEGIN pages: CARDINAL ← GetDecimal[@ss]; Storage.Expand[pages]; MessageDecimal["Expanded the Heap by "L, pages, " pages"L]; END; String.EquivalentString[name, "KILL DEBUGGER BITMAP"L] => BEGIN IF String.EquivalentString[arg, "TRUE"L] THEN BEGIN MiscOps.ReleaseDebuggerBitmap[]; Message["Released the debugger's bitmap"L]; END ELSE Message["Didn't release the debugger's bitmap"L]; END; String.EquivalentString[name, "MICROCODE"L] => -- <filename> BEGIN LoadRam[arg]; END; String.EquivalentString[name, "Activate OISCP Router"L] => BEGIN IF String.EquivalentString[arg, "TRUE"L] THEN BEGIN noOiscp ← FALSE; Message["Oiscp router will be activated"L]; END ELSE Message["Didn't activate Oiscp router"L]; END; String.EquivalentString[name, "Priority"L] => -- <priority> (decimal) BEGIN priority ← GetDecimal[@ss]; MessageDecimal["Priority will be "L, priority]; END; String.EquivalentString[name, "TURN OFF DISPLAY"L] => BEGIN IF String.EquivalentString[arg, "TRUE"L] THEN BEGIN [] ← TajoMisc.SetState[disconnected]; [] ← UserTerminal.SetBackground[black]; Message["Turning the Display OFF"L]; END ELSE Message["Didn't turn the display OFF"L]; END; String.EquivalentString[name, "Typescript"L] => -- <pages> BEGIN pages: CARDINAL ← GetDecimal[@ss]; Trouble.WrapTypescriptFile[GateDefs.typescript, pages]; MessageDecimal[ "Typescript file will be trimmed at "L, pages, " pages"L]; END; -- Device things String.EquivalentString[name, "Ethernet"L] => BEGIN net: CARDINAL ← GetOctal[@ss]; host: CARDINAL ← GetOctal[@ss]; board: CARDINAL ← GetOctal[@ss]; [] ← DriverDefs.CreateEthernetDriver[net, board]; PrintHost[" is an Ethernet"L, net, host, noLines, board]; CheckHost[host]; END; String.EquivalentString[name, "ChainedEthernet"L] => BEGIN net: CARDINAL ← GetOctal[@ss]; host: CARDINAL ← GetOctal[@ss]; board: CARDINAL ← GetOctal[@ss]; [] ← DriverDefs.CreateChainedEthernetDriver[net, board]; PrintHost[" is a Chained Ethernet"L, net, host, noLines, board]; CheckHost[host]; END; String.EquivalentString[name, "EIA"L] => BEGIN net: CARDINAL ← GetOctal[@ss]; host: CARDINAL ← GetOctal[@ss]; lines: CARDINAL ← GetOctal[@ss]; Trouble.SetDisplayOnOffProcs[ Clock.DisplayGoingOn, Clock.DisplayGoingOff]; [] ← DriverDefs.CreateEIADriver[host: host, net: net, lines: lines]; PrintHost[" is an EIA board"L, net, host, lines, noBoard]; END; String.EquivalentString[name, "CommProc"L] => BEGIN net: CARDINAL ← GetOctal[@ss]; host: CARDINAL ← GetOctal[@ss]; lines: CARDINAL ← GetOctal[@ss]; [] ← DriverDefs.CreateCommProcDriver[ host: host, net: net, lines: lines]; PrintHost[" is a CommProc"L, net, host, lines, noBoard]; END; String.EquivalentString[name, "PacketRadio"L] => BEGIN net: CARDINAL ← GetOctal[@ss]; host: CARDINAL ← GetOctal[@ss]; [] ← DriverDefs.CreatePacketRadioDriver[host: host, net: net]; PrintHost[" is a PacketRadio"L, net, host, noLines, noBoard]; END; String.EquivalentString[name, "ROUTE"L] => BEGIN text: STRING = [100]; myp: POINTER TO AltoPRDefs.PRDriverVars ← AltoPRDefs.GetPRDriverVars[]; to: CARDINAL ← GetDecimal[@ss]; String.AppendNumber[text, to, 8]; String.AppendString[text, "]: "L]; FOR i: AltoPRDefs.PRRouteIndex IN AltoPRDefs.PRRouteIndex DO n: WORD ← GetOctal[@ss]; myp↑.prRouteSetp[to][i] ← n; String.AppendChar[text, ' ]; String.AppendNumber[text, n, 8]; ENDLOOP; Message["PRRoute["L, text]; END; -- Password things String.EquivalentString[name, "LineNeedsPassword"L] => BEGIN line: CARDINAL ← GetOctal[@ss]; AltoSlaDefs.LineNeedsPassword[line]; MessageOctal["Line "L, line, " needs a password"L]; -- Groan. Do this here so we don't clutter up memory when it isn't needed. CommUtilDefs.LockCode[Password.Check]; [] ← Password.Encrypt["foo"L, "foo"L]; -- Get it started and marked as in END; String.EquivalentString[name, "DialinPassword"L] => BEGIN e: Password.Encrypted; p: POINTER ← @e; text: STRING = [8*8]; FOR i: CARDINAL IN [0..SIZE[Password.Encrypted]) DO (p + i)↑ ← GetOctal[@ss]; ENDLOOP; FOR i: CARDINAL IN [0..SIZE[Password.Encrypted]) DO IF i # 0 THEN String.AppendChar[text, ' ]; String.AppendNumber[text, (p + i)↑, 8]; ENDLOOP; AltoSlaDefs.RememberDialinPassword[e]; Message["Dialin Password is "L, text]; END; String.EquivalentString[name, "SetupDialoutPassword"L] => BEGIN IF String.EquivalentString[arg, "TRUE"L] THEN BEGIN SetupDialoutPasswordTool[]; Message["Setup Dialout Password Tool"L]; END ELSE Message["Didn't Setup Dialout Password Tool"L]; END; ENDCASE => BEGIN Put.Text[NIL, "****** Unrecognized keyword: "L]; Put.Line[NIL, name]; END; Storage.FreeString[name]; Storage.FreeString[arg]; ENDLOOP; CmFile.Close[parmFileName]; IF ramNeeded AND ~ramLoaded THEN Trouble.Bug["Special Microcode required."L]; END; -- User interface things for setting the dialout password password: STRING ← NIL; SetupDialoutPasswordTool: PROCEDURE = BEGIN [] ← Tool.Create[ name: "Dialout Password"L, initialState: active, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; SetPassword: FormSW.ProcType = BEGIN AltoSlaDefs.RememberDialoutPassword[password]; END; MakeSWs: Tool.MakeSWsProc = BEGIN [] ← Tool.MakeFormSW[window: window, formProc: MakeForm]; END; MakeForm: FormSW.ClientItemsProcType = BEGIN nParams: CARDINAL = 2; items ← FormSW.AllocateItemDescriptor[nParams]; items[0] ← FormSW.CommandItem[ tag: "SetPassword"L, proc: SetPassword, place: FormSW.newLine]; items[1] ← FormSW.StringItem[ tag: "Password"L, string: @password, feedback: password]; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => password ← Storage.String[20]; new = inactive => Storage.FreeString[password]; ENDCASE; END; -- xx MessageDecimal: PROCEDURE [ one: STRING, num: CARDINAL, two, three: STRING ← NIL] = BEGIN text: STRING = [100]; String.AppendString[text, one]; String.AppendDecimal[text, num]; IF two # NIL THEN String.AppendString[text, two]; IF three # NIL THEN String.AppendString[text, three]; String.AppendChar[text, '.]; LogString[text]; END; MessageOctal: PROCEDURE [one: STRING, num: CARDINAL, two, three: STRING ← NIL] = BEGIN text: STRING = [100]; String.AppendString[text, one]; String.AppendNumber[text, num, 8]; IF two # NIL THEN String.AppendString[text, two]; IF three # NIL THEN String.AppendString[text, three]; String.AppendChar[text, '.]; LogString[text]; END; Message: PROCEDURE [one, two, three: STRING ← NIL] = BEGIN text: STRING = [100]; String.AppendString[text, one]; IF two # NIL THEN String.AppendString[text, two]; IF three # NIL THEN String.AppendString[text, three]; String.AppendChar[text, '.]; LogString[text]; END; LogString: PROCEDURE [text: STRING] = BEGIN Put.Line[NIL, text]; END; -- The rest of this module doesn't have anything to do with parameter files, but this is a handy location because it is already Alto specific. TryForMicrocodeChecksum: PROCEDURE = BEGIN config: SegmentDefs.MemoryConfig ← SegmentDefs.GetMemoryConfig[]; SELECT TRUE FROM (config.AltoType = AltoIIXM AND (config.controlStore = RamandRom OR config.controlStore = Ram3k)) => PupDefs.UseAltoChecksumMicrocode[]; config.AltoType = D0, config.AltoType = Dorado => PupDefs.UsePrincOpsChecksumMicrocode[]; ENDCASE => Trouble.Bug["This program needs an XM Alto (or a D0)"L]; END; -- AltoTajoControl leaves a dangling stream on User.cm FlushDanglingUserDotCm: PROCEDURE = BEGIN OPEN StreamDefs; userDotCmFile: SegmentDefs.FileHandle = TajoOps.UserCmFile[]; FOR sh: StreamHandle ← GetDiskStreamList[], sh.link UNTIL sh = NIL DO WITH s: sh SELECT FROM Disk => BEGIN IF s.file = userDotCmFile THEN BEGIN -- This assumes that nobody else is reading User.cm sh.destroy[sh]; EXIT; END; END; ENDCASE; ENDLOOP; END; -- initialization TryForMicrocodeChecksum[]; FlushDanglingUserDotCm[]; END.