CKViewerTestImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by Pier on January 9, 1984 5:41 pm
Doug Wyatt, April 30, 1985 6:54:21 pm PDT
Rick Beach, November 25, 1985 1:54:50 pm PST
DIRECTORY
CKViewerPanel,
CKViewerButtons,
CKViewerTables,
Random, Rope, ChoiceButtons, NumberLabels, MessageWindow,
Basics, IO, ViewerTools;
CKViewerTestImpl: CEDAR PROGRAM
IMPORTS IO, NumberLabels, ViewerTools, Basics, CKViewerPanel, CKViewerTables, Random, Rope, ChoiceButtons, MessageWindow
EXPORTS CKViewerPanel
= BEGIN OPEN IO, CKViewerTables, CKViewerPanel;
CKViewer: TYPE = CKViewerButtons.CKViewer;
CARD: TYPE = LONG CARDINAL;
PanelData: TYPE = RECORD [
firstAddress, lastAddress, addressInc: CARDINAL,
pattern: CARD --24 bits
];
Global Variables
panel: PanelData;
scriptStream: IO.STREAM;
passLabel: NumberLabels.NumberLabel;
check, read, readOnly, show, write, writeOnly: BOOLEAN;
aOnly, bOnly, cOnly, all: BOOLEAN;
random, fixed, cycle, count, sweep: BOOLEAN;
randomStream: Random.RandomStream ← NIL;
verbose, terse, none: BOOLEAN;
gStop: BOOLEANTRUE; --global stop flag
passCount: INT;
savePat, pat, cpat: CARD;
nextPat: TableData;
ReadPanel: PROC [ckv: CKViewer]= {
--fill in global variables
OPEN Rope, ChoiceButtons;
rope: ROPE;
panel ← [firstAddress: 0, lastAddress: 377B, addressInc: 1, pattern: 0];
check←read←write←readOnly←writeOnly←show←FALSE;
aOnly𡤋Only𡤌Only𡤊ll←FALSE;
random𡤏ixed𡤌ount𡤌ycle←sweep←FALSE;
verbose←terse←none𡤊ll←FALSE;
rope ← GetSelectedButton[ckv.panel.tableOp];
rope ← GetSelectedButton[ckv.panel.tableOp];
SELECT TRUE FROM
Equal[rope,"WriteReadCheck"] => check←read←write←TRUE;
Equal[rope,"WriteRead"]=> read←write←TRUE;
Equal[rope,"ReadOnly"]=> read←readOnly←TRUE;
Equal[rope,"ReadAndCheck"]=> check←read←write←readOnly←TRUE; --only one write, then read
Equal[rope,"ReadAndShow"]=> show𡤌heck←read←write←readOnly←TRUE;
Equal[rope,"WriteOnly"]=> write←writeOnly←TRUE;
Equal[rope,"Sweep"] => write←sweep←TRUE;
ENDCASE => ERROR;
rope ← GetSelectedButton[ckv.panel.table];
rope ← GetSelectedButton[ckv.panel.table];
SELECT TRUE FROM
Equal[rope,"ALL"] => all←TRUE;
Equal[rope,"A"] => aOnly←TRUE;
Equal[rope,"B"] => bOnly←TRUE;
Equal[rope,"C"] => cOnly←TRUE;
ENDCASE => ERROR;
rope ← GetSelectedButton[ckv.panel.action];
rope ← GetSelectedButton[ckv.panel.action];
SELECT TRUE FROM
Equal[rope,"Fixed"] => fixed←TRUE;
Equal[rope,"Random"] => random←TRUE;
Equal[rope,"Cycle"] => cycle←TRUE;
Equal[rope,"Count"] => count←TRUE;
ENDCASE => ERROR;
rope ← GetSelectedButton[ckv.panel.report];
rope ← GetSelectedButton[ckv.panel.report];
SELECT TRUE FROM
Equal[rope,"Long"] => verbose←TRUE;
Equal[rope,"Short"]=> terse←TRUE;
Equal[rope,"None"] => none←TRUE;
ENDCASE => ERROR;
panel.pattern ← IO.GetCard[IO.RIS[ViewerTools.GetContents[ckv.panel.pattern.textViewer]] ! IO.Error, IO.EndOfStream => {MessageWindow.Append[message: "Input Syntax Error in Pattern", clearFirst: TRUE]; StopTest[]; CONTINUE;};];
panel.firstAddress ← Basics.LowHalf[IO.GetCard[IO.RIS[ViewerTools.GetContents[ckv.panel.firstAddr.textViewer]] ! IO.Error, IO.EndOfStream => {MessageWindow.Append[message: "Input Syntax Error in First Address", clearFirst: TRUE]; StopTest[]; CONTINUE;};]];
panel.lastAddress ← Basics.LowHalf[IO.GetCard[IO.RIS[ViewerTools.GetContents[ckv.panel.lastAddr.textViewer]] ! IO.Error, IO.EndOfStream => {MessageWindow.Append[message: "Input Syntax Error in Last Address", clearFirst: TRUE]; StopTest[]; CONTINUE;};]];
panel.addressInc ← Basics.LowHalf[IO.GetCard[IO.RIS[ViewerTools.GetContents[ckv.panel.incAddr.textViewer]] ! IO.Error, IO.EndOfStream => {MessageWindow.Append[message: "Input Syntax Error in Address Increment", clearFirst: TRUE]; StopTest[]; CONTINUE;};]];
passLabel ← ckv.panel.passCount;
};
StopTest: PUBLIC PROC [] = {gStop←TRUE; writeOnly←readOnly←FALSE};
StartTest: PUBLIC PROC [ckViewer: CKViewer] = {
gStop ← FALSE;
scriptStream ← ckViewer.panel.stream;
CKViewerPanel.SetUpPanelTest[ckViewer]; --set testingPanel and clear screen,
ReadPanel[ckViewer]; --ReadPanel does reasonableness checks and sets gStop if needed
InitializeTest[];
IF NOT show THEN ClearAllTables[]
ELSE SELECT TRUE FROM
aOnly => {ClearTable[B]; ClearTable[C]};
bOnly => {ClearTable[A]; ClearTable[C]};
cOnly => {ClearTable[A]; ClearTable[B]};
ENDCASE => NULL;
passCount ← 0; ShowPassCount[];
UNTIL gStop DO
SELECT TRUE FROM
aOnly => TestTable[A];
bOnly => TestTable[B];
cOnly => TestTable[C];
all => {
TestTable[A]; ClearTable[A];
TestTable[B]; ClearTable[B];
TestTable[C]; ClearTable[C];
};
ENDCASE => ERROR;
IncPassCount[];
ENDLOOP;
Script[format: "\nPanelTest Complete at %t\n", v1: time[]];
FinalizeTest[];
ckViewer.state.testingPanel ← FALSE;
};
IncPassCount: PROC = {
passCount ← passCount+1;
ShowPassCount[];
};
ShowPassCount: PROC = {
NumberLabels.NumberLabelUpdate[nl: passLabel, new: passCount];
};
TestTable: PROC [t: Table] RETURNS [] = {
ok: BOOLEAN; badIndex: Address; badData: TableData;
ReleaseAllTables[]; --release any previous tables
IF NOT show THEN { --going to write first
ClearTable[t]; --preliminary tests which must work
[ok: ok, index: badIndex, d: badData] ← VerifyClearedTable[t];
IF NOT ok THEN Script[format: "\nClear Table %g failed: address %b, data r: %b, g: %b, b: %b", v1: char[TableToChar[t]], v2: card[badIndex], v3: card[badData.red], v4: card[badData.green], v5: card[badData.blue]];
};
IF write THEN {TakeTable[t]; WriteTest[t];}; --don't want TakeTable inside WriteTest
WHILE writeOnly DO WriteTest[t]; IncPassCount[]; ENDLOOP; --Stop resets writeOnly;
IF gStop THEN RETURN; --writes may have been interrupted in midpass
IF read THEN {TakeTable[t]; ReadTest[t];}; --don't want TakeTable inside ReadTest
WHILE readOnly DO ReadTest[t]; IncPassCount[]; ENDLOOP; --Stop resets readOnly;
};
WriteTest: PROC [t: Table] RETURNS [] = {
size: CARDINAL;
testingA: BOOL ← t=A;
fA: CARDINAL ← panel.firstAddress;
inc: CARDINAL ← panel.addressInc;
lA: CARDINALMIN[panel.lastAddress, (size← GetSize[t])-1];
IF fA>=size OR lA<fA THEN {Script["\n%g Write Address Range ERROR", char[TableToChar[t]]]; StopTest[]; RETURN};
IF sweep THEN SweepTest[t,size] ELSE {
InitPat[];
LoadTableAddress[t, fA];
FOR curA: CARDINAL ← fA, curA+inc UNTIL curA > lA DO
IF inc#1 THEN LoadTableAddress[t, curA];
WriteTableData[t, nextPat]; --increments hardware address
GetNextPat[testingA];
IF gStop THEN EXIT;
ENDLOOP;
};
};
ReadTest: PROC [t: Table] RETURNS [] = {
tD: TableData;
size: CARDINAL;
testingA: BOOL ← t=A;
inc: CARDINAL ← panel.addressInc;
fA: CARDINAL ← panel.firstAddress;
lA: CARDINALMIN[panel.lastAddress, (size← GetSize[t])-1];
IF fA>=size OR lA<fA THEN {Script["\n%g Read Address Range ERROR\n", char[TableToChar[t]]]; StopTest[]; RETURN};
RestorePat[]; --assumes at least one pass of writes done
FOR curA: CARDINAL ← fA, curA+inc UNTIL curA > lA DO
LoadTableAddress[t, curA]; --must always load address for read
tD ← ReadTables[];
IF check THEN {CheckData[t: t, a: curA, d: tD]; GetNextPat[testingA];};
IF show THEN ShowData[t: t, a: curA, d: tD];
IF gStop THEN EXIT;
ENDLOOP;
};
SweepTest: PROCEDURE [t: Table, size: CARDINAL] = {
i,j: CARDINAL;
tD: TableData;
ClearTable[t];
TakeTable[t];
FOR i IN [0..size) DO
LoadTableAddress[t, i];
WriteTableData[t, [red: 377B, green: 377B, blue: 377B]]; --all ones
FOR j IN [i+1..size) DO
LoadTableAddress[t, j];
tD ← ReadTables[];
IF tD#[0,0,0] THEN Script["\n Sweep Up %g fail: addr %b ALIAS to addr %b ", char[TableToChar[t]], card[i], card[j]];
IF gStop THEN RETURN;
ENDLOOP;
ENDLOOP;
ClearTable[t];
TakeTable[t];
FOR i DECREASING IN [0..size) DO
LoadTableAddress[t, i];
WriteTableData[t, [red: 377B, green: 377B, blue: 377B]]; --all ones
FOR j DECREASING IN [0..i) DO
LoadTableAddress[t, j];
tD ← ReadTables[];
IF tD#[0,0,0] THEN Script["\n Sweep Down %g fail: addr %b ALIAS to addr %b ", char[TableToChar[t]], card[i], card[j]];
IF gStop THEN RETURN;
ENDLOOP;
ENDLOOP;
};
InitPat: PROC [] = {
IF passCount=0 THEN cpat←savePat←pat←panel.pattern ELSE cpat←savePat←pat;
IF random THEN randomStream ← Random.Create[range: 100000000B, seed: pat];
nextPat ← [red: Basics.LowByte[Basics.HighHalf[pat]], green: Basics.HighByte[Basics.LowHalf[pat]], blue: Basics.LowByte[Basics.LowHalf[pat]]];
};
RestorePat: PROC [] = {
cpat←pat←savePat;
IF random THEN randomStream ← Random.Create[range: 100000000B, seed: pat]; -- reset
nextPat ← [red: Basics.LowByte[Basics.HighHalf[pat]], green: Basics.HighByte[Basics.LowHalf[pat]], blue: Basics.LowByte[Basics.LowHalf[pat]]];
};
GetNextPat: PROC [testingA: BOOL] = { --updates the globals pat and nextPat
IF fixed THEN RETURN;
IF random THEN pat ← randomStream.NextInt[];
IF cycle THEN { IF (pat MOD 2) = 0 THEN pat ← (pat/2) ELSE pat ← (pat/2) + 40000000B;};
IF count THEN {
cpat𡤌pat+1; IF cpat> (IF testingA THEN 1777B ELSE 377B) THEN cpat𡤀
pat←IF NOT testingA THEN (cpat*200000B+cpat*400B+cpat) --all three bytes identical
ELSE cpat;
};
nextPat ← [red: Basics.LowByte[Basics.HighHalf[pat]], green: Basics.HighByte[Basics.LowHalf[pat]], blue: Basics.LowByte[Basics.LowHalf[pat]]];
};
CheckData: PROC [t: Table, a: CARDINAL, d: TableData] = {
--assumes nextPat has the pattern to check in RGB
IF t=B THEN nextPat.green←nextPat.red𡤀 --only blue data for B channel
IF t=C THEN nextPat.blue←nextPat.red𡤀 --only green data for C channel
IF nextPat#d THEN SELECT TRUE FROM
none => RETURN;
terse => Script[format: "%g", v1: char['!]];
verbose => {
Script["\nCheck %g fail: addr %b, IS [r:%b, g:%b, b:%b] ", char[TableToChar[t]], card[a], card[d.red], card[d.green], card[d.blue]];
Script["Should Be [r:%b, g:%b, b:%b] ", card[nextPat.red], card[nextPat.green], card[nextPat.blue]];
};
ENDCASE => ERROR;
};
ShowData: PROC [t: Table, a: CARDINAL, d: TableData] = {
Script["\nTable %g addr %b IS [r:%b, g:%b, b:%b] ", char[TableToChar[t]], card[a], card[d.red], card[d.green], card[d.blue]];
Script["PATTERN [%b]", card[(d.red*200000B)+(d.green*400B)+d.blue]];
};
TableToChar: PROC [t: Table] RETURNS [c: CHAR] = {
RETURN [ SELECT t FROM
A => 'A,
B => 'B,
C => 'C,
H => ERROR,
ENDCASE => ERROR
]
};
Script: PROC [format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] = {
IF none THEN RETURN;
IO.PutF[stream: scriptStream, format: format, v1: v1, v2: v2, v3: v3, v4: v4, v5: v5];
};
END.