DIRECTORY Atom USING [ PutProp ], Buttons USING [Button, ButtonProc, Create, Destroy], ChoiceButtons USING [BuildEnumTypeSelection, BuildTextPrompt, ButtonList, PromptDataRef, SelectionNotifierProc], Commander USING [CommandProc, Register], CommandTool USING [ArgumentVector, Parse, 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], PupTypes USING [allNets, PupAddress], Rope USING [Concat, Equal, ROPE], RPCPkt USING [Machine], 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 [DestroyViewer, OpenIcon, SetOpenHeight]; LarkControlImpl: CEDAR MONITOR IMPORTS Atom, Buttons, ChoiceButtons, Commander, CommandTool, Containers, IO, Labels, LarkControl, LarkPrograms, LarkWork, List, MBQueue, 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 [machine: RPCPkt.Machine] RETURNS [log: IO.STREAM] = { lark: LarkControl.LarkData; IF larkControl = NIL THEN RETURN [NIL]; IF machine.net = PupTypes.allNets THEN RETURN [NARROW[larkControl.first, LarkControl.Data].out]; lark _ GetLark[machine]; IF lark = NIL THEN RETURN [NIL]; log _ lark.h.log; }; GetLark: PUBLIC PROC [machine: RPCPkt.Machine] RETURNS [lark: LarkControl.LarkData] = { d: LarkControl.Data; IF larkControl = NIL THEN RETURN [NIL]; IF machine.net = PupTypes.allNets OR machine.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 = machine.net THEN RETURN[d.larks[machine.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.LarkGVSet[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]; 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.LarkGVSet[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], 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], startAddress: 0E000H, stopAddress: 0]; }; ENDCASE; }; StatusThis: Buttons.ButtonProc = TRUSTED { lark: LarkControl.LarkData = NARROW[clientData]; Labels.Set[lark.status, LarkControl.PollLark[lark, TRUE, mouseButton = blue]]; }; Create: Commander.CommandProc = { argv: CommandTool.ArgumentVector; d: LarkControl.Data; address: PupTypes.PupAddress; found: BOOL; argv _ CommandTool.Parse[cmd: cmd ! CommandTool.Failed => { msg _ errorMsg; CONTINUE; }]; IF argv = NIL THEN RETURN[$Failure, msg]; IF argv.argc < 2 THEN { cmd.out.PutRope["Usage: LarkControl netaddress\n"]; RETURN; }; [address: address, ok: found] _ TeleLoad.NameToAddress[argv[1]]; IF NOT found THEN { cmd.out.PutF["Net %g not found\n", IO.rope[argv[1]]]; 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[argv[1]]]; RETURN; }; ENDLOOP; d _ NEW[LarkControl.LarkControlDataObject]; d.net _ address.net; 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, fork: TRUE, 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, fork: TRUE]; 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]]; lData.rName _ Rope.Concat[lData.addressRope, ".lark"]; [] _ 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, $GetLogStream, NEW[LarkControl.GetLogStreamProc_GetLogStream]]; END. ¦LarkControlImpl.mesa L. Stewart, December 26, 1983 4:12 pm Last Edited by: Swinehart, June 15, 1984 1:46:11 am PDT The master data structure PROC [viewer: ViewerClasses.Viewer, event: ViewerEvents.ViewerEvent] Global control buttons Per-Lark control buttons ******** Viewer management ******** -- Turn off event server Stop watfcher process Stop all debug processes (or just print if there are any) This is a separate procedure so that it is synchronized with d.mbQueue -- Thus, the buttons can't be invoked until we've finished creating them, and called SetWorld. Label: PROC[name: Rope.ROPE, newline: BOOL] = { child _ Labels.Create[ info: [name: name, parent: v, border: FALSE, wy: y, wx: x+1], paint: TRUE ]; x _ IF newline THEN 1 ELSE child.wx + d.maxW - 1; y _ IF newline THEN child.wy + child.wh - 1 ELSE child.wy; }; kludge to find max button size! -- new line [nameRope: lData.nameRope, addressRope: lData.addressRope] _ TeleLoad.AddressToName[address: lData.address]; lData.rName _ IO.PutFR["%03b#%03b#.lark", IO.card[lData.address.net], IO.card[lData.address.host]]; Mainline code. Register an event proc to handle the destruction of the viewer, then create the viewer. ʘJšœ™Jšœ%™%J™7J˜šÏk ˜ Jšœœ ˜Jšœœ'˜4Jšœœ]˜pJšœ œ˜(Jšœ œ!˜2Jšœ œ$˜4Jšœ œ˜%Jšœ˜Jšœœ˜"Jšœ ˜ Jšœ œQ˜cJšœ œ.˜Jšœ˜J˜J˜J˜/Jšœ%œœœ˜uJšœl™lJšœœœœ™cJšœ6˜6Jšœ œœœ˜AJšœ1œ˜8Jšœ,œ˜3Jšœ.œ˜5Jšœ7œ˜>Jšœ6œ˜=Jšœ˜Jšœ0œ˜7Jšœœœ˜ Jšœ*˜*Jšœ œ˜JšœH˜HJšœ œœœ˜Jšœ˜—Jšœ˜J˜—J˜J™gJ˜:Jšœ†˜†Jšœ)œ-˜YJ˜Jšœ˜J˜—…—;xQ"