<> <> <> <> <> 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 ]; <> 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: BOOLEAN _ TRUE; --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_bOnly_cOnly_all_FALSE; random_fixed_count_cycle_sweep_FALSE; verbose_terse_none_all_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_check_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: CARDINAL _ MIN[panel.lastAddress, (size_ GetSize[t])-1]; IF fA>=size OR lA 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: CARDINAL _ MIN[panel.lastAddress, (size_ GetSize[t])-1]; IF fA>=size OR lA 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_cpat+1; IF cpat> (IF testingA THEN 1777B ELSE 377B) THEN cpat_0; 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_0; --only blue data for B channel IF t=C THEN nextPat.blue_nextPat.red_0; --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.