<> <> <> <> DIRECTORY Atom USING [ PutProp ], Buttons USING [Button, ButtonProc, Create, Destroy], ChoiceButtons USING [BuildEnumTypeSelection, BuildTextPrompt, ButtonList, PromptDataRef, SelectionNotifierProc], Commander USING [CommandProc, Register], CommandTool USING [NextArgument, Failed], Containers USING [ChildXBound, ChildYBound, Create], EditedStream USING [DeliverWhenProc], IO, Labels USING [Create, Label, Set], LarkControl, LarkPrograms USING [AddOrReplaceProgram, EnumeratePrograms, Monitor, Program, ReadProgramFromDisk], LarkWork USING [MaybeCreateWorkArea, MaybeShutDownWorkArea], List USING [Remove], MBQueue USING [Create, CreateButton, Flush, Queue, QueueClientAction], ProcessProps USING [ GetProp ], Pup USING [allNets, Address], Rope USING [Concat, Equal, ROPE], Rules USING [Create], TeleLoad USING [GoToDebugger, NameToAddress, Start, StartEventServer, StartKing, Stop, StopEventServer, StopKing, teleSwatSocket], TypeScript USING [Create], ViewerClasses USING [Viewer], ViewerEvents USING [EventProc, RegisterEventProc], ViewerIO USING [CreateViewerStreams], ViewerOps USING [OpenIcon, SetOpenHeight]; LarkControlImpl: CEDAR MONITOR IMPORTS Atom, Buttons, ChoiceButtons, Commander, CommandTool, Containers, IO, Labels, LarkControl, LarkPrograms, LarkWork, List, MBQueue, ProcessProps, Rope, Rules, TeleLoad, TypeScript, ViewerEvents, ViewerIO, ViewerOps EXPORTS LarkControl = BEGIN <> larkControl: LIST OF REF ANY _ NIL; mainSwitchRopes: ARRAY LarkControl.MainSwitchStates OF Rope.ROPE _ ["off", "manual", "auto"]; IsASPorCR: EditedStream.DeliverWhenProc = TRUSTED { RETURN [appendChar: TRUE, activate: char=' OR char = '\n]; }; GetInstanceList: PUBLIC PROC RETURNS [LIST OF REF ANY] = { RETURN [larkControl]; }; GetLogStream: PUBLIC PROC [address: Pup.Address] RETURNS [log: IO.STREAM] = { lark: LarkControl.LarkData; IF larkControl = NIL THEN RETURN [NIL]; IF address.net = Pup.allNets THEN RETURN [NARROW[larkControl.first, LarkControl.Data].out]; lark _ GetLark[address]; IF lark = NIL THEN RETURN [NIL]; log _ lark.h.log; }; GetLark: PUBLIC PROC [address: Pup.Address] RETURNS [lark: LarkControl.LarkData] = { d: LarkControl.Data; IF larkControl = NIL THEN RETURN [NIL]; IF address.net = Pup.allNets OR address.host NOT IN LarkControl.LarkIndex THEN RETURN [NIL]; FOR ll: LIST OF REF ANY _ larkControl, ll.rest WHILE ll # NIL DO d _ NARROW[ll.first]; IF d.net = address.net THEN RETURN[d.larks[address.host]]; ENDLOOP; RETURN [NIL]; }; DestroyProc: ViewerEvents.EventProc = TRUSTED { <> d: LarkControl.Data; FOR ll: LIST OF REF ANY _ larkControl, ll.rest WHILE ll # NIL DO d _ NARROW[ll.first]; IF d.viewer = viewer THEN EXIT; REPEAT FINISHED => d _ NIL; ENDLOOP; IF d # NIL THEN { FOR i: LarkControl.LarkIndex IN LarkControl.LarkIndex DO IF d.larks[i].eval # NIL THEN { MBQueue.QueueClientAction[d.mbQueue, PrintBusy, d]; RETURN; }; ENDLOOP; larkControl _ List.Remove[ref: d, list: larkControl]; MBQueue.Flush[d.mbQueue]; MBQueue.QueueClientAction[d.mbQueue, DestroyEverything, d]; }; }; PrintBusy: PROC [clientData: REF ANY] = { d: LarkControl.Data = NARROW[clientData]; d.out.PutRope["There are open work area.\n"]; }; <<>> <> StopProc: Buttons.ButtonProc = TRUSTED { d: LarkControl.Data = NARROW[clientData]; d.pleaseStop _ TRUE; }; PrintHelp: Buttons.ButtonProc = TRUSTED { d: LarkControl.Data = NARROW[clientData]; d.out.PutRope["See LarkControlDocumentation.tioga in Teleload.df\n"]; }; StatusAll: Buttons.ButtonProc = TRUSTED { d: LarkControl.Data = NARROW[clientData]; lark: LarkControl.LarkData; FOR b: LarkControl.LarkIndex IN LarkControl.LarkIndex DO IF d.pleaseStop THEN { d.pleaseStop _ FALSE; EXIT; }; lark _ d.larks[b]; Labels.Set[lark.status, LarkControl.PollLark[lark: lark, print: shift, setPointers: mouseButton = blue]]; IF lark.event.reason # LarkControl.cDown AND lark.larkMode # 'dTHEN { LarkControl.LarkDBSet[lark: lark, setMode: TRUE, setProgram: TRUE]; LarkControl.PaintMode[lark]; }; ENDLOOP; }; ResetAll: Buttons.ButtonProc = TRUSTED { d: LarkControl.Data = NARROW[clientData]; lark: LarkControl.LarkData; FOR b: LarkControl.LarkIndex IN LarkControl.LarkIndex DO IF d.pleaseStop THEN { d.pleaseStop _ FALSE; EXIT; }; lark _ d.larks[b]; IF lark.larkMode = 'd THEN LOOP; IF mouseButton # yellow THEN [] _ LarkControl.SetState[h: lark.h, state: lark.state, tp: TeleLoad.GoToDebugger, print: FALSE]; IF mouseButton # red THEN LarkControl.BootLark[lark]; ENDLOOP; }; StartAll: Buttons.ButtonProc = TRUSTED { d: LarkControl.Data = NARROW[clientData]; lark: LarkControl.LarkData; FOR b: LarkControl.LarkIndex IN LarkControl.LarkIndex DO IF d.pleaseStop THEN { d.pleaseStop _ FALSE; EXIT; }; lark _ d.larks[b]; IF lark.larkMode = 'd THEN LOOP; Labels.Set[lark.status, LarkControl.PollLark[lark: lark, print: shift, setPointers: TRUE]]; IF lark.event.reason = LarkControl.cRUNNING THEN { LarkControl.LogEntry[lark: lark, rope: "already running\n"]; LOOP; }; IF lark.event.reason = LarkControl.cDown THEN LOOP; -- down LarkControl.ConsiderActionFurther[lark: lark, event: lark.event]; LarkControl.PaintMode[lark]; ENDLOOP; }; NewSoftware: Buttons.ButtonProc = TRUSTED { d: LarkControl.Data = NARROW[clientData]; newProgramList: LIST OF LarkPrograms.Program _ NIL; ReParse: PROC [program: LarkPrograms.Program] RETURNS [stop: BOOL] = TRUSTED { newProgram: LarkPrograms.Program _ LarkPrograms.ReadProgramFromDisk[objectFileName: program.programName, log: d.out, addressSpace: program.addressSpace, wDir: d.wDir]; IF newProgram # NIL THEN newProgramList _ CONS[newProgram, newProgramList]; RETURN [FALSE]; }; LarkPrograms.EnumeratePrograms[proc: ReParse]; WHILE newProgramList # NIL DO LarkPrograms.AddOrReplaceProgram[newProgramList.first]; newProgramList _ newProgramList.rest; ENDLOOP; }; MainSwitchProc: ChoiceButtons.SelectionNotifierProc = TRUSTED { d: LarkControl.Data = NARROW[clientdata]; FOR i: LarkControl.MainSwitchStates IN LarkControl.MainSwitchStates DO IF Rope.Equal[name, mainSwitchRopes[i]] THEN { d.mainSwitch _ i; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; }; <> <<>> LoadThis: Buttons.ButtonProc = TRUSTED { lark: LarkControl.LarkData = NARROW[clientData]; Labels.Set[lark.status, LarkControl.PollLark[lark: lark, print: FALSE, setPointers: TRUE]]; IF lark.event.reason = LarkControl.cRUNNING THEN { LarkControl.LogEntry[lark: lark, rope: "already running\n"]; RETURN; }; IF lark.program # NIL THEN lark.state _ lark.program.startState ELSE { LarkControl.LogEntry[lark: lark, rope: "No program selected\n"]; RETURN; }; IF mouseButton = blue THEN LarkControl.LocalGo[lark] ELSE { IF lark.slaveProgram # NIL THEN LarkControl.LoadProgram[lark: lark, go: FALSE, main: FALSE]; IF lark.program # NIL THEN LarkControl.LoadProgram[lark: lark, go: shift, main: TRUE]; }; }; ResetThis: Buttons.ButtonProc = TRUSTED { lark: LarkControl.LarkData = NARROW[clientData]; IF mouseButton # yellow THEN [] _ LarkControl.SetState[h: lark.h, state: lark.state, tp: TeleLoad.GoToDebugger, print: FALSE]; IF mouseButton # red THEN LarkControl.BootLark[lark]; }; ModeThis: Buttons.ButtonProc = TRUSTED { lark: LarkControl.LarkData = NARROW[clientData]; IF mouseButton = red OR lark.larkMode = 'dTHEN { lark.larkMode _ 'U; LarkControl.LarkDBSet[lark: lark, setMode: TRUE, setProgram: TRUE]; } ELSE lark.larkMode _ 'd; LarkControl.PaintMode[lark]; }; DebugThis: Buttons.ButtonProc = TRUSTED { lark: LarkControl.LarkData = NARROW[clientData]; result: Rope.ROPE; SELECT mouseButton FROM red => { IF lark.eval = NIL THEN result _ LarkWork.MaybeCreateWorkArea[lark] ELSE result _ LarkWork.MaybeShutDownWorkArea[lark]; lark.larkMode _ IF lark.eval = NIL THEN 'U ELSE 'd; LarkControl.PaintMode[lark]; lark.world.out.PutRope[result]; }; yellow => { LarkControl.LogEntry[lark: lark, rope: "Verify monitor", endWithCR: TRUE]; LarkControl.VerifyInternal[lark: lark, program: LarkPrograms.Monitor[log: lark.h.log, addressSpace: main, wDir: lark.world.wDir], startAddress: 0E000H, stopAddress: 0]; }; blue => { LarkControl.LogEntry[lark: lark, rope: "Verify slave EPROM", endWithCR: TRUE]; LarkControl.VerifyInternal[lark: lark, program: LarkPrograms.Monitor[log: lark.h.log, addressSpace: slave, wDir: lark.world.wDir], startAddress: 0E000H, stopAddress: 0]; }; ENDCASE; }; StatusThis: Buttons.ButtonProc = TRUSTED { lark: LarkControl.LarkData = NARROW[clientData]; Labels.Set[lark.status, LarkControl.PollLark[lark, TRUE, mouseButton = blue]]; }; <<******** Viewer management ******** -->> Create: Commander.CommandProc = { arg: Rope.ROPE; d: LarkControl.Data; address: Pup.Address; workingDirectory: Rope.ROPE; found: BOOL; arg _ CommandTool.NextArgument[ cmd: cmd ! CommandTool.Failed => { msg _ errorMsg; CONTINUE; }]; IF msg # NIL THEN RETURN[$Failure, msg]; IF arg = NIL THEN { cmd.out.PutRope["Usage: LarkControl []\n"]; RETURN; }; workingDirectory _CommandTool.NextArgument[ cmd: cmd ! CommandTool.Failed => { msg _ errorMsg; CONTINUE; }]; IF msg # NIL THEN RETURN[$Failure, msg]; IF workingDirectory=NIL THEN workingDirectory _ NARROW[ProcessProps.GetProp[$WorkingDirectory]]; [address: address, ok: found] _ TeleLoad.NameToAddress[arg.Concat["##"]]; IF NOT found THEN { cmd.out.PutF["Net %g not found\n", IO.rope[arg]]; RETURN; }; FOR ll: LIST OF REF ANY _ larkControl, ll.rest WHILE ll # NIL DO d _ NARROW[ll.first]; IF d.net = address.net THEN { cmd.out.PutF["Lark controller for net %g already exists\n", IO.rope[arg]]; RETURN; }; ENDLOOP; d _ NEW[LarkControl.LarkControlDataObject]; d.net _ address.net; d.wDir _ workingDirectory; d.mbQueue _ MBQueue.Create[]; MBQueue.QueueClientAction[d.mbQueue, ReallyCreate, d]; }; DestroyEverything: PROC [clientData: REF ANY] = { d: LarkControl.Data = NARROW[clientData]; lark: LarkControl.LarkData; <> <> <> FOR i: LarkControl.LarkIndex IN LarkControl.LarkIndex DO lark _ d.larks[i]; d.larks[i] _ NIL; lark.world _ NIL; TeleLoad.Stop[lark.h]; lark.h _ NIL; lark.program _ NIL; lark.breakList _ NIL; lark.mode _ NIL; lark.status _ NIL; ENDLOOP; TeleLoad.StopKing[]; TeleLoad.StopEventServer[]; LarkControl.StopWatcher[]; }; ReallyCreate: PROC[clientData: REF ANY] = <> <> { d: LarkControl.Data = NARROW[clientData]; v: ViewerClasses.Viewer = Containers.Create[ info: [name: IO.PutFR["Lark Control, Net %3b", IO.card[d.net]], column: left, scrollable: FALSE, iconic: TRUE]]; child: ViewerClasses.Viewer _ NIL; x: INTEGER _ 1; y: INTEGER _ 0; bn: ChoiceButtons.ButtonList; CommandButton: PROC[name: Rope.ROPE, proc: Buttons.ButtonProc, data: REF ANY, newline: BOOL, guarded: BOOL _ FALSE] = { child _ MBQueue.CreateButton[ q: d.mbQueue, info: [name: name, parent: v, border: TRUE, wy: y, wx: x ], proc: proc, clientData: data, paint: TRUE, guarded: guarded]; x _ IF newline THEN 1 ELSE child.wx + child.ww - 1; y _ IF newline THEN child.wy + child.wh - 1 ELSE child.wy; }; LabelText: PROC[name, data: Rope.ROPE] RETURNS[p: ChoiceButtons.PromptDataRef] = { p _ ChoiceButtons.BuildTextPrompt[viewer: v, x: x+1, y: y, title: name, default: data]; child _ p.promptButton; x _ 1; y _ child.wy + child.wh + 1; RETURN[p] }; <> <<{>> <> <> <> <> <> <> <<};>> Rule: PROC = { child _ Rules.Create[ info: [parent: v, border: FALSE, wy: y, wx: 0, ww: v.ww, wh: 1], paint: TRUE ]; Containers.ChildXBound[v, child]; x _ 1; y _ child.wy + child.wh + 1; }; d.viewer _ v; { <> temp: Buttons.Button = Buttons.Create[ info: [name: "ScanUniverse", parent: v, border: FALSE, wx: 0, wy: 0], proc: NIL, clientData: d, fork: FALSE, paint: FALSE]; d.maxW _ temp.ww; d.buttH _ temp.wh; Buttons.Destroy[temp]; }; bn _ LIST[mainSwitchRopes[off], mainSwitchRopes[manual], mainSwitchRopes[auto]]; d.mainSwitchController _ ChoiceButtons.BuildEnumTypeSelection[viewer: v, x: x, y: y, buttonNames: LIST[mainSwitchRopes[off], mainSwitchRopes[manual], mainSwitchRopes[auto]], default: mainSwitchRopes[off], notifyClientProc: MainSwitchProc, clientdata: d, style: menuSelection]; x _ d.mainSwitchController.nextx; child _ Buttons.Create[info: [name: "STOP!", parent: v, border: TRUE, wy: y, wx: x, ww: d.maxW], proc: StopProc, clientData: d]; x _ child.wx + d.maxW - 1; <> y _ d.mainSwitchController.nexty + 1; x _ 1; CommandButton[name: "Help", proc: PrintHelp, data: d, newline: FALSE]; CommandButton[name: "StatusAll", proc: StatusAll, data: d, newline: FALSE]; CommandButton[name: "ResetAll", proc: ResetAll, data: d, newline: FALSE]; CommandButton[name: "StartAll", proc: StartAll, data: d, newline: FALSE]; CommandButton[name: "NewSoftware", proc: NewSoftware, data: d, newline: TRUE]; y _ y + 3; Rule[]; d.larksY _ y; y _ y + (d.larksH _ 10*(d.buttH-1) + d.buttH/2); Rule[]; d.script _ TypeScript.Create[ info: [parent: v, wh: v.ch-y, ww: v.cw, border: FALSE, wy: y, wx: 0] ]; Containers.ChildXBound[v, d.script]; Containers.ChildYBound[v, d.script]; d.out _ ViewerIO.CreateViewerStreams[name: NIL, viewer: d.script, editedStream: FALSE].out; ViewerOps.SetOpenHeight[v, y + 10 * d.buttH]; CreateLarkButtons[d]; ViewerOps.OpenIcon[v]; TeleLoad.StartKing[]; TeleLoad.StartEventServer[LarkControl.NoteEvents, d]; LarkControl.StartWatcher[]; larkControl _ CONS[d, larkControl]; }; CreateLarkButtons: PROC[d: LarkControl.Data] = TRUSTED { parent: ViewerClasses.Viewer = d.viewer; child: ViewerClasses.Viewer _ NIL; x: INTEGER _ 1; y: INTEGER _ 1; CommandButton: PROC[name: Rope.ROPE, proc: Buttons.ButtonProc, data: REF ANY, newline: BOOL] RETURNS [ViewerClasses.Viewer] = TRUSTED { child _ MBQueue.CreateButton[ q: d.mbQueue, info: [name: name, parent: larkViewer, border: TRUE, wy: y, wx: x, ww: IF newline THEN larkViewer.cw - x - 2 ELSE 0 -- d.maxW --], proc: proc, clientData: data]; x _ IF newline THEN 1 ELSE child.wx + child.ww - 1; y _ IF newline THEN child.wy + child.wh - 1 ELSE child.wy; RETURN[child]; }; Label: PROC[name: Rope.ROPE, newline: BOOL] RETURNS [Labels.Label] = TRUSTED { child _ Labels.Create[ info: [name: name, parent: larkViewer, border: FALSE, wy: y, wx: x+1, ww: IF newline THEN larkViewer.cw - x - 2 ELSE 0] ]; x _ IF newline THEN 1 ELSE child.wx + child.ww - 1; y _ IF newline THEN child.wy + child.wh - 1 ELSE child.wy; RETURN[child]; }; larkViewer: ViewerClasses.Viewer = Containers.Create[ info: [parent: parent, border: FALSE, scrollable: TRUE, wx: 0, wy: d.larksY, ww: parent.cw, wh: d.larksH] ]; Containers.ChildXBound[parent, larkViewer]; FOR i: LarkControl.LarkIndex IN LarkControl.LarkIndex DO lData: LarkControl.LarkData _ NEW[LarkControl.LarkDataObject]; lData.world _ d; lData.address.net _ d.net; lData.address.host _ [i]; lData.address.socket _ TeleLoad.teleSwatSocket; lData.nameRope _ lData.addressRope _ IO.PutFR["%03b#%03b#", IO.card[lData.address.net], IO.card[lData.address.host]]; [] _ Label[IO.PutFR["%03b", IO.card[lData.address.host]], FALSE]; lData.userRNameViewer _ Label[" ", FALSE]; [] _ CommandButton["Load", LoadThis, lData, FALSE]; [] _ CommandButton["Reset", ResetThis, lData, FALSE]; lData.debug _ CommandButton["Debug", DebugThis, lData, FALSE]; lData.mode _ CommandButton["Mode W", ModeThis, lData, FALSE]; LarkControl.PaintMode[lData]; [] _ CommandButton["Status", StatusThis, lData, FALSE]; lData.status _ Label[NIL, TRUE]; Containers.ChildXBound[larkViewer, child]; lData.eval _ NIL; lData.h _ TeleLoad.Start[host: lData.addressRope, log: lData.world.out]; IF lData.h = NIL THEN ERROR; d.larks[i] _ lData; ENDLOOP; }; <> [] _ ViewerEvents.RegisterEventProc[DestroyProc, destroy]; Commander.Register[key: "LarkControl", proc: Create, doc: "LarkControl net-name, Create a lark control viewer for the given network"]; Atom.PutProp[$Interfaces, $GetLogStreamProc, NEW[LarkControl.GetLogStreamProc_GetLogStream]]; END. <> <> <> <<>>