DIRECTORY
Commander USING [CommandProc, Handle, Register],
IO,
Rope,
Buttons USING [Button, ButtonProc, Create, ReLabel],
Containers USING [ChildXBound],
Labels USING [Create, Set],
PopUpSelection USING [Request],
RuntimeError USING [BoundsFault],
ViewerClasses USING [Viewer, ViewerRec],
ViewerOps USING [CreateViewer],
ViewerTools USING [GetContents, MakeNewTextViewer, SetContents, SetSelection],
SoftcardOps,
SoftcardToolPrivate;
SoftcardToolImpl:
CEDAR
MONITOR
IMPORTS
Commander, IO, PopUpSelection, RuntimeError,
Buttons, Containers, Labels, ViewerOps, ViewerTools,
SoftcardOps, SoftcardToolPrivate
EXPORTS SoftcardToolPrivate
= BEGIN OPEN IO, SoftcardToolPrivate;
STREAM: TYPE = IO.STREAM;
variables
tsViewer, topViewer: PUBLIC Viewer;
tsOut: PUBLIC STREAM;
runOrStopButton: Viewer;
runChoice: ROPE = " Is running ";
stopChoice: ROPE = " Is stopped ";
unknownChoice: ROPE = " Is unknown ";
dragonState: DragonState ← unknown;
connectionText: Viewer;
phaseAdjustText: Viewer;
delayText: Viewer;
freqSelectLabel: Viewer;
freqSelectChoice: INT ← -1;
freqSelectArray:
PUBLIC
ARRAY [0..3]
OF SelectRecord;
euRegValText: Viewer;
euSelectChoice: INT ← -1;
euSelectArray: PUBLIC ARRAY [0..8] OF SelectRecord;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
MakeControlWindow:
PROC[name, tsLogFile:
ROPE]
RETURNS [
STREAM] = {
IF topViewer =
NIL
OR topViewer.destroyed
THEN {
sib: Viewer;
topViewer ← ViewerOps.CreateViewer[
flavor: $Container,
info: [name: name, iconic: FALSE, scrollable: FALSE] ];
line 1 of Buttons
sib ← Buttons.Create[
info: [ name: " EstablishConnection ", parent: topViewer,
wx: 3, wy: 4, wh: entryHeight, border: TRUE, scrollable: FALSE],
proc: OpenConnectionProc ];
sib ← Buttons.Create[
info: [ name: " CloseConnection ", parent: topViewer,
wx: sib.wx+sib.ww+1, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE],
proc: CloseConnectionProc ];
sib ← Buttons.Create[
info: [ name: "Host:", parent: topViewer,
wx: sib.wx+sib.ww+10, wy: sib.wy, wh: entryHeight,
border: FALSE, scrollable: FALSE],
proc: ConnectionTextProc ];
sib ← connectionText ← ViewerTools.MakeNewTextViewer[
info: [parent: topViewer, wx: sib.wx+sib.ww+xFudge, wy: sib.wy,
ww: 1000, wh: entryHeight, border: FALSE, scrollable: TRUE]];
Containers.ChildXBound[topViewer, sib];
line 2 of Buttons - ControlBits
sib ← Labels.Create[
info: [ name: " ControlBits ", parent: topViewer,
wx: 3, wy: sib.wy + sib.wh + 2, wh: entryHeight,
border: FALSE, scrollable: FALSE]
];
sib ← Buttons.Create[
info: [ name: " Read ", parent: topViewer,
wx: sib.wx+sib.ww+5, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE],
proc: ReadControlBits ];
sib ← Buttons.Create[
info: [name: " Set ", parent: topViewer,
wx: sib.wx+sib.ww+1, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE ],
proc: SetControlBits ];
sib ← Buttons.Create[
info: [name: " Reset ", parent: topViewer,
wx: sib.wx+sib.ww+1, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE ],
proc: ResetControlBits ];
line 3 of Buttons - StatusBits
sib ← Labels.Create[
info: [ name: " StatusBits ", parent: topViewer,
wx: 3, wy: sib.wy + sib.wh + 2, wh: entryHeight,
border: FALSE, scrollable: FALSE]
];
sib ← Buttons.Create[
info: [ name: " Read ", parent: topViewer,
wx: sib.wx+sib.ww+5, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE],
proc: ReadStatusBits ];
sib ← Buttons.Create[
info: [name: " Reset ", parent: topViewer,
wx: sib.wx+sib.ww+1, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE ],
proc: ResetStatusBits ];
line 4 of Buttons
sib ← Labels.Create[
info: [ name: " ClockControl ", parent: topViewer,
wx: 3, wy: sib.wy+sib.wh+2, wh: entryHeight, border: FALSE, scrollable: FALSE]
];
sib ← Buttons.Create[
info: [name: "Read", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: ReadClockControl ];
sib ← Buttons.Create[
info: [name: "Write", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: WriteClockControl ];
sib ← Buttons.Create[
info: [name: "FreqSelect", parent: topViewer,
wx: sib.wx+sib.ww+xFudge+5, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: FreqSelectProc ];
sib ← freqSelectLabel ← Labels.Create[
info: [name: " ", parent: topViewer, wx: sib.wx+sib.ww+xFudge+2, wy: sib.wy,
wh: entryHeight, border: FALSE, scrollable: FALSE]];
sib ← Buttons.Create[
info: [name: "PhaseAdjust [0..7]", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: PhaseAdjustProc ];
sib ← phaseAdjustText ← ViewerTools.MakeNewTextViewer[
info: [parent: topViewer, wx: sib.wx+sib.ww+xFudge+2, wy: sib.wy,
ww: 20, wh: entryHeight, border: FALSE, scrollable: FALSE]];
sib ← Buttons.Create[
info: [name: "Delay [0..7]", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: DelayProc ];
sib ← delayText ← ViewerTools.MakeNewTextViewer[
info: [parent: topViewer, wx: sib.wx+sib.ww+xFudge+2, wy: sib.wy,
ww: 20, wh: entryHeight, border: FALSE, scrollable: FALSE]];
line 5 of Buttons
sib ← Labels.Create[
info: [ name: " Regular EU Registers ", parent: topViewer,
wx: 3, wy: sib.wy+sib.wh+2, wh: entryHeight, border: FALSE, scrollable: FALSE]
];
sib ← Buttons.Create[
info: [name: "Read", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: ReadEUReg ];
sib ← Buttons.Create[
info: [name: "Write", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: WriteEUReg ];
sib ← Buttons.Create[
info: [name: "Val: ", parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight, scrollable: FALSE ],
proc: EUValProc ];
sib ← euRegValText ← ViewerTools.MakeNewTextViewer[
info: [parent: topViewer, wx: sib.wx+sib.ww+xFudge+2, wy: sib.wy,
ww: 600, wh: entryHeight, border: FALSE, scrollable: FALSE]];
Containers.ChildXBound[topViewer, sib];
line 6 of Buttons
sib ← Labels.Create[
info: [ name: " DragonRunControl ", parent: topViewer,
wx: 3, wy: sib.wy+sib.wh+2, wh: entryHeight, border: FALSE, scrollable: FALSE]
];
sib ← runOrStopButton ← Buttons.Create[
info: [ name: unknownChoice, parent: topViewer,
wx: sib.wx+sib.ww+xFudge, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE],
proc: RunOrStopProc ];
line 7 of Buttons
sib ← Buttons.Create[
info: [ name: " HaltDragonInPhase ", parent: topViewer,
wx: 3, wy: sib.wy+sib.wh+2, wh: entryHeight, border: TRUE, scrollable: FALSE],
proc: HaltDragonProc ];
sib ← Buttons.Create[
info: [ name: " StepDragon ", parent: topViewer,
wx: sib.wx+sib.ww+xFudge+6, wy: sib.wy, wh: entryHeight,
border: TRUE, scrollable: FALSE],
proc: StepDragonProc ];
sib ← BuildPeekPokeButtons[topViewer, sib];
BuildMiscButtons[topViewer, sib, tsLogFile];
};
topViewer.inhibitDestroy ← TRUE;
RETURN[tsOut];
};
OpenConnectionProc: ClickProc = {
name: ROPE = ViewerTools.GetContents[connectionText];
ok: BOOL = SoftcardOps.EstablishConnection[name];
isRunning: BOOL = SoftcardOps.ReadControlBit[dragonRun];
IF ok
THEN {
IF isRunning
THEN SetDragonStateLabelButton[running]
ELSE SetDragonStateLabelButton[stopped];
tsOut.PutF["Connection to %g has been established\n", IO.rope[name]]
}
ELSE
tsOut.PutF["Could not establish connection with %g has \n", IO.rope[name]];
};
CloseConnectionProc: ClickProc = {
SoftcardOps.CloseConnection[];
tsOut.PutRope["Connection has been closed\n\n"];
SetDragonStateLabelButton[unknown];
};
ReadClockControl: ClickProc = {
current: SoftcardOps.ClockControl = SoftcardOps.ReadClockControl[];
tsOut.PutF[
" Current value of clock control is: [freqSelect: %g, phaseAdjust: %g, delay: %g]\n",
IO.rope[freqSelectArray[current.freqSelect].name], IO.int[current.phaseAdjust],
IO.int[current.delay] ];
freqSelectChoice ← current.freqSelect;
Labels.Set[freqSelectLabel, freqSelectArray[freqSelectChoice].name ];
ViewerTools.SetContents[phaseAdjustText, IO.PutFR[NIL, IO.int[current.phaseAdjust]] ];
ViewerTools.SetContents[delayText, IO.PutFR[NIL, IO.int[current.delay]] ];
};
WriteClockControl: ClickProc = {
ENABLE RuntimeError.BoundsFault => GOTO oops;
BEGIN
new: SoftcardOps.ClockControl;
IF freqSelectChoice = -1
THEN {
tsOut.PutRope[" Please select a frequency first - quitting\n"];
RETURN;
};
new.freqSelect ← freqSelectArray[freqSelectChoice].val;
new.phaseAdjust ← GetAsInt[phaseAdjustText];
new.delay ← GetAsInt[delayText];
SoftcardOps.WriteClockControl[new];
tsOut.PutRope[" New value of clockControl has been set\n"];
RETURN;
END;
EXITS
oops => tsOut.PutRope["Boundsfault doing ClockControl - not done\n"];
};
RunOrStopProc: ClickProc = {
IF dragonState = unknown
THEN {
tsOut.PutRope[" Dragon state is unknown - can't change\n"];
RETURN
};
IF dragonState = running
THEN {
SoftcardOps.DragonStop[];
SetDragonStateLabelButton[stopped];
}
ELSE {
SoftcardOps.DragonRun[];
SetDragonStateLabelButton[running];
};
};
SetDragonStateLabelButton:
PUBLIC
PROC[which: DragonState] = {
IF dragonState = which THEN RETURN; -- nothing to do
SELECT which
FROM
running => Buttons.ReLabel[runOrStopButton, runChoice];
stopped => Buttons.ReLabel[runOrStopButton, stopChoice];
unknown => Buttons.ReLabel[runOrStopButton, unknownChoice];
ENDCASE => ERROR;
dragonState ← which;
};
ConnectionTextProc: ClickProc =
{ ViewerTools.SetSelection[connectionText, NIL] };
FreqSelectProc: ClickProc = {
which:
INT = PopUpSelection.Request[
header: "Frequency Select",
choice:
LIST[freqSelectArray[0].name, freqSelectArray[1].name, freqSelectArray[2].name,
freqSelectArray[3].name]
];
IF which = 0 THEN RETURN; -- no selection
Labels.Set[freqSelectLabel, freqSelectArray[which - 1].name];
freqSelectChoice ← which - 1;
};
PhaseAdjustProc: ClickProc =
{ ViewerTools.SetSelection[phaseAdjustText, NIL] };
DelayProc: ClickProc =
{ ViewerTools.SetSelection[delayText, NIL] };
ReadEUReg: ClickProc = {
which: SoftcardOps.EUInternal;
name: ROPE;
val: CARD;
[which, name] ← SelectEURegister[];
IF name = NIL THEN RETURN;
val ← SoftcardOps.ReadEURegister[which];
tsOut.PutF[" The value of EUReg %g is: %xH\n", IO.rope[name], IO.int[val] ];
ViewerTools.SetContents[euRegValText, IO.PutFR["%xH", IO.int[val]] ];
SetDragonStateLabelButton[stopped];
};
WriteEUReg: ClickProc = {
which: SoftcardOps.EUInternal;
name: ROPE;
val: CARD;
[which, name] ← SelectEURegister[];
IF name = NIL THEN RETURN;
val ← GetAsCard[euRegValText];
SoftcardOps.WriteEURegister[which, val];
tsOut.PutF["EUReg %g has been set: %xH\n", IO.rope[name], IO.int[val] ];
SetDragonStateLabelButton[stopped];
};
EUValProc: ClickProc =
{ ViewerTools.SetSelection[euRegValText, NIL] };
SelectEURegister:
PROC
RETURNS[reg: SoftcardOps.EUInternal, name:
ROPE] = {
which:
INT = PopUpSelection.Request[
header: "Regular EU Register",
choice: LIST[euSelectArray[0].name, euSelectArray[1].name, euSelectArray[2].name, euSelectArray[3].name, euSelectArray[4].name, euSelectArray[5].name, euSelectArray[6].name, euSelectArray[7].name, euSelectArray[8].name] ];
SELECT which
FROM
1 => RETURN[left, euSelectArray[0].name];
2 => RETURN[right, euSelectArray[1].name];
3 => RETURN[st2A, euSelectArray[2].name];
4 => RETURN[st2B, euSelectArray[3].name];
5 => RETURN[st3A, euSelectArray[4].name];
6 => RETURN[r2B, euSelectArray[5].name];
7 => RETURN[r3A, euSelectArray[6].name];
8 => RETURN[r3B, euSelectArray[7].name];
9 => RETURN[dataIn, euSelectArray[8].name];
ENDCASE => RETURN[left, NIL];
};
HaltDragonProc: ClickProc = {
which:
INT = PopUpSelection.Request[
header: "DragonPhase",
choice: LIST["phaseA", "betweenAandB", "phaseB", "betweenBandA"] ];
phase: SoftcardOps.DragonPhase;
name: ROPE;
IF which = 0 THEN RETURN;
SELECT which
FROM
1 => { phase ← phaseA; name ← "phaseA" };
2 => { phase ← betweenAandB; name ← "betweenAandB" };
3 => { phase ← phaseB; name ← "phaseA" };
4 => { phase ← betweenBandA; name ← "betweenBandA" };
ENDCASE => ERROR;
SoftcardOps.DragonHaltInPhase[phase];
tsOut.PutF[" Dragon has been halted in %g\n", IO.rope[name] ];
SetDragonStateLabelButton[stopped];
};
StepDragonProc: ClickProc = {
which:
INT = PopUpSelection.Request[
header: "DragonStep",
choice: LIST["quarter", "half", "full"] ];
step: SoftcardOps.DragonStepSize;
name: ROPE;
IF which = 0 THEN RETURN;
IF dragonState # stopped
THEN {
tsOut.PutRope["Dragon can only be stepped when halted\n"];
RETURN
};
SELECT which
FROM
1 => { step ← quarter; name ← "quarter" };
2 => { step ← half; name ← "half" };
3 => { step ← full; name ← "full" };
ENDCASE => ERROR;
[] ← SoftcardOps.DragonStep[step];
tsOut.PutF[" Dragon has been stepped by one %g cycle\n", IO.rope[name] ];
};