DIRECTORY Ascii, Booting USING [Switches, switches], GermSwap USING [Switch], IO, Rope, SimpleTerminal USING [TurnOn, TurnOff]; BootSwitchesImpl: CEDAR PROGRAM IMPORTS Ascii, Booting, IO, Rope, SimpleTerminal EXPORTS ~ BEGIN STREAM: TYPE ~ IO.STREAM; ROPE: TYPE ~ Rope.ROPE; GetSwitches: PUBLIC PROC [in, out: STREAM] RETURNS [switches: Booting.Switches] = { RopeDefaultNil: TYPE = ROPE _ NIL; switchTable: ARRAY GermSwap.Switch OF RopeDefaultNil _ [ zero: "worry-call debugger as early as possible", one: "call debugger after MesaRuntime initialization", two: "call debugger after VM initialization", three: "call debugger after File initialization", four: "call debugger after finding VM file and swapping in non-initial parts of boot file", five: "call debugger in LoaderDriver after loading but before starting loadees", a: "don't start Ethernet1 drivers", b: "don't start Ethernet2 drivers", c: "don't start Communication package", d: "development version: don't try the Cedar directory in LoaderDriver/Installer", f: "do full booting sequence, even if defaults would imply a rollback", h: "hang in CPU loop with MP code instead of swapping to debugger", i: "enable control-swat as early as possible (instead of waiting until after login)", l: "long (and interactive) installation dialogue", n: "don't touch the disk during initialization (forces entry to Iago)", p: "don't read user profile from disk", q: "quick - don't read DF files", r: "rollback if the system volume has a valid checkpoint", s: "use software safe storage ops instead of microcode", t: "force teledebugging instead of disk world-swap", v: "perform VM copying for checkpoint (internal use only!)", w: "for world-swap debugger, assume debuggee outload file is valid/interesting" ]; value: ROPE _ NIL; DO end: CHAR; errors: BOOL _ FALSE; FromChar: PROC[c: CHAR] = { SELECT TRUE FROM Ascii.Letter[c] => switches[VAL[GermSwap.Switch.a.ORD+(Ascii.Lower[c]-'a)]] _ TRUE; Ascii.Digit[c] => switches[VAL[GermSwap.Switch.zero.ORD+(c-'0)]] _ TRUE; ENDCASE => { IO.PutRope[out, IF errors THEN ", " ELSE "\nUnrecognized switches: "]; IO.PutChar[out, c]; errors _ TRUE; }; }; ToChar: PROC [sw: GermSwap.Switch] RETURNS [CHAR] = { IF sw IN [zero..nine] THEN RETURN ['0+sw.ORD] ELSE RETURN ['A + (sw.ORD - GermSwap.Switch.a.ORD)] }; IO.PutRope[out, "\nSwitches: "]; IO.PutRope[out, value]; [id: value, c: end] _ GetID[in: in, out: out, default: NIL, init: value ! Rubout => {value _ NIL; end _ '?; CONTINUE}]; IF end = '? THEN IO.PutChar[out, end]; switches _ ALL[FALSE]; FOR i: INT IN [0..value.Length[]) DO FromChar[value.Fetch[i]] ENDLOOP; IF end = '? THEN { all: BOOL = value.Length[] = 0; IF all THEN IO.PutRope[out, " Type one or more boot switches."]; IO.PutRope[out, "\nThe boot switches have the following meanings:"]; FOR sw: GermSwap.Switch IN GermSwap.Switch DO IF (all AND switchTable[sw] # NIL) OR switches[sw] THEN { IO.PutRope[out, "\n "]; IO.PutChar[out, ToChar[sw]]; IO.PutRope[out, ": "]; IO.PutRope[out, IF switchTable[sw] = NIL THEN "I don't know any meaning for this switch" ELSE switchTable[sw]]; }; ENDLOOP; } ELSE { IF NOT errors THEN EXIT }; ENDLOOP; IO.PutChar[out, '\n]; }; Rubout: PUBLIC ERROR = CODE; GetID: PUBLIC PROC [in, out: STREAM, default: ROPE, init: ROPE _ NIL, echo: BOOL _ TRUE] RETURNS [id: ROPE, c: CHAR] = { OPEN Ascii; firstTime: BOOL _ init = NIL; EraseAll: PROC = { IF echo THEN FOR i: INT DECREASING IN [0..id.Length[]) DO out.EraseChar[id.Fetch[i]]; ENDLOOP; id _ NIL; }; Done: PROC [c: CHAR] RETURNS [BOOL] = INLINE { IF firstTime THEN { SELECT c FROM ControlA, BS, ControlQ, ControlW, ControlX, CR, SP, DEL => NULL; ENDCASE => EraseAll[]; firstTime _ FALSE; }; RETURN [c = SP OR c = CR OR c = '?] }; id _ Rope.Concat[init, default]; IF echo THEN IO.PutRope[out, default]; c _ IO.GetChar[in]; UNTIL Done[c] DO SELECT c FROM DEL => ERROR Rubout; ControlA, BS => { len: INT _ id.Length[]; IF len > 0 THEN { len _ len - 1; IF echo THEN out.EraseChar[id.Fetch[len]]; id _ id.Substr[len: len]; }; }; ControlW, ControlQ => { alpha: BOOL _ FALSE; FOR i: INT DECREASING IN [0..id.Length[]) DO ch: CHAR = id.Fetch[i]; IF Ascii.Letter[ch] OR Ascii.Digit[ch] THEN alpha _ TRUE ELSE IF alpha THEN {id _ id.Substr[len: i + 1]; EXIT}; IF echo THEN out.EraseChar[ch]; REPEAT FINISHED => id _ NIL; ENDLOOP; }; ControlX => EraseAll[]; ENDCASE => { id _ Rope.Concat[id, Rope.FromChar[c]]; IF echo THEN IO.PutChar[out, c]; }; c _ IO.GetChar[in]; ENDLOOP; }; SetBootSwitches: PROC [] = BEGIN in, out: IO.STREAM; [in: in, out: out] _ SimpleTerminal.TurnOn[]; Booting.switches _ GetSwitches[in: in, out: out]; SimpleTerminal.TurnOff[]; END; SetBootSwitches[]; END. BootSwitchesImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Tim Diebert: December 18, 1985 7:04:03 pm PST text to be backed up is of the form ..., the and following are to be removed. Κ₯˜™Icodešœ Οmœ1™